dsh-kylin-media
v0.3.0
Published
麒麟(QiLin)/ DSH 多媒体网关插件:连接本地 comfyui-gateway,在会话里出图、出视频、出音乐、对口型,并做语音转写、合成与分离。
Maintainers
Readme
dsh-kylin-media
把本地 comfyui-gateway 接进麒麟(QiLin)/ DSH 会话:出图、出视频、出音乐、对口型、图片超分,以及语音转写、语音合成与人声/伴奏分离。
插件由两半组成,同一份包同时服务两个宿主:
- Host(
entry.js+lib/):注册 6 个media_*工具、一个随包的kylin-media技能,以及一个只允许回环访问的 JSON API; - Client(
client.js):只注册 设置页面 的一个菜单「多媒体网关」,用于配置网关地址、访问 Key、等待时长与产物目录,并展示实时能力目录。
访问 Key 只写入插件私有目录下的 settings.json(POSIX 下目录 0700 / 文件 0600;Windows 由用户私有目录的 ACL 保护),UI 与 API 都只回显脱敏串。
安装
发布到 registry 后:
qilin plugin --profile <profile> add dsh-kylin-media
# 或 DSH
dsh plugin --profile <profile> add dsh-kylin-media本地目录安装(开发 / 内网分发):
qilin plugin --profile <profile> add /path/to/dsh-kylin-media安装后如果页面没有出现菜单,刷新一次浏览器;替换同版本包需要重启宿主进程才能加载新的客户端 JavaScript。
发布到 npm
包已在 package.json 里配置 publishConfig.registry = https://registry.npmjs.org/,npm publish 不会误发到本机配置的 npmmirror(镜像是只读的,发不上去)。
npm login --registry=https://registry.npmjs.org/
npm whoami --registry=https://registry.npmjs.org/
cd dsh-kylin-media
npm publish # prepack 会自动跑 smoke- 发布前可先
npm pack --dry-run检查载荷(files白名单,约 17-19 个文件)。 - 版本一旦发布不可覆盖;升级用
npm version patch|minor|major后再 publish。 - 刚发布的版本可能被宿主 profile 的
minimumReleaseAge(pnpm 默认 24h)拒绝安装,等一段时间或把包名加入该 profile 的排除项。 - 安装:
qilin plugin --profile <profile> add dsh-kylin-media。
设置
打开 设置 → 多媒体网关:
| 项 | 说明 |
|---|---|
| 网关地址 | 默认 http://127.0.0.1:8288;局域网用 http://<主机IP>:8288,frp / 反代填对外地址。编辑的是「当前线路」的地址 |
| 连接线路 | 可同时保存多条地址(本机 / 局域网 / frp 公网),点圆点切换当前线路,「测试连接」与所有 media_* 都用它;「全部测速」并发探测每条线路并标出最快可用的那条 |
| 访问 Key | 网关 API_KEY_MODE=always 时必填;保存后不再回显明文,留空表示沿用已保存的值 |
| 单次最多等待 | 工具调用内等待任务的秒数(10-600);超时不影响网关侧任务,可继续用 media_job |
| 产物目录 | 留空 = <会话目录>/media-output/<任务 id>/;也可填绝对路径 |
| 自动下载 | 关闭后只返回远端 URL,用 media_job action=download 取回 |
| 默认模型 | 「可用能力」卡片里逐类型列出网关实时目录中的模型,点选即设为该类型默认模型并立即保存;media_* 未传 model 时用它,没选则用该类型第一个可用模型 |
页面上的「测试连接」会读取 /api/health 与 /api/models,显示网关版本、鉴权模式、ComfyUI 与双卡队列,并按能力类型列出具体模型(含可用性与权重缺失),可直接点选默认模型。连接失败时会给出排查提示。
常见坑:网关默认监听明文 HTTP(
API_PORT=8288)。frp / 反代把 8288 映射出去后仍然是 HTTP,地址要写http://<对外地址>:<端口>;写成https://会在 TLS 握手阶段被断开,错误信息里会提示「这个端口没有完成 TLS 握手…把地址改成 http:// 再试」。反过来,如果前面套了 nginx / Caddy 的 HTTPS,则必须写https://(自签证书还需要让运行宿主信任该 CA)。
为什么「本机 / 局域网」地址连不上:
127.0.0.1/localhost只有网关和插件跑在同一台机器时才通。网关在远端(例如 Windows 主机)而插件在 Mac 上时,本机地址必然被拒绝。- 局域网地址要求两者在同一网段,且网关监听
HOST=0.0.0.0(默认)、系统防火墙放行 8288(仓库里有add-firewall-rule.bat)。可先用curl http://<主机IP>:8288/api/health验证。- 上面两条都不满足时只能用 frp / 公网地址。把三条地址都加进「连接线路」,点「全部测速」即可看出哪条通、哪条最快;失败原因直接写在行内(拒绝连接 / 不可达 / 域名解析失败 / 协议写反)。
局域网里偶发
EHOSTUNREACH(刚唤醒、Wi-Fi 切换、ARP 未就绪)不用管:所有 GET 探测都会自动重试最多 2 次;仍失败时先在本机curl http://<主机IP>:8288/api/health复核。
工具
| 工具 | 作用 |
|---|---|
| media_health | 网关 / ComfyUI / 队列 / 鉴权状态;action=test 附带能力目录 |
| media_models | 按类型列模型、可用性与缺失文件;传 model 看参数 schema |
| media_generate | 按「类型 + 模型」提交生成,支持等待与自动下载 |
| media_audio | transcribe / speech / separate 三种语音能力 |
| media_job | status / wait / list / cancel / delete / download |
| media_upload | 上传参考图 / 音频 / 视频,返回可填进 params.image 等的 name |
生成类型:text2image、image_edit、text2video、image2video、reference2video、lipsync、music、upscale、video_upscale、extract_frame。
同族模型带 tier(fast/balanced/quality)与 group;不给 model 时可传 tier + group 选档,例如 media_generate type=video_upscale tier=fast group=video-upscale params={"video":"clip.mp4"}。
错误码 missing-nodes(缺 ComfyUI 节点)、tier-not-found、ambiguous-group 会附带修复建议。
语音能力:asr(whisper)、tts(本地 MeloTTS / 小米 MiMo)、separate(demucs 4 轨)。
例子
media_generate type=text2image params={"prompt":"雪夜里的红灯笼,浅景深","width":1024,"height":576,"seed":42}
media_upload file=D:\refs\frame.png
media_generate type=image2video params={"prompt":"她转身微笑","image":"frame.png","length":124} wait=false
media_job action=wait id=<上一步的 job id> waitSeconds=300
media_audio action=transcribe file=D:\audio\song.wav language=zh srt=true
media_audio action=speech text="你好,这是本地语音合成。" format=mp3产物默认落到会话目录的 media-output/<任务 id>/,返回绝对路径;图片可直接用 read_image 查看。
包契约
package.json同时声明dsh.bundle.patch与qilin.bundle.patch,两者指向同一份cordis.patch.yml;dsh.client.bundle/qilin.client.bundle指向手写零构建的client.js,通过window.__ModuleLoader__.load自注册;files是发布载荷白名单,新增模块或资源时同步更新;- 无运行时依赖,Node ≥ 20。
安全边界
- 插件 API 只接受回环
Host(127.0.0.1/localhost/::1),其它来源一律 403; - 访问 Key 不写入 composition,不走宿主设置 RPC,只存在
<QILIN_HOME|DSH_HOME|~/.kcoder>/.dsh-kylin-media/settings.json; - 任何响应都不包含明文 Key;UI 输入框保存后即清空;
- 产物下载只允许当前网关同源的
/api/files/*地址,避免被任务数据带去任意主机。
开发
cd dsh-kylin-media
npm test # smoke(包契约 + 客户端自注册 + locale/icon/技能)+ selftest(mock ctx + mock 网关)+ client-test(渲染自测)selftest 会用临时 HOME 与 127.0.0.1 上的 mock 网关跑完整链路:设置持久化、403 / 400 / 404 / 405 围栏、默认模型选择与回退、提交轮询、产物下载、鉴权头、注册与卸载。
client-test 用最小 React 替身渲染设置页的「可用能力」卡片:类型卡片列出具体模型、默认模型高亮、点选后 POST settings.update、缺权重模型不可选,且渲染树不含明文 Key。
目录
dsh-kylin-media/
├── entry.js # 宿主入口:设置播种、工具 / 路由 / 技能注册
├── client.js # 设置页菜单(手写零构建)
├── lib/
│ ├── home.js # 插件私有目录解析
│ ├── store.js # settings.json(0600、原子写、Key 脱敏)
│ ├── gateway.js # comfyui-gateway 客户端
│ ├── runner.js # 轮询、终态、下载
│ ├── catalog.js # 类型标签与能力摘要
│ ├── tools.js # media_* 工具面
│ └── routes.js # fenced JSON API
├── skills/kylin-media/ # 随包技能
├── locale/ # 插件管理器展示元数据
└── scripts/ # smoke / selftest / client-testLicense
MIT
