Skip to content

Commit

Permalink
Merge pull request #660 from Ikaros-521/owner
Browse files Browse the repository at this point in the history
对接koboldcpp
  • Loading branch information
Ikaros-521 authored Feb 26, 2024
2 parents e10bf4a + 89aed3c commit f2be24a
Show file tree
Hide file tree
Showing 11 changed files with 409 additions and 116 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<a href="//github.com/Ikaros-521/AI-Vtuber/network"><img alt="GitHub forks" src="https://img.shields.io/github/forks/Ikaros-521/AI-Vtuber?color=%2300BFFF&style=flat-square"></a>
<a href="//www.python.org"><img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="python"></a>

`Luna AI` 是一款结合了最先进技术的虚拟AI主播。它的核心是一系列高效的人工智能模型,包括 `ChatterBot、GPT、Claude、langchain、chatglm、text-generation-webui、讯飞星火、智谱AI、谷歌Bard、文心一言、通义星尘、千帆大模型、Gemini、Kimi ChatQAnything`。这些模型既可以在本地运行,也可以通过云端服务提供支持。
`Luna AI` 是一款结合了最先进技术的虚拟AI主播。它的核心是一系列高效的人工智能模型,包括 `ChatterBot、GPT、Claude、langchain、chatglm、text-generation-webui、讯飞星火、智谱AI、谷歌Bard、文心一言、通义星尘、千帆大模型、Gemini、Kimi ChatQAnything、koboldcpp`。这些模型既可以在本地运行,也可以通过云端服务提供支持。

`Luna AI` 的外观由 `Live2D、Vtube Studio、xuniren 和 UE5 结合 Audio2Face` 技术打造,为用户提供了一个生动、互动的虚拟形象。这使得 `Luna AI` 能够在各大直播平台,如 `Bilibili、抖音、快手、微信视频号、斗鱼、YouTube、Twitch 和 TikTok`,进行实时互动直播。当然,它也可以在本地环境中与您进行个性化对话。

Expand Down
20 changes: 19 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,23 @@
"history_enable": true,
"history_max_len": 300
},
"koboldcpp": {
"api_ip_port": "http://127.0.0.1:5001",
"max_context_length": 2048,
"max_length": 100,
"quiet": false,
"rep_pen": 1.1,
"rep_pen_range": 256,
"rep_pen_slope": 1,
"temperature": 0.5,
"tfs": 1,
"top_a": 0,
"top_k": 3,
"top_p": 0.9,
"typical": 1,
"history_enable": true,
"history_max_len": 600
},
"local_qa": {
"text": {
"enable": true,
Expand Down Expand Up @@ -1272,7 +1289,8 @@
"tongyixingchen": true,
"my_wenxinworkshop": true,
"gemini": true,
"qanything": true
"qanything": true,
"koboldcpp": true
},
"tts": {
"edge-tts": true,
Expand Down
20 changes: 19 additions & 1 deletion config.json.bak
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,23 @@
"history_enable": true,
"history_max_len": 300
},
"koboldcpp": {
"api_ip_port": "http://127.0.0.1:5001",
"max_context_length": 2048,
"max_length": 100,
"quiet": false,
"rep_pen": 1.1,
"rep_pen_range": 256,
"rep_pen_slope": 1,
"temperature": 0.5,
"tfs": 1,
"top_a": 0,
"top_k": 3,
"top_p": 0.9,
"typical": 1,
"history_enable": true,
"history_max_len": 600
},
"local_qa": {
"text": {
"enable": true,
Expand Down Expand Up @@ -1272,7 +1289,8 @@
"tongyixingchen": true,
"my_wenxinworkshop": true,
"gemini": true,
"qanything": true
"qanything": true,
"koboldcpp": true
},
"tts": {
"edge-tts": true,
Expand Down
Binary file modified docs/AI Vtuber.xmind
Binary file not shown.
Binary file modified docs/xmind.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
209 changes: 109 additions & 100 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1789,134 +1789,143 @@ def run_live(self):
# 代理软件开启TUN模式进行代理,由于库的ws不走传入的代理参数,只能靠代理软件全代理了
client: TikTokLiveClient = TikTokLiveClient(unique_id=f"@{room_id}", proxies=None)

# Define how you want to handle specific events via decorator
@client.on("connect")
async def on_connect(_: ConnectEvent):
logging.info(f"连接到 房间ID:{client.room_id}")
def start_client():
# Define how you want to handle specific events via decorator
@client.on("connect")
async def on_connect(_: ConnectEvent):
logging.info(f"连接到 房间ID:{client.room_id}")

@client.on("disconnect")
async def on_disconnect(event: DisconnectEvent):
logging.info("断开连接")
@client.on("disconnect")
async def on_disconnect(event: DisconnectEvent):
logging.info("断开连接,10秒后重连")
await asyncio.sleep(10) # 等待一段时间后尝试重连,这里等待10秒
start_client() # 尝试重新连接

@client.on("join")
async def on_join(event: JoinEvent):
user_name = event.user.nickname
unique_id = event.user.unique_id
@client.on("join")
async def on_join(event: JoinEvent):
user_name = event.user.nickname
unique_id = event.user.unique_id

logging.info(f'[🚹🚺直播间成员加入消息] 欢迎 {user_name} 进入直播间')
logging.info(f'[🚹🚺直播间成员加入消息] 欢迎 {user_name} 进入直播间')

data = {
"platform": platform,
"username": user_name,
"content": "进入直播间"
}
data = {
"platform": platform,
"username": user_name,
"content": "进入直播间"
}

# 添加用户名到最新的用户名列表
add_username_to_last_username_list(user_name)
# 添加用户名到最新的用户名列表
add_username_to_last_username_list(user_name)

my_handle.process_data(data, "entrance")
my_handle.process_data(data, "entrance")

# Notice no decorator?
@client.on("comment")
async def on_comment(event: CommentEvent):
# 闲时计数清零
global_idle_time = 0
# Notice no decorator?
@client.on("comment")
async def on_comment(event: CommentEvent):
# 闲时计数清零
global_idle_time = 0

user_name = event.user.nickname
content = event.comment

logging.info(f'[📧直播间弹幕消息] [{user_name}]:{content}')
user_name = event.user.nickname
content = event.comment
logging.info(f'[📧直播间弹幕消息] [{user_name}]:{content}')

data = {
"platform": platform,
"username": user_name,
"content": content
}

my_handle.process_data(data, "comment")
data = {
"platform": platform,
"username": user_name,
"content": content
}
my_handle.process_data(data, "comment")

@client.on("gift")
async def on_gift(event: GiftEvent):
"""
This is an example for the "gift" event to show you how to read gift data properly.
@client.on("gift")
async def on_gift(event: GiftEvent):
"""
This is an example for the "gift" event to show you how to read gift data properly.
Important Note:
Important Note:
Gifts of type 1 can have streaks, so we need to check that the streak has ended
If the gift type isn't 1, it can't repeat. Therefore, we can go straight to logging.infoing
Gifts of type 1 can have streaks, so we need to check that the streak has ended
If the gift type isn't 1, it can't repeat. Therefore, we can go straight to logging.infoing
"""
"""

# Streakable gift & streak is over
if event.gift.streakable and not event.gift.streaking:
# 礼物重复数量
repeat_count = event.gift.count
# Streakable gift & streak is over
if event.gift.streakable and not event.gift.streaking:
# 礼物重复数量
repeat_count = event.gift.count

# Non-streakable gift
elif not event.gift.streakable:
# 礼物重复数量
repeat_count = 1
# Non-streakable gift
elif not event.gift.streakable:
# 礼物重复数量
repeat_count = 1

gift_name = event.gift.info.name
user_name = event.user.nickname
# 礼物数量
num = 1

gift_name = event.gift.info.name
user_name = event.user.nickname
# 礼物数量
num = 1

try:
# 暂时是写死的
data_path = "data/tiktok礼物价格表.json"

# 读取JSON文件
with open(data_path, "r", encoding="utf-8") as file:
# 解析JSON数据
data_json = json.load(file)

if gift_name in data_json:
# 单个礼物金额 需要自己维护礼物价值表
discount_price = data_json[gift_name]
else:
logging.warning(f"数据文件:{data_path} 中,没有 {gift_name} 对应的价值,请手动补充数据")
try:
# 暂时是写死的
data_path = "data/tiktok礼物价格表.json"

# 读取JSON文件
with open(data_path, "r", encoding="utf-8") as file:
# 解析JSON数据
data_json = json.load(file)

if gift_name in data_json:
# 单个礼物金额 需要自己维护礼物价值表
discount_price = data_json[gift_name]
else:
logging.warning(f"数据文件:{data_path} 中,没有 {gift_name} 对应的价值,请手动补充数据")
discount_price = 1
except Exception as e:
logging.error(traceback.format_exc())
discount_price = 1
except Exception as e:
logging.error(traceback.format_exc())
discount_price = 1


# 总金额
combo_total_coin = repeat_count * discount_price
# 总金额
combo_total_coin = repeat_count * discount_price

logging.info(f'[🎁直播间礼物消息] 用户:{user_name} 赠送 {num}{gift_name},单价 {discount_price}抖币,总计 {combo_total_coin}抖币')
logging.info(f'[🎁直播间礼物消息] 用户:{user_name} 赠送 {num}{gift_name},单价 {discount_price}抖币,总计 {combo_total_coin}抖币')

data = {
"platform": platform,
"gift_name": gift_name,
"username": user_name,
"num": num,
"unit_price": discount_price / 10,
"total_price": combo_total_coin / 10
}
data = {
"platform": platform,
"gift_name": gift_name,
"username": user_name,
"num": num,
"unit_price": discount_price / 10,
"total_price": combo_total_coin / 10
}

my_handle.process_data(data, "gift")
my_handle.process_data(data, "gift")

@client.on("follow")
async def on_follow(event: FollowEvent):
user_name = event.user.nickname
@client.on("follow")
async def on_follow(event: FollowEvent):
user_name = event.user.nickname

logging.info(f'[➕直播间关注消息] 感谢 {user_name} 的关注')
logging.info(f'[➕直播间关注消息] 感谢 {user_name} 的关注')

data = {
"platform": platform,
"username": user_name
}

my_handle.process_data(data, "follow")
data = {
"platform": platform,
"username": user_name
}
my_handle.process_data(data, "follow")

try:
client.run()
try:
client.stop()
logging.info(f"连接{room_id}中...")
client.run()

except LiveNotFound:
logging.info(f"用户ID: @{client.unique_id} 好像不在线捏, 1分钟后重试...")
except LiveNotFound:
logging.info(f"用户ID: @{client.unique_id} 好像不在线捏, 1分钟后重试...")
start_client()

# 运行客户端
start_client()
elif platform == "twitch":
import socks
from emoji import demojize
Expand Down
Loading

0 comments on commit f2be24a

Please sign in to comment.