hanxi/xiaomusic

【插件】自定义口令功能

hanxi opened this issue · 13 comments

自定义口令配置需要配置到 config.json 文件里,使用 config.json 方式启动。参考 #94

口令的配置方式见 config-example.json 文件。口令对应的代码需要写到 plugins/ 目录下面,如果是容器启动,则需要把这个目录挂载出来。

config.json 格式是下面这样的。

{
    "hardware": "L07A",
    "account": "",
    "password": "",
    "mi_did": "",
    "cookie": "",
    "verbose": false,
    "music_path": "music",
    "conf_path": null,
    "hostname": "192.168.2.5",
    "port": 8090,
    "public_port": 0,
    "proxy": null,
    "search_prefix": "bilisearch:",
    "ffmpeg_location": "./ffmpeg/bin",
    "active_cmd": "play,random_play,playlocal,play_music_list,stop",
    "exclude_dirs": "@eaDir",
    "music_path_depth": 10,
    "disable_httpauth": true,
    "httpauth_username": "admin",
    "httpauth_password": "admin",
    "music_list_url": "",
    "music_list_json": "",
    "disable_download": false,
    "key_word_dict": {
        "播放歌曲": "play",
        "播放本地歌曲": "playlocal",
        "关机": "stop",
        "下一首": "play_next",
        "单曲循环": "set_play_type_one",
        "全部循环": "set_play_type_all",
        "随机播放": "random_play",
        "分钟后关机": "stop_after_minute",
        "播放列表": "play_music_list",
        "刷新列表": "gen_music_list",
        "set_volume#": "set_volume",
        "get_volume#": "get_volume",
        "本地播放歌曲": "playlocal",
        "放歌曲": "play",
        "暂停": "stop",
        "停止": "stop",
        "停止播放": "stop",
        "测试自定义口令": "exec#code1(\"hello\")",
        "测试链接": "exec#httpget(\"https://github.com/hanxi/xiaomusic\")"
    },
    "key_match_order": [
        "set_volume#",
        "get_volume#",
        "分钟后关机",
        "播放歌曲",
        "下一首",
        "单曲循环",
        "全部循环",
        "随机播放",
        "关机",
        "刷新列表",
        "播放列表",
        "播放本地歌曲",
        "本地播放歌曲",
        "放歌曲",
        "暂停",
        "停止",
        "停止播放",
        "测试自定义口令",
        "测试链接"
    ],
    "use_music_api": false,
    "use_music_audio_id": "1582971365183456177",
    "use_music_id": "355454500",
    "log_file": "/tmp/xiaomusic.txt",
    "fuzzy_match_cutoff": 0.6,
    "enable_fuzzy_match": true,
    "stop_tts_msg": "收到,再见",
    "keywords_playlocal": "播放本地歌曲,本地播放歌曲",
    "keywords_play": "播放歌曲,放歌曲",
    "keywords_stop": "关机,暂停,停止,停止播放",
    "user_key_word_dict": {
        "测试自定义口令": "exec#code1(\"hello\")",
        "测试链接": "exec#httpget(\"https://github.com/hanxi/xiaomusic\")"
    }
}

配置自定义口令时,只需要配置 user_key_word_dict 即可,会自动插入到 key_word_dict 里的。配置格式是:

 "测试自定义口令": "exec#code1(\"hello\")",

其中 "测试自定义口令" 就是对小爱音箱说的,"exec#code1(\"hello\")" 就是要执行的插件代码,代码以 exec# 开头,后面紧跟着执行代码。这里 code1 是一个插件函数,插件函数需要在 plugin 目录里实现,一个文件只会导出一个与文件名相同的插件函数。所以 code1 函数是在 plugin/code1.py 里实现的。

async def code1(arg1):
    global log, xiaomusic
    log.info(f"code1:{arg1}")
    await xiaomusic.do_tts("你好,我是自定义的测试口令")

这里只是演示了打印日志和让小爱音箱说话。还有一个示例插件是 httpget ,可以用来访问 url 。

比如下面这样配置的话,当对小爱音箱说测试链接时,会去访问 url ,可以用来很多其他的事情。

"测试链接": "exec#httpget(\"https://github.com/hanxi/xiaomusic\")

最后还需要在 active_cmd 中配上口令用于唤醒:

  "active_cmd": "play,set_random_play,playlocal,play_music_list,play_music_list_index,stop_after_minute,stop,测试自定义口令",

感兴趣的可以体验一下,写了有什么好玩的插件也可以在这里分享,或者提 pr 合并进官方库里作为自带插件。

如果开启服务的状态下 如何唤醒才能调用原有的播放QQ 网易云?而特定唤醒词调用xiaoai播放?

如果开启服务的状态下 如何唤醒才能调用原有的播放QQ 网易云?而特定唤醒词调用xiaoai播放?

不使用 xiaomusic 的唤醒词就会调用音箱自带的,比如说播放音乐

[23:26:12] [0.3.30] [INFO] xiaomusic.py:531: 收到消息:测试自定义口令 控制面板:False did:290874427
[23:26:12] [0.3.30] [INFO] xiaomusic.py:577: 完全匹配指令. query:测试自定义口令 opvalue:exec#code1("hello")
[23:26:12] [0.3.30] [INFO] code1.py:3: code1:hello
[23:26:12] [0.3.30] [ERROR] xiaomusic.py:542: Execption XiaoMusic.do_tts() missing 1 required positional argument: 'value'
Traceback (most recent call last):
  File "/app/xiaomusic/xiaomusic.py", line 540, in do_check_cmd
    await func(did=did, arg1=oparg)
  File "/app/xiaomusic/xiaomusic.py", line 890, in exec
    await self.plugin_manager.execute_plugin(code)
  File "/app/xiaomusic/plugin.py", line 66, in execute_plugin
    await coroutine
  File "/app/plugins/code1.py", line 4, in code1
    await xiaomusic.do_tts("你好,我是自定义的测试口令")
TypeError: XiaoMusic.do_tts() missing 1 required positional argument: 'value'

我用code1的代码执行报错,有大佬知道为什么吗?

@shellingford37 重构后漏改了,修复了。

先说播放歌曲,再说 测试自定义口令 就行

CZJCC commented

想请教下插件那个功能,如何把用户的语音输入作为参数内容传到自定义函数里

hanxi commented

想请教下插件那个功能,如何把用户的语音输入作为参数内容传到自定义函数里

现在获取不到,等我加个接口获取吧。

CZJCC commented

666,支持以后我可以贡献一个接入通义模型的插件

hanxi commented

@CZJCC 你可以更新看看 plugins/code1.py 的测试代码,我测试了是可以拿到语音输入的原始内容的。

hanxi commented

文档更新了下,active_cmd 也需要配置一下才能正常唤醒。

CZJCC commented

@CZJCC 你可以更新看看 plugins/code1.py 的测试代码,我测试了是可以拿到语音输入的原始内容的。

我原先设想的事用户的话术是”通义提问为什么地球是圆的“,指令匹配的时候通义提问前缀匹配到类似于code1方法,为什么地球是圆的作为参数传入这个函数,但我看现在是拿历史记录实现的

hanxi commented

是的,插件函数里面再切割一下前缀就行。last_record就是当前的那条语音数据。

hanxi commented

@CZJCC 你可以更新看看 plugins/code1.py 的测试代码,我测试了是可以拿到语音输入的原始内容的。

我原先设想的事用户的话术是”通义提问为什么地球是圆的“,指令匹配的时候通义提问前缀匹配到类似于code1方法,为什么地球是圆的作为参数传入这个函数,但我看现在是拿历史记录实现的

是的,这样比较简单,交给插件里面处理也比较自由。