数据结构
插件返回的 JSON 会被反序列化为 mio-music-sdk 里的 Rust 类型。字段名与类型必须对得上,否则整次调用会失败。本页列出每一种结构。
下面表格的「必填」列表示:缺少该字段时反序列化是否失败。「可选」字段缺失时取默认值(空串、null 或 0)。
MusicItem(歌曲)
歌曲在列表里出现、被收藏、加入歌单、下载,最后又作为 song 参数传回你的 musicUrl / lyrics 等方法,都是这个结构。所有字段都是可选的,但实际上请至少填写前面几项。
| 字段 | 类型 | 说明 |
|---|---|---|
songmid | string | number | 歌曲在来源里的唯一 ID。建议用字符串。 |
name | string | 歌名。 |
singer | string | 歌手名,多个歌手自行拼接。 |
albumName | string | 专辑名。 |
albumId | string | number | 专辑 ID,之后可用于 albumDetail。 |
singerId | string | 歌手 ID,用于跳转到歌手页。 |
source | string | 来源 ID。宿主会改写成本次调用的来源,但仍建议填写。 |
interval | string | 时长,格式 mm:ss(或 hh:mm:ss)。 |
img | string | 封面 URL,没有则空串。 |
types | string[] | 这首歌可用的音质名称(128k、320k、flac …),由差到好。 |
_types | object | 各音质的补充信息:{ "320k": { size: "9.8MB", hash?: "…" } }。size 是字符串。 |
typeUrl | object | 私有数据的容器,见下文。 |
lrc | string | null | 已经附带的歌词文本,通常为 null。 |
hash、songId、strMediaMid、albumMid、copyrightId、lrcUrl、mrcUrl、trcUrl | 各异 | 原版若干来源用到的额外字段,自建来源一般不需要。 |
字符串类型的字段(name、singer、albumName、interval、img 等)如果传了数字,整个结果都会被拒绝。服务器返回数字的时候,用 String(v) 转换一下。
私有数据放在哪里
歌曲会被缓存、写入收藏与歌单、交给下载器,再在播放时传回你的方法。这个过程通过 MusicItem 结构往返,所以结构里没有的字段会丢失——你自己加的 serverPath、token 之类的顶层字段,到 musicUrl 时已经不在了。两个办法:
- 把定位歌曲所需的一切编进
songmid(例如"srv1:12345"),在方法里再拆开; - 或把私有字段放进
typeUrl对象。typeUrl是自由结构,会随歌曲完整保留,旧版服务适配层也用它保存原始来源。
function toSong(v) {
return {
songmid: String(v.id),
name: String(v.title || ''),
singer: String(v.artist || ''),
albumName: String(v.album || ''),
source: 'myid',
interval: mmss(Math.trunc(v.duration) || 0),
img: coverUrl(v),
types: ['128k', '320k'],
typeUrl: { path: v.path }, // 私有数据:播放时从 song.typeUrl.path 读回
};
}
SearchResult
search、singerSongs 的返回值。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
list | MusicItem[] | 是 | 本页歌曲。 |
allPage | integer | 是 | 总页数。 |
limit | integer | 是 | 本页大小,通常原样返回参数里的 limit。 |
total | integer | 是 | 总条数。 |
source | string | 是 | 来源 ID(宿主会改写,但字段本身必须存在)。 |
PlaylistResult 与 PlaylistItem
searchPlaylist、getPlaylists 的返回值,以及发现页里歌单列表的元素。
| PlaylistResult | 类型 | 必填 |
|---|---|---|
list | PlaylistItem[] | 是 |
allPage、limit、total | integer | 是 |
source | string | 是 |
| PlaylistItem | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | number | 是 | 之后作为 playlistDetail 的 id 传回。 |
name | string | 是 | |
img | string | 是 | 封面 URL,可为空串。 |
source | string | 是 | |
desc | string | 否 | 简介。 |
author | string | 否 | 创建者。 |
playCount | number | string | null | 否 | 播放量。 |
total | number | string | null | 否 | 歌曲数。 |
PlaylistDetail
playlistDetail、albumDetail、chartDetail 的返回值:一页歌曲,加上歌单自身的信息。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
list | MusicItem[] | 是 | 本页歌曲。 |
info | object | 是 | { name, img, desc, author },四项均为可选字符串,没有就给 {}。 |
allPage、limit、total | integer | 是 | |
source | string | 是 |
歌手
SingerInfo
| 字段 | 类型 | 必填 |
|---|---|---|
id、source、name、desc、avatar | string | 是 |
gender | string | null | 否 |
musicCount、albumCount | integer | 是 |
SingerAlbumPage
| 字段 | 类型 | 必填 |
|---|---|---|
list | SingerAlbum[] | 是 |
allPage、limit、total | integer | 是 |
source | string | 是 |
其中 SingerAlbum 为 { id, count, name, author, img, desc }:id、name、author、img 是字符串(ID 不能是数字),count 是整数,desc 是字符串或 null。id 之后会作为 albumDetail 的 id 传回。
发现页
has_more 和 update_frequency,不是 hasMore 和 updateFrequency。写成 camelCase 会得到「字段缺失」的错误。其中嵌套的 PlaylistItem、MusicItem 仍然是 camelCase。
DiscoveryCategories(discoveryCategories)
{
groups: [
{ name: '专辑', list: [{ id: 'newest', name: '最新添加', source }] },
],
hot: [{ id: 'newest', name: '最新添加', source }],
source,
}
groups 与 hot 都是必填;分类里的 id 是字符串,会作为 discoveryPlaylists 的 category 传回。
DiscoveryPlaylistPage(discoveryPlaylists)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
list | PlaylistItem[] | 是 | |
page | integer | 是 | 当前页码。 |
total | integer | null | 否 | 来源不提供总数时给 null,不要估算。 |
has_more | boolean | 是 | 是否还有下一页。 |
source | string | 是 |
DiscoveryChart(discoveryCharts 的数组元素)
{ id: 'random', name: '随机歌曲', img: '', source, update_frequency: '' }
全部字段必填且都是字符串,id 最长 40 个字符,会作为 chartDetail 的 id 传回。
Lyric(歌词)
| 字段 | 类型 | 说明 |
|---|---|---|
lyric | string | 逐行 LRC 文本,每行形如 [mm:ss.xx]歌词。既没有 lyric 也没有可解析的 ttml,就视为没有歌词。 |
tlyric | string | 翻译 LRC,时间轴与 lyric 对应,没有就留空。 |
rlyric | string | 音译(罗马音)LRC,没有就留空。 |
crlyric | string | 逐字歌词文本,没有就留空。排版由 crlyricFormat 说明。 |
crlyricFormat | string | 可选,crlyric 的逐字排版。wordTagBefore(默认):[start,duration] 之后是若干 (start,duration,0)词,标签在词前;wordTagAfter:[start,duration] 之后是若干 词(start,duration),标签在词后;wordTagAfterWithProperty:行首是 [属性](0–8,表示对唱与背景声),之后同样是 词(start,duration)。时间单位都是毫秒。不符合任何一种的文本只显示逐行歌词。 |
source | string | 来源 ID。 |
ttml | string | 可选。带逐字时间的 TTML 文档。提供它,歌词页就能做逐字高亮。可用 cerumusic.utils.lyric.validTtml 事先校验。 |
来源自己的加密、压缩或私有排版格式(例如 KRC、MRC、QRC、LYRICX)由插件自己解码成上面的通用字段;宿主不提供这些来源专用的解码,只提供 zlib 解压与字符集解码这类通用工具。
整个返回值序列化后不得超过 4 MB。服务器没有歌词时,throw new Error('没有找到歌词'),而不是返回空对象。
Comments(评论)
{
comments: [
{
id: '123', // 用于去重,必须唯一
userName: 'Mio',
avatar: 'https://…',
timeStr: '2026-10-01',
text: '好听!',
likedCount: 42,
images: ['https://…'], // 可选
reply: [ /* 同结构的回复,可选 */ ],
},
],
total: 1280, // 总评论数
maxPage: 43, // 总页数
cursor: '', // 下一页游标,没有就空串或省略
}
- 一页最多 300 条,整体序列化后不超过 4 MB,否则整次调用被拒绝。
text按纯文本展示,宿主会对其中的 HTML 做转义,所以不必也不应当自己转义。avatar与images只接受不含用户名密码的http(s)地址,不合法的会被忽略。- 返回对象里加上
cursorPaged: true,表示「最新评论」要靠游标翻页:此时返回的cursor为空,或与上一页相同,应用就认为已经到底并停止翻页。 cursor只允许字母、数字与下划线,最长 256 个字符。如果连续两次返回的内容相同(id全部重复),应用会认为已经到底并停止翻页。