Skip to content

Edint386/simple-kook-voice

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simple-kook-voice

Python SDK for kook music bot
希望做成一款开箱即用的推流sdk
遇到问题/功能建议/代码贡献都可以来 KOOK服务器 找我

Special Thanks

hank9999: 提供了0.0.x版本中的voice.py 以及 大部分推流底层逻辑

安装

pip install kookvoice

需要自备ffmpeg且配置好全局变量
不配置全局变量的话需要在代码中指定ffmpeg路径 如下:

import kookvoice

kookvoice.set_ffmpeg("F:/ffmpeg/bin/ffmpeg.exe")

其余python依赖已写在reqirements.txt中
当然你可以可以直接 pip install aiohttp
因为就这一个依赖 而且如果常用khl.py肯定装了

使用教程

先放一个最基础的推流体验一下

import kookvoice

kookvoice.configure_logging()

music_path_or_link = "https://static.xsnight.cn/Ulchero,Couple%20N%20-%20Love%20Trip.mp3"  # 仅示例音频,侵权请联系删除
player = kookvoice.Player('服务器id', '语音频道id', '机器人token')
player.add_music(music_path_or_link)

kookvoice.run()

看过了基础的使用教程,但是如何与机器人(khl.py)实现结合呢? 还没接触过khl.py的情况下记得先 pip install khl.py

import asyncio
import kookvoice
from khl import *

bot_token = 'your_bot_token'
bot = Bot(token=bot_token)

kookvoice.set_ffmpeg("ffmepg")
kookvoice.configure_logging()

async def find_user(gid, aid):
    # 调用接口查询用户所在的语音频道
    voice_channel_ = await bot.client.gate.request('GET', 'channel-user/get-joined-channel',
                                                   params={'guild_id': gid, 'user_id': aid})
    voice_channel = voice_channel_["items"]
    if voice_channel:
        vcid = voice_channel[0]['id']
        return vcid


# 让点歌机加入频道
# 这条指令其实完全没用,因为点歌了会自动加入语音频道
# 但是还是写了,万一有人要呢
# 指令: /join
@bot.command(name='join')
async def join_vc(msg: Message):
    # 获取用户所在频道
    voice_channel_id = await find_user(msg.ctx.guild.id, msg.author_id)
    if voice_channel_id is None:
        await msg.ctx.channel.send('请先加入语音频道')
        return
    player = kookvoice.Player(msg.ctx.guild.id, voice_channel_id, bot_token)
    player.join()
    voice_channel = await bot.client.fetch_public_channel(voice_channel_id)
    await msg.ctx.channel.send(f'已加入语音频道 #{voice_channel.name}')


# 播放直链或本地歌曲
# 指令: /播放 https://static.xsnight.cn/Ulchero,Couple%20N%20-%20Love%20Trip.mp3
@bot.command(name='播放')
async def play(msg: Message, music_url: str):

    # 第一步:获取用户所在的语音频道
    voice_channel_id = await find_user(msg.ctx.guild.id, msg.author_id)
    # 如果不在语音频道就提示加入语音频道后点歌
    if voice_channel_id is None:
        await msg.ctx.channel.send('请先加入语音频道')
        return

    # 如果用户发了音乐直链,会被kook转为链接的kmd,要拆一下
    if 'http' in music_url and '[' in music_url:
        music_url = music_url.split('[')[1].split(']')[0]

    # 这时候只需要为他添加歌曲即可
    # 构建一个player,首次使用需要填写服务器id,语音频道id以及token
    player = kookvoice.Player(msg.ctx.guild.id, voice_channel_id, bot_token)

    # 这里的extra data是歌曲的备注信息,你可以在这里存入播放列表
    # 而后在播放列表里以及歌曲切换时获取到这些信息
    # 当然想不填也完全没问题
    extra_data = {"音乐名字": "未知", "点歌人": msg.author_id, "文字频道": msg.ctx.channel.id}

    # 注:如果填写的为本地播放路径,建议填写绝对路径
    player.add_music(music_url, extra_data)

    # 机器人提示点歌成功
    await msg.ctx.channel.send(f'添加音乐成功 {music_url}')


# 既然能够添加歌曲 那也得有控制选项
# 指令: /跳过
@bot.command(name='跳过')
async def skip(msg: Message):
    # 在当前服务器歌单有歌曲的时候,你可以直接填入guild_id来获取player
    player = kookvoice.Player(msg.ctx.guild.id)
    player.skip()
    await msg.ctx.channel.send(f'已跳过当前歌曲')


# 指令: /停止
@bot.command(name='停止')
async def stop(msg: Message):
    player = kookvoice.Player(msg.ctx.guild.id)
    player.stop()
    await msg.ctx.channel.send(f'播放已停止')


from khl.card import Module, Card, CardMessage


# 指令: /列表
@bot.command(name="列表")
async def list(msg: Message):
    player = kookvoice.Player(msg.ctx.guild.id)
    music_list = player.list()
    c = Card(color='#FFA4A4')
    c.append(Module.Context('正在播放'))
    c.append(Module.Header(f"{music_list.pop(0)['file']}"))
    c.append(Module.Divider())
    for index, i in enumerate(music_list):
        # 这里的extra data 便是点歌的时候放入的东西
        c.append(Module.Context(f"{index + 1}. {i['file']} 点歌人:(met){i['extra_data']['点歌人']}(met)"))
    await msg.ctx.channel.send(CardMessage(c))


# 指令: /跳转 120
# 注:120是秒数
@bot.command(name="跳转")
async def seek(msg: Message, time: int):
    player = kookvoice.Player(msg.ctx.guild.id)
    player.seek(time)
    await msg.ctx.channel.send(f'已跳转到 {time} 秒')


# 切歌时触发事件便于发送开始的消息
from kookvoice import run_async


@kookvoice.on_event(kookvoice.Status.START)
async def on_music_start(play_info: kookvoice.PlayInfo):
    guild_id = play_info.guild_id
    voice_channel_id = play_info.voice_channel_id
    music_bot_token = play_info.token
    extra_data = play_info.extra_data  # 你可以在这里获取到歌曲的备注信息
    text_channel_id = extra_data['文字频道']

    text_channel = await bot.client.fetch_public_channel(text_channel_id)
    await text_channel.send(f"正在播放 {play_info.file}")


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    # 使用gather同时启动机器人与推流
    loop.run_until_complete(asyncio.gather(bot.start(), kookvoice.start()))

Contribute

在保证 简单易用 的宗旨下,十分欢迎大家的pr!