音源目录 API 详解
「作者自有音源目录」插件用 echo.sources.registerProvider 向 ECHO 提供可搜索的条目,用户确认后由宿主经 Audio Core 播放直链。入门 → 插件教程 · catalog;边界 → 下载与插件音源法律边界。
不能做成「搜网易云 / Spotify 歌名就播」。只能暴露你有权提供的 HTTP(S) 音频 URL,通常来自自建 API + 你已授权存储的音频文件。
node .\bin\echo-workshop-sdk.mjs init .\catalog --recipe source-catalognpm run add -- --permission network:request典型权限:
| 权限 | 用途 |
|---|---|
sources:provide | 注册 provider |
sources:direct | resolve 返回可播放直链 |
network:request | echo.network.get/post |
fs:plugin | 可选,存用户偏好等小 JSON |
外层 content/echo.workshop.json 声明 networkHosts(仅域名,如 audio.example.com)。
四个 handler
Section titled “四个 handler”echo.sources.registerProvider('owned-catalog', { title: '我的目录' }, { search: async ({ query, page, pageSize }) => { /* ... */ }, browse: async ({ page, pageSize }) => { /* ... */ }, listCollection: async ({ collectionId, page, pageSize }) => { /* ... */ }, resolve: async ({ providerTrackId }) => { /* ... */ },});| 方法 | 何时调用 | 返回 |
|---|---|---|
search | 用户搜索 | { tracks, total, hasMore } |
browse | 浏览首页/目录 | 同上 |
listCollection | 打开某个合集 | 同上 |
resolve | 用户要播某条 | 一条直链对象 |
tracks[] 条目字段(常用)
Section titled “tracks[] 条目字段(常用)”每条 track 至少要有稳定 id(provider 内唯一),以及展示用 title / artist 等(见 API 2 类型 .echo-sdk/echo-workshop-plugin.d.ts)。不要在这里塞 file:// 或未声明域名 URL。
resolve 返回
Section titled “resolve 返回”return { url: 'https://audio.example.com/stream/abc123', // 必须 http(s) title: 'Song', artist: 'Artist', album: 'Album', live: false, // 可选,直播流标记};- 只有
resolve可以返回最终播放 URL - 用户第一次播某域名时 ECHO 会再确认
- 用户拒绝后插件不得循环弹窗
const res = await echo.network.get( `https://audio.example.com/catalog?q=${encodeURIComponent(query || '')}&page=${page}&pageSize=${pageSize}`);const payload = JSON.parse(res.body);规则:
| 规则 | 原因 |
|---|---|
URL 的 host 必须在 networkHosts 里 | mock 与生产都会拒 |
| 不要自定义端口 | 用 443/80;network-port-denied |
| 优先 HTTPS | HTTP 兼容但作者应优先 https |
| 不要带 Cookie / Token 头绕过授权 | 违规且易封号 |
生产环境:先解析 DNS 到公网 IP,再连已校验地址,保留原 Host/TLS。
本地 mock 与真网
Section titled “本地 mock 与真网”test / dev 的 mock 不会真的访问互联网,但会检查:
- 是否声明了 permission
- 请求 host 是否在 networkHosts
- handler 是否抛错
示例里常用 example.invalid 域名;换成你的 API 前记得写进 manifest。
完整片段:
node .\bin\echo-workshop-sdk.mjs snippet source-provider-searchnode .\bin\echo-workshop-sdk.mjs example network-source后端 API 建议形状(非强制)
Section titled “后端 API 建议形状(非强制)”作者自建 API 常见约定(你可自定义,只要 JSON 能 parse):
GET /catalog?q=&page=&pageSize= → { tracks: [...], total, hasMore }GET /collections/:id?page= → { tracks, total, hasMore }GET /resolve/:providerTrackId → { url, title, artist, album, live? }- 分页:
page从 1 起,pageSize合理上限(如 24–50) - 错误:返回 4xx/5xx,插件应
notify用户可读信息,别吞异常 - 版权:只索引你有权串流的文件
清单与 sync
Section titled “清单与 sync”改 src/plugin.js 或 networkHosts 后 必须 npm run check。内层 community.echo 的 apiVersion 与外层 compatibility.pluginApiVersion 一致。
- 插件教程
- 开发调试 · mock 拒绝
- 官方示例 · network-source
echo-workshop-sdk api errors— 哪些错误可重试