Skip to content

歌曲管理 ​

接口列表 ​

方法路径说明
PUT/settings/remote-title-source更新网络歌曲标题来源配置
GET/settings/remote-title-source获取网络歌曲标题来源配置
PUT/settings/tag-sync-to-file保存标签同步到文件开关
GET/settings/tag-sync-to-file获取标签同步到文件开关
GET/songs获取歌曲列表
PUT/songs/{id}更新歌曲信息
DELETE/songs/{id}删除歌曲
GET/songs/{id}获取单个歌曲详情
POST/songs/{id}/activate标记当前活跃歌曲
PUT/songs/{id}/artists全量更新歌曲参与歌手
GET/songs/{id}/artists获取歌曲参与歌手
GET/songs/{id}/audio-tracks获取歌曲音频流列表
GET/songs/{id}/cover获取歌曲封面图片
GET/songs/{id}/lyric获取歌曲歌词
PUT/songs/{id}/lyrics更新歌曲歌词
GET/songs/{id}/play流式播放歌曲
GET/songs/{id}/play.m3u8流式播放歌曲
POST/songs/{id}/played通知歌曲播放事件
PUT/songs/{id}/tags写入歌曲标签
GET/songs/{id}/tracks枚举歌曲音频轨道
GET/songs/{id}/video-hls/{path}获取视频 HLS 子资源
GET/songs/{id}/video-hls/playlist.m3u8获取视频 HLS 播放列表
POST/songs/batch-delete批量删除歌曲
POST/songs/clean清理无效的本地歌曲
GET/songs/duplicates获取重复歌曲组
GET/songs/facets曲库标签分类聚合
GET/songs/folders文件夹浏览
GET/songs/ids获取匹配歌曲的 ID 列表
GET/songs/names曲库歌名/歌手名清单
POST/songs/organize批量整理歌曲文件
POST/songs/organize/preview预览批量整理歌曲文件
POST/songs/radio批量添加电台/广播
GET/songs/random随机获取歌曲
POST/songs/refresh-metadata刷新歌曲元数据
POST/songs/refresh-metadata/cancel取消元数据刷新
GET/songs/refresh-metadata/progress获取元数据刷新进度
POST/songs/remote批量添加网络歌曲
GET/songs/stats获取曲库汇总统计

PUT /settings/remote-title-source ​

更新网络歌曲标题来源配置

tag:元数据刷新时用音频标签覆盖标题;filename(默认):保持文件名作为标题,不覆盖。

需要认证

此接口需要 Bearer Token 认证

请求体 ​

标题来源配置

类型: remoteTitleSourceRequest

字段类型必填说明
title_sourcestring否可选值: tag, filename 示例: "filename"

响应 ​

200 - 返回 title_source 字段 ​

类型: remoteTitleSourceRequest

字段类型必填说明
title_sourcestring否可选值: tag, filename 示例: "filename"

400 - 请求格式错误或参数无效 ​

类型: map[string]string

500 - 保存配置失败 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /settings/remote-title-source ​

获取网络歌曲标题来源配置

tag:元数据刷新时用音频标签覆盖标题;filename(默认):保持文件名作为标题,不覆盖。

需要认证

此接口需要 Bearer Token 认证

响应 ​

200 - 返回 title_source 字段 ​

类型: remoteTitleSourceRequest

字段类型必填说明
title_sourcestring否可选值: tag, filename 示例: "filename"

内容类型 ​

  • 响应: application/json

PUT /settings/tag-sync-to-file ​

保存标签同步到文件开关

开启/关闭“自定义标签同步写入音频文件”功能。开启后,对歌曲执行 SetSongTags 时会将标签列表写入音频文件的 SONGLOFT_TAGS 自定义字段。

需要认证

此接口需要 Bearer Token 认证

请求体 ​

开关设置 {enabled: bool}

类型: object

响应 ​

200 - 保存后的开关状态 {enabled: bool} ​

类型: map[string]boolean

400 - 请求格式错误 ​

类型: map[string]string

500 - 保存配置失败 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /settings/tag-sync-to-file ​

获取标签同步到文件开关

获取“自定义标签同步写入音频文件 SONGLOFT_TAGS 字段”开关的当前状态。开启后,每次修改歌曲标签时会同步写入音频文件元数据。默认关闭。

需要认证

此接口需要 Bearer Token 认证

响应 ​

200 - 开关状态 {enabled: bool} ​

类型: map[string]boolean

内容类型 ​

  • 响应: application/json

GET /songs ​

获取歌曲列表

获取歌曲列表,支持按类型过滤、关键词搜索和分页。默认排除隐藏歌单里的歌,传 exclude_playlist_labels=none 显示全部

需要认证

此接口需要 Bearer Token 认证

查询参数 ​

参数类型必填说明
typestring否歌曲类型 可选值: local, remote, radio
keywordstring否搜索关键词
path_prefixstring否按 file_path 前缀过滤(如 music/Pop)
genrestring否按流派精确过滤
artiststring否按歌手精确过滤
albumstring否按专辑精确过滤
languagestring否按语种精确过滤
stylestring否按风格精确过滤
yearinteger否按发行年份精确过滤
decadeinteger否按年代过滤(起始年,如 1990 匹配 1990-1999)
exclude_playlist_labelsstring否排除属于这些 label 歌单的歌曲(逗号分隔), 默认 hidden; 传 none 显示全部 默认: "hidden"
limitinteger否每页数量 默认: 20
offsetinteger否偏移量 默认: 0
sortstring否排序字段,缺省 added_at 可选值: id, title, artist, album, duration, added_at, updated_at, file_modified_at, year, genre, file_size
orderstring否排序方向,缺省 desc 可选值: asc, desc

响应 ​

200 - 成功返回歌曲列表 ​

类型: map[string]any

500 - 服务器错误 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

PUT /songs/{id} ​

更新歌曲信息

更新歌曲信息(仅支持网络歌曲和电台)

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲ID

请求体 ​

歌曲信息

类型: object

字段类型必填说明
albumstring否
artiststring否
cover_urlstring否
is_liveboolean否
is_videoboolean否
titlestring否
urlstring否

响应 ​

200 - 更新成功 ​

类型: Song

字段类型必填说明
added_atstring否添加时间 示例: "2024-01-01T12:00:00Z"
albumstring否专辑名称 示例: "十一月的萧邦"
artiststring否艺术家/歌手 示例: "周杰伦"
bit_rateinteger否比特率(kbps) 示例: 320
cover_urlstring否封面图片URL 示例: "https://example.com/cover.jpg"
cue_source_pathstring否CUE 来源路径(非空表示 CUE 拆分歌曲)
cue_track_indexinteger否CUE track 序号 (1-99)
dedup_keystring否去重 key(由插件定义,典型形态 "<platform>:<platform_id>");与 PluginEntryPath 组成 UNIQUE
durationnumber否播放时长(秒) 示例: 253.5
file_modified_atstring否文件修改时间(mtime,本地歌曲扫描时记录;未知为 nil)
file_pathstring否本地文件路径 示例: "/music/周杰伦/夜曲.mp3"
file_sizeinteger否文件大小(字节) 示例: 10485760
fingerprintstring否音频指纹(Chromaprint)
fingerprint_durationnumber否指纹对应音频时长
formatstring否音频格式 示例: "mp3"
genrestring否流派 示例: "Pop"
idinteger否歌曲ID 示例: 1
is_liveboolean否是否为直播流 示例: false
is_videoboolean否是否含真实视频轨(扫描时 ffprobe 探测,排除封面);客户端据此渲染画面/选择投屏 mime 示例: false
isrcstring否ISRC(国际标准录音编码)
languagestring否语种 示例: "国语"
lyric_remote_urlstring否lyric_source=url 时的原始 URL(运行时由 LyricFetcher 拉取)
lyric_urlstring否歌词端点 URL(客户端唯一可见字段,指向 /api/v1/songs/{id}/lyric)
plugin_entry_pathstring否音源插件 entryPath(网络歌曲) 示例: "my-source"
sample_rateinteger否采样率(Hz) 示例: 44100
source_cover_urlstring否原始封面 URL(仅 JSON 输出,CoverURL 非空时保留原始值供编辑使用)
source_datastring否音源元数据 JSON(给插件 music/url 接口用,opaque)
source_urlstring否原始音源 URL(仅 JSON 输出,radio/remote 类型返回原始流地址供编辑使用)
stylestring否风格 示例: "抒情"
titlestring否标题 示例: "夜曲"
trackstring否音轨号,可为 "3" 或 "3/12"(轨号/总数) 示例: "3/12"
typestring否歌曲类型:local/remote/radio 可选值: local, remote, radio 示例: "local"
updated_atstring否最后更新时间 示例: "2024-01-01T12:00:00Z"
urlstring否网络地址 示例: "https://example.com/song.mp3"
yearinteger否发行年份 示例: 2005

400 - 请求数据错误 ​

类型: map[string]string

404 - 歌曲不存在 ​

类型: map[string]string

500 - 更新失败 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

DELETE /songs/{id} ​

删除歌曲

根据歌曲ID删除歌曲。设置 delete_files=true 时同步删除本地音频文件

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲ID

查询参数 ​

参数类型必填说明
delete_filesboolean否是否同时删除本地音频文件

响应 ​

200 - 删除成功 ​

类型: map[string]string

400 - 无效的歌曲ID ​

类型: map[string]string

500 - 删除失败 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /songs/{id} ​

获取单个歌曲详情

根据歌曲ID获取详细信息

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲ID

响应 ​

200 - 成功返回歌曲详情 ​

类型: Song

字段类型必填说明
added_atstring否添加时间 示例: "2024-01-01T12:00:00Z"
albumstring否专辑名称 示例: "十一月的萧邦"
artiststring否艺术家/歌手 示例: "周杰伦"
bit_rateinteger否比特率(kbps) 示例: 320
cover_urlstring否封面图片URL 示例: "https://example.com/cover.jpg"
cue_source_pathstring否CUE 来源路径(非空表示 CUE 拆分歌曲)
cue_track_indexinteger否CUE track 序号 (1-99)
dedup_keystring否去重 key(由插件定义,典型形态 "<platform>:<platform_id>");与 PluginEntryPath 组成 UNIQUE
durationnumber否播放时长(秒) 示例: 253.5
file_modified_atstring否文件修改时间(mtime,本地歌曲扫描时记录;未知为 nil)
file_pathstring否本地文件路径 示例: "/music/周杰伦/夜曲.mp3"
file_sizeinteger否文件大小(字节) 示例: 10485760
fingerprintstring否音频指纹(Chromaprint)
fingerprint_durationnumber否指纹对应音频时长
formatstring否音频格式 示例: "mp3"
genrestring否流派 示例: "Pop"
idinteger否歌曲ID 示例: 1
is_liveboolean否是否为直播流 示例: false
is_videoboolean否是否含真实视频轨(扫描时 ffprobe 探测,排除封面);客户端据此渲染画面/选择投屏 mime 示例: false
isrcstring否ISRC(国际标准录音编码)
languagestring否语种 示例: "国语"
lyric_remote_urlstring否lyric_source=url 时的原始 URL(运行时由 LyricFetcher 拉取)
lyric_urlstring否歌词端点 URL(客户端唯一可见字段,指向 /api/v1/songs/{id}/lyric)
plugin_entry_pathstring否音源插件 entryPath(网络歌曲) 示例: "my-source"
sample_rateinteger否采样率(Hz) 示例: 44100
source_cover_urlstring否原始封面 URL(仅 JSON 输出,CoverURL 非空时保留原始值供编辑使用)
source_datastring否音源元数据 JSON(给插件 music/url 接口用,opaque)
source_urlstring否原始音源 URL(仅 JSON 输出,radio/remote 类型返回原始流地址供编辑使用)
stylestring否风格 示例: "抒情"
titlestring否标题 示例: "夜曲"
trackstring否音轨号,可为 "3" 或 "3/12"(轨号/总数) 示例: "3/12"
typestring否歌曲类型:local/remote/radio 可选值: local, remote, radio 示例: "local"
updated_atstring否最后更新时间 示例: "2024-01-01T12:00:00Z"
urlstring否网络地址 示例: "https://example.com/song.mp3"
yearinteger否发行年份 示例: 2005

400 - 无效的歌曲ID ​

类型: map[string]string

404 - 歌曲不存在 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

POST /songs/{id}/activate ​

标记当前活跃歌曲

客户端切歌前调用,让后端 cancel 同一会话下其他歌曲的进行中工作(prefetch/transcode/reassign)。其他客户端会话不受影响。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

响应 ​

204 - 无内容 ​

400 - 无效的 song_id ​

类型: map[string]string

内容类型 ​

  • 响应: application/json

PUT /songs/{id}/artists ​

全量更新歌曲参与歌手

用请求体整组替换一首歌的参与歌手(删旧建新)。请求体 artists 数组每一项含 name/role/position:role 取 artist(主唱/表演者)或 album_artist(专辑歌手),缺省 artist;position 为同角色内展示顺序(可省略)。主要解决对唱/合唱歌曲只存了一个歌手、按搭档检索不到的问题——可在此手动补录搭档。同时按 role=artist 的名字重建 songs.artist 显示串(对唱得到 "A & B")。角色非法返回 400;歌曲不存在返回 404。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

请求体 ​

参与歌手全量列表(整组替换)

类型: songArtistsRequest

字段类型必填说明
artistsArtistInput[]否

响应 ​

200 - 更新后的参与歌手列表 ​

类型: songArtistsResponse

字段类型必填说明
artistsSongArtist[]否

400 - 无效的歌曲 ID 或角色非法 ​

类型: map[string]string

404 - 歌曲不存在 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /songs/{id}/artists ​

获取歌曲参与歌手

返回一首歌的全部参与歌手(含角色 artist/album_artist 与顺序)。多值歌手由此拆分展示,供前端编辑界面加载当前状态。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

响应 ​

200 - 参与歌手列表 ​

类型: songArtistsResponse

字段类型必填说明
artistsSongArtist[]否

400 - 无效的歌曲 ID ​

类型: map[string]string

404 - 歌曲不存在 ​

类型: map[string]string

内容类型 ​

  • 响应: application/json

GET /songs/{id}/audio-tracks ​

获取歌曲音频流列表

用 ffprobe 探测该歌曲文件的音频流,返回每条流的 audio-relative index(对应 ffmpeg -map 0🅰️N)、title、language、codec、default。主要用于 Web 端双音轨(原唱/伴奏 mka)切换:前端据 tracks 数量决定是否显示切轨入口,并用 index 调 /songs/{id}/play?track=N 抽轨播放。仅本地歌曲(或已落地缓存的网络歌曲)有文件可探测;无可探测文件或音频流 < 2 条时也正常返回(前端据此不显示切轨)。运行时按需探测,不落库。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

响应 ​

200 - 音频流列表 ​

类型: audioTracksResponse

字段类型必填说明
tracksAudioTrackInfo[]否

400 - 无效的歌曲 ID ​

类型: map[string]string

404 - 歌曲不存在 ​

类型: map[string]string

内容类型 ​

  • 响应: application/json

GET /songs/{id}/cover ​

获取歌曲封面图片

根据歌曲 ID 获取封面图片。优先使用本地封面文件(CoverPath),其次代理 CoverURL。CoverURL 支持以 "/" 开头的相对路径,服务端自动经 InternalURLResolver 解析为内部 URL(含 access_token),用于插件歌曲封面代理。可选 query 参数 w:把本地封面等比缩放到该宽度(物理像素,绝不放大、上限 1024)后以 JPEG 返回,用于 Web 端降低 GPU 纹理体积(songloft-org/songloft#309);缺省或非法时返回原图。缩略仅作用于本地封面,远程代理封面忽略 w。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

查询参数 ​

参数类型必填说明
winteger否本地封面缩略目标宽度(物理像素,绝不放大,上限 1024)

响应 ​

200 - 封面图片 ​

类型: file

400 - 无效的歌曲 ID ​

类型: map[string]string

404 - 歌曲或封面不存在 ​

类型: map[string]string

500 - 服务器错误 ​

类型: map[string]string

内容类型 ​

  • 响应: image/jpeg

GET /songs/{id}/lyric ​

获取歌曲歌词

根据 song.ID 返回 LyricPayload JSON,含 lyric/tlyric/rlyric/lxlyric。优先级:旁挂 .lrc 文件 > DB url > DB payload > 歌词搜索插件。manual 歌词不被旁挂覆盖。传 refresh=1 时强制重新抓取:跳过库中自动获取的旧歌词(空/scraped/cached)重跑歌词搜索插件,响应挂 no-store 不缓存;file/embedded/manual 等权威歌词不被覆盖。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

查询参数 ​

参数类型必填说明
refreshboolean否为 true 时绕过缓存强制重新抓取歌词(重跑歌词搜索插件,不覆盖 file/embedded/manual 歌词)

响应 ​

200 - LyricPayload ​

类型: map[string]any

404 - 歌曲或歌词不存在 ​

类型: string

502 - 歌词获取失败 ​

类型: string

内容类型 ​

  • 响应: application/json

PUT /songs/{id}/lyrics ​

更新歌曲歌词

更新指定歌曲的歌词内容和来源。url 来源传 lyric_remote_url,其它来源传 lyric/tlyric/rlyric/lxlyric 四字段。响应里的 file_write_status 表示是否把元数据回写到本地音频文件:written=已写入,unchanged=未变更(非本地歌曲/无文件路径/不支持的扩展名/url 来源),skipped=标签已一致无需写入,failed=尝试写入但失败(DB 已成功)。lyric_source=manual 用于标记用户手动调整,scanner 重扫时不会覆盖

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

请求体 ​

歌词信息

类型: object

字段类型必填说明
lxlyricstring否
lyricstring否
lyric_remote_urlstring否
lyric_sourcestring否
rlyricstring否
tlyricstring否

响应 ​

200 - 更新成功 ​

类型: object

字段类型必填说明
file_write_statusstring否
messagestring否

400 - 请求数据错误 ​

类型: map[string]string

404 - 歌曲不存在 ​

类型: map[string]string

500 - 更新失败 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /songs/{id}/play ​

流式播放歌曲

按 song.ID 流式返回音频。内部根据 song.type 分发到本地文件 / 缓存下载 / 直链下载 / 电台 302。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

查询参数 ​

参数类型必填说明
formatstring否目标转码格式(如 mp3、ogg),用于平台兼容性转码
qualitystring否目标音质码率(128/192/320),不传或不合法值表示原始音质。指定后默认转码为 mp3(除非同时指定了 format)
trackinteger否抽取指定音频流播放(audio-relative 0-based,对应 ffmpeg -map 0🅰️N)。用于 Web 端双音轨(原唱/伴奏 mka)切轨:后端抽出单条音轨,AAC 编码时无损 remux 成 m4a、否则转 mp3。缺省/负数=不抽轨;与 media=video 互斥
prefetchstring否传 1 时异步预热缓存/转码,立即返回 202
mediastring否传 video 时按视频播放:直出原容器(忽略 format/quality 转码,避免 -vn 丢画面),并按容器真实类型返回 Content-Type(如 video/mp4)。用于应用内视频画面渲染与 DLNA 视频投屏
hlsstring否仅电台(HLS)有效。传 direct 时强制 302 直连源站、绕过本机 HLS 反代(即使 /settings/hls-proxy 已开)。原生 player 无 CORS 限制,直连可避免直播切片经反代往返后过期(404);浏览器不传此参数以继续走反代解决 CORS
normalizestring否传 1 显式开启、0 显式关闭 EBU R128 音量均衡;不传时由服务端 /settings/volume-normalize 配置决定(默认关闭)。启用后使用 ffmpeg loudnorm=I=-16:LRA=11:TP=-1.5 消除不同音源之间的响度落差。需要重编码,未同时指定 format 时默认转为 mp3。均衡产物有独立缓存(文件名带 norm. 标记);产物尚未生成时服务端边转边发一条 chunked MP3 流(无 Content-Length、不可 Range、Cache-Control 为 no-store),因此首字节不必等整首转完。media=video 忽略(-vn 会丢画面);缺 ffmpeg 时优雅降级为原始音频
radio_transcodestring否仅电台有效。传目标格式(如 mp3)时,服务端用 ffmpeg 把电台流实时转码为该格式(HLS 与裸流均适用)。用于只支持 MP3、无法解码 AAC/HE-AAC 或不支持 HLS 的音箱。缺 ffmpeg 或坏源时优雅降级为原样代理/302。与 format 分离:电台侧忽略 format,只认此参数
seeknumber否从第 N 秒起播。面向不支持 HTTP Range seek 的推流客户端(如小爱音箱经 player_play_url 只会从头拉流):服务端用 ffmpeg input seek 产出一条以第 N 秒为开头的 chunked MP3 流,因此响应无 Content-Length、不可 Range、Cache-Control 为 no-store;浏览器等支持 Range 的客户端请用 Range 而非此参数。仅本地歌曲与已缓存的网络歌曲有效(电台是直播、未缓存的网络歌曲会阻塞整首下载,均忽略);media=video 与 HEAD 忽略;缺 ffmpeg / seek 越过时长时优雅降级为从头完整播放
speednumber否播放倍速,取值夹到 [0.5, 2.0](超出该区间需要链式拼接多个 atempo,暂不支持)。服务端用 ffmpeg atempo 滤镜实时变速不变调,产出 chunked MP3 流(同 seek,无 Content-Length、不可 Range);可与 seek/normalize 组合,由同一条 ffmpeg 一起处理。仅本地歌曲与已缓存的网络歌曲有效;电台、media=video、HEAD 忽略;缺 ffmpeg 或值非法时优雅降级为原速播放

响应 ​

200 - 音频文件 ​

类型: file

202 - 预拉取已触发 ​

类型: string

302 - 电台流重定向 ​

类型: string

404 - 歌曲不存在 ​

类型: string

502 - 音源不可用 ​

类型: string

内容类型 ​

  • 响应: application/octet-stream

GET /songs/{id}/play.m3u8 ​

流式播放歌曲

按 song.ID 流式返回音频。内部根据 song.type 分发到本地文件 / 缓存下载 / 直链下载 / 电台 302。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

查询参数 ​

参数类型必填说明
formatstring否目标转码格式(如 mp3、ogg),用于平台兼容性转码
qualitystring否目标音质码率(128/192/320),不传或不合法值表示原始音质。指定后默认转码为 mp3(除非同时指定了 format)
trackinteger否抽取指定音频流播放(audio-relative 0-based,对应 ffmpeg -map 0🅰️N)。用于 Web 端双音轨(原唱/伴奏 mka)切轨:后端抽出单条音轨,AAC 编码时无损 remux 成 m4a、否则转 mp3。缺省/负数=不抽轨;与 media=video 互斥
prefetchstring否传 1 时异步预热缓存/转码,立即返回 202
mediastring否传 video 时按视频播放:直出原容器(忽略 format/quality 转码,避免 -vn 丢画面),并按容器真实类型返回 Content-Type(如 video/mp4)。用于应用内视频画面渲染与 DLNA 视频投屏
hlsstring否仅电台(HLS)有效。传 direct 时强制 302 直连源站、绕过本机 HLS 反代(即使 /settings/hls-proxy 已开)。原生 player 无 CORS 限制,直连可避免直播切片经反代往返后过期(404);浏览器不传此参数以继续走反代解决 CORS
normalizestring否传 1 显式开启、0 显式关闭 EBU R128 音量均衡;不传时由服务端 /settings/volume-normalize 配置决定(默认关闭)。启用后使用 ffmpeg loudnorm=I=-16:LRA=11:TP=-1.5 消除不同音源之间的响度落差。需要重编码,未同时指定 format 时默认转为 mp3。均衡产物有独立缓存(文件名带 norm. 标记);产物尚未生成时服务端边转边发一条 chunked MP3 流(无 Content-Length、不可 Range、Cache-Control 为 no-store),因此首字节不必等整首转完。media=video 忽略(-vn 会丢画面);缺 ffmpeg 时优雅降级为原始音频
radio_transcodestring否仅电台有效。传目标格式(如 mp3)时,服务端用 ffmpeg 把电台流实时转码为该格式(HLS 与裸流均适用)。用于只支持 MP3、无法解码 AAC/HE-AAC 或不支持 HLS 的音箱。缺 ffmpeg 或坏源时优雅降级为原样代理/302。与 format 分离:电台侧忽略 format,只认此参数
seeknumber否从第 N 秒起播。面向不支持 HTTP Range seek 的推流客户端(如小爱音箱经 player_play_url 只会从头拉流):服务端用 ffmpeg input seek 产出一条以第 N 秒为开头的 chunked MP3 流,因此响应无 Content-Length、不可 Range、Cache-Control 为 no-store;浏览器等支持 Range 的客户端请用 Range 而非此参数。仅本地歌曲与已缓存的网络歌曲有效(电台是直播、未缓存的网络歌曲会阻塞整首下载,均忽略);media=video 与 HEAD 忽略;缺 ffmpeg / seek 越过时长时优雅降级为从头完整播放
speednumber否播放倍速,取值夹到 [0.5, 2.0](超出该区间需要链式拼接多个 atempo,暂不支持)。服务端用 ffmpeg atempo 滤镜实时变速不变调,产出 chunked MP3 流(同 seek,无 Content-Length、不可 Range);可与 seek/normalize 组合,由同一条 ffmpeg 一起处理。仅本地歌曲与已缓存的网络歌曲有效;电台、media=video、HEAD 忽略;缺 ffmpeg 或值非法时优雅降级为原速播放

响应 ​

200 - 音频文件 ​

类型: file

202 - 预拉取已触发 ​

类型: string

302 - 电台流重定向 ​

类型: string

404 - 歌曲不存在 ​

类型: string

502 - 音源不可用 ​

类型: string

内容类型 ​

  • 响应: application/octet-stream

POST /songs/{id}/played ​

通知歌曲播放事件

客户端在歌曲开始播放、播放完成或被跳过时调用此端点,后端将事件广播给已订阅播放事件的 JS 插件(通过 songloft.events.onPlayEvent 注册)。source 参数标识调用来源,如 songloft-player(官方客户端)、miot(小爱音箱插件)等。type 参数标识事件类型:play(开始播放)、finish(播放完成)、skip(用户跳过)。 副作用:当 type=play 且同时传入合法的 context_type + context_key 时,额外把该歌曲写入对应播放上下文的播放历史(见 GET /play-history),同一上下文内按歌曲去重、只保留最近 50 条。仅 type=play 会落库:finish 是同一首歌的重复信息,而 skip 上报的是上一首歌、此时上下文可能已切换,会记错归属。落库失败只记日志,不影响响应码。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

查询参数 ​

参数类型必填说明
sourcestring否调用来源标识,如 songloft-player、miot
typestring否事件类型:play、finish、skip,默认 finish 可选值: play, finish, skip
context_typestring否播放上下文类型,仅 type=play 时生效:playlist、tag 或分面维度(artist/album/genre/year/decade/language/style) 可选值: playlist, tag, artist, album, genre, year, decade, language, style
context_keystring否播放上下文标识,仅 type=play 时生效:playlist 传歌单 ID,tag 传标签 ID,分面维度传该维度取值(如歌手名)

响应 ​

204 - 无内容 ​

400 - 无效的歌曲 ID 或事件类型 ​

类型: ErrorResponse

字段类型必填说明
detailstring否详细错误信息(可选) 示例: "详细错误信息"
errorstring否错误信息 示例: "操作失败"

404 - 歌曲不存在 ​

类型: ErrorResponse

字段类型必填说明
detailstring否详细错误信息(可选) 示例: "详细错误信息"
errorstring否错误信息 示例: "操作失败"

内容类型 ​

  • 响应: application/json

PUT /songs/{id}/tags ​

写入歌曲标签

将元数据写入数据库和本地音频文件标签(仅本地歌曲)。cover_data(base64) 优先于 cover_url。非空字段覆盖,空值保留原值。设置 clear_cover=true 可显式清空封面。rename_file=true 时按 "{artist} - {title}" 重命名本地音频文件(保留原目录与扩展名,artist 为空则回退为仅 title,多歌手由 artist 中的 " & " 分隔符体现;仅本地非 CUE 歌曲生效);标题清理后为空或目标文件名已存在时返回 400,与原文件同名则不移动仅写库。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲ID

请求体 ​

标签数据

类型: WriteSongTagsRequest

字段类型必填说明
albumstring否
artiststring否
clear_coverboolean否
cover_datastring否
cover_urlstring否
genrestring否
languagestring否
lyricsstring否
rename_fileboolean否RenameFile 为 true 时按新标题重命名本地音频文件(保留原目录与扩展名),仅对本地非 CUE 歌曲生效。
stylestring否
titlestring否
trackstring否
yearinteger否

响应 ​

200 - 写入结果 ​

类型: object

字段类型必填说明
file_writestring否
songSong否

400 - 请求错误 ​

类型: map[string]string

404 - 歌曲不存在 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /songs/{id}/tracks ​

枚举歌曲音频轨道

用 ffprobe 探测该歌曲文件的所有音频流,返回每条流的 index、codec、language、title。如果 ffprobe 不可用或执行失败,返回空数组而不报错。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

响应 ​

200 - 音频轨道列表 ​

类型: trackItem[]

字段类型必填说明
codecstring否
indexinteger否
languagestring否
titlestring否

数组元素结构:

字段类型必填说明
codecstring否
indexinteger否
languagestring否
titlestring否

400 - 无效的歌曲 ID ​

类型: map[string]string

404 - 歌曲不存在 ​

类型: map[string]string

内容类型 ​

  • 响应: application/json

GET /songs/{id}/video-hls/{path} ​

获取视频 HLS 子资源

返回视频 HLS 转码生成的子播放列表或 .ts 切片文件。由 hls.js 根据 master playlist 自动请求。支持多音轨场景下的子目录结构(stream_0/playlist.m3u8, stream_0/0001.ts 等)。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID
pathstring是子资源路径(如 stream_0/playlist.m3u8 或 stream_0/0001.ts)

响应 ​

200 - HLS 子资源 ​

类型: file

400 - 无效请求 ​

类型: map[string]string

404 - 资源不存在 ​

类型: map[string]string


GET /songs/{id}/video-hls/playlist.m3u8 ​

获取视频 HLS 播放列表

对浏览器不原生支持的视频格式(mpg/flv/wmv/rmvb/avi/mkv 等)实时转码为 HLS(H.264+AAC),返回 master.m3u8 播放列表。多音轨文件会生成 HLS 多音频 rendition(hls.js 原生支持切换)。首次请求会启动转码(转完再播);后续请求命中缓存。需要 ffmpeg。

需要认证

此接口需要 Bearer Token 认证

路径参数 ​

参数类型必填说明
idinteger是歌曲 ID

响应 ​

200 - HLS 播放列表内容 ​

类型: string

400 - 无效的歌曲 ID ​

类型: map[string]string

404 - 歌曲不存在 ​

类型: map[string]string

503 - ffmpeg 不可用或转码失败 ​

类型: map[string]string

内容类型 ​

  • 响应: application/vnd.apple.mpegurl

POST /songs/batch-delete ​

批量删除歌曲

根据歌曲 ID 列表批量删除歌曲。设置 delete_files=true 时同步删除本地音频文件(用于去重等场景)

需要认证

此接口需要 Bearer Token 认证

请求体 ​

批量删除请求

类型: BatchDeleteSongsRequest

字段类型必填说明
delete_filesboolean否是否同步删除本地音频文件 示例: false
idsinteger[]否要删除的歌曲 ID 列表 示例: [1]

响应 ​

200 - 删除成功 ​

类型: BatchDeleteSongsResponse

字段类型必填说明
deletedinteger否实际删除的数量 示例: 3

400 - 请求数据错误 ​

类型: map[string]string

500 - 删除失败 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

POST /songs/clean ​

清理无效的本地歌曲

清理本地歌曲中文件已不存在或位于排除目录中的记录,同时删除关联的封面文件

需要认证

此接口需要 Bearer Token 认证

响应 ​

200 - 清理成功 ​

类型: map[string]any

500 - 清理失败 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /songs/duplicates ​

获取重复歌曲组

通过音频指纹查询本地歌曲中内容相同的重复组

需要认证

此接口需要 Bearer Token 认证

响应 ​

200 - 重复歌曲组列表 ​

类型: map[string]any

内容类型 ​

  • 响应: application/json

GET /songs/facets ​

曲库标签分类聚合

按指定维度聚合曲库,返回该维度下非空取值、各自的歌曲数量及一首代表歌曲的封面 URL,用于「分类浏览」的卡片网格。 支持维度:genre(流派)/artist(歌手)/album(专辑)/language(语种)/style(风格)/year(年份)/decade(年代)/tag(标签)。 year/decade 的 value 为数字字符串(年代如 "1990" 表示 1990-1999)。取到某取值后可用 /songs?<field>=<value> 拉取该分类下歌曲(tag 维度除外——tag 的 value 为标签名,需用 /songs?tag_name=<value> 过滤)。 支持 keyword 模糊搜索取值、limit/offset 分页、sort(count|name)/order 排序;返回 total 为该维度去重取值总数。

需要认证

此接口需要 Bearer Token 认证

查询参数 ​

参数类型必填说明
fieldstring是聚合维度 可选值: genre, artist, album, language, style, year, decade, tag
keywordstring否对取值模糊搜索
limitinteger否分页大小,缺省 20,上限 100000
offsetinteger否分页偏移,缺省 0
sortstring否排序维度,缺省 count 可选值: count, name
orderstring否排序方向;count 缺省 desc,name 缺省 asc 可选值: asc, desc

响应 ​

200 - 成功返回聚合结果 {field, facets:[{value,count,cover_url}], total, limit, offset} ​

类型: map[string]any

400 - 缺少或不支持的 field ​

类型: map[string]string

500 - 服务器错误 ​

类型: map[string]string

内容类型 ​

  • 响应: application/json

GET /songs/folders ​

文件夹浏览

按目录层级浏览本地歌曲。path 为相对于 music_path 的路径(空 = 根目录),返回下一级子文件夹及其递归歌曲数和当前目录的直属歌曲。

需要认证

此接口需要 Bearer Token 认证

查询参数 ​

参数类型必填说明
pathstring否相对路径,空 = 音乐根目录
keywordstring否搜索过滤(文件夹名 / 歌曲标题)

响应 ​

200 - 成功 {path, parent_path, music_path, folders:[{name,path,song_count}], total_folders, songs:[...], total_songs} ​

类型: map[string]any

400 - 未设置音乐目录 / 非法路径 ​

类型: map[string]string

500 - 服务器错误 ​

类型: map[string]string

内容类型 ​

  • 响应: application/json

GET /songs/ids ​

获取匹配歌曲的 ID 列表

与 /songs 共享过滤条件,仅返回 ID。用于「全选当前筛选范围」场景。

需要认证

此接口需要 Bearer Token 认证

查询参数 ​

参数类型必填说明
typestring否歌曲类型
keywordstring否搜索关键词
path_prefixstring否按 file_path 前缀过滤
genrestring否按流派精确过滤
artiststring否按歌手精确过滤
albumstring否按专辑精确过滤
languagestring否按语种精确过滤
stylestring否按风格精确过滤
yearinteger否按发行年份精确过滤
decadeinteger否按年代过滤(起始年,如 1990 匹配 1990-1999)
exclude_playlist_labelsstring否排除属于这些 label 歌单的歌曲(逗号分隔), 默认 hidden; 传 none 显示全部 默认: "hidden"
sortstring否排序字段,缺省 added_at 可选值: id, title, artist, album, duration, added_at, updated_at, file_modified_at, year, genre, file_size
orderstring否排序方向,缺省 desc 可选值: asc, desc

响应 ​

200 - 成功返回 ID 列表 ​

类型: map[string]any

500 - 服务器错误 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /songs/names ​

曲库歌名/歌手名清单

一次性返回曲库中指定维度的全部去重、非空取值(按名称升序),不分页、无计数、无封面等冗余字段。 支持维度:title(歌名)/artist(歌手名)。供 TV 等第三方客户端拉取曲库名录后本地搜索匹配,替代「分页拉全部歌曲再自行去重」的浪费。 artist 按曲库原始整串返回(不按 / 、等分隔符拆分),返回的名字可直接回填 /songs?artist=<value> 精确过滤。

需要认证

此接口需要 Bearer Token 认证

查询参数 ​

参数类型必填说明
fieldstring是维度 可选值: title, artist

响应 ​

200 - 成功返回 {field, names:[...], total} ​

类型: map[string]any

400 - 缺少或不支持的 field ​

类型: map[string]string

500 - 服务器错误 ​

类型: map[string]string

内容类型 ​

  • 响应: application/json

POST /songs/organize ​

批量整理歌曲文件

批量移动/重命名本地歌曲文件到指定目录结构。target_path 为相对于 music_path 的路径(含目录和文件名),扩展名必须与原文件一致。CUE 拆分歌曲会被跳过(status=skip);目标文件已存在时拒绝覆盖(status=error)。music_path 由服务端自取。

需要认证

此接口需要 Bearer Token 认证

请求体 ​

整理项目列表

类型: OrganizeItem[]

字段类型必填说明
idinteger否
target_pathstring否

数组元素结构:

字段类型必填说明
idinteger否
target_pathstring否

响应 ​

200 - 整理结果 ​

类型: OrganizeResult[]

字段类型必填说明
errorstring否
file_pathstring否
idinteger否
statusstring否

数组元素结构:

字段类型必填说明
errorstring否
file_pathstring否
idinteger否
statusstring否

400 - 请求错误 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

POST /songs/organize/preview ​

预览批量整理歌曲文件

dry-run 预览目录整理变更,返回每项 old_path→new_path 与状态(ok/conflict/skip/error),不移动任何文件、不改数据库。target_path 为相对 music_path 的路径。CUE 歌曲 skip;目标已存在或批内撞名 conflict。music_path 由服务端自取。

需要认证

此接口需要 Bearer Token 认证

请求体 ​

整理项目列表

类型: OrganizeItem[]

字段类型必填说明
idinteger否
target_pathstring否

数组元素结构:

字段类型必填说明
idinteger否
target_pathstring否

响应 ​

200 - 预览结果 ​

类型: OrganizePreviewResult[]

字段类型必填说明
errorstring否
idinteger否
new_pathstring否
old_pathstring否
statusstring否

数组元素结构:

字段类型必填说明
errorstring否
idinteger否
new_pathstring否
old_pathstring否
statusstring否

400 - 请求错误 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

POST /songs/radio ​

批量添加电台/广播

批量添加电台/广播到数据库

需要认证

此接口需要 Bearer Token 认证

请求体 ​

电台/广播列表

类型: object[]

字段类型必填说明
cover_urlstring否
is_videoboolean否
titlestring否
urlstring否

响应 ​

201 - 添加成功 ​

类型: object

字段类型必填说明
countinteger否
songsSong[]否

400 - 请求数据错误 ​

类型: map[string]string

500 - 添加失败 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /songs/random ​

随机获取歌曲

与 /songs 共享过滤条件,随机返回 limit 首歌曲完整对象。用于「随机播放」场景。 返回字段与 GET /songs 一致(数组包裹在 songs 字段中),total 为实际返回数量。

需要认证

此接口需要 Bearer Token 认证

查询参数 ​

参数类型必填说明
typestring否歌曲类型
keywordstring否搜索关键词
path_prefixstring否按 file_path 前缀过滤
genrestring否按流派精确过滤
artiststring否按歌手精确过滤
albumstring否按专辑精确过滤
languagestring否按语种精确过滤
stylestring否按风格精确过滤
yearinteger否按发行年份精确过滤
decadeinteger否按年代过滤(起始年,如 1990 匹配 1990-1999)
exclude_playlist_labelsstring否排除属于这些 label 歌单的歌曲(逗号分隔), 默认 hidden; 传 none 显示全部 默认: "hidden"
limitinteger否随机返回数量,默认 50,上限 500 默认: 50

响应 ​

200 - 成功返回随机歌曲列表 ​

类型: map[string]any

500 - 服务器错误 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

POST /songs/refresh-metadata ​

刷新歌曲元数据

对所有元数据缺失且本地有文件的歌曲(本地歌曲及已缓存的网络歌曲)从文件提取时长、比特率、采样率、格式及标签并回填。未缓存的网络歌曲不参与,其元数据在播放缓存落盘后自动回填。已在运行时返回 409。

需要认证

此接口需要 Bearer Token 认证

响应 ​

202 - 已启动 ​

类型: map[string]string

409 - 已在运行 ​

类型: map[string]string

500 - 启动失败 ​

类型: map[string]string

内容类型 ​

  • 响应: application/json

POST /songs/refresh-metadata/cancel ​

取消元数据刷新

取消正在执行的远程歌曲元数据刷新任务

需要认证

此接口需要 Bearer Token 认证

响应 ​

204 - 已取消 ​

内容类型 ​

  • 响应: application/json

GET /songs/refresh-metadata/progress ​

获取元数据刷新进度

轮询远程歌曲元数据刷新的执行状态和进度

需要认证

此接口需要 Bearer Token 认证

响应 ​

200 - 进度信息 ​

类型: MetadataRefreshProgress

字段类型必填说明
failedinteger否
processedinteger否
statusstring否
totalinteger否

内容类型 ​

  • 响应: application/json

POST /songs/remote ​

批量添加网络歌曲

批量添加网络歌曲到数据库。cover_url 支持以 "/" 开头的相对路径(插件场景下由服务端自动解析为内部 URL,与歌词 lyric_remote_url 的解析机制一致)。lyric_remote_url 为歌词远程 URL 直传字段,提供时优先于 lyric + lyric_source=url 的间接方式。副作用:插入成功后,对缺失技术元数据(duration/bitrate/samplerate/format)的歌曲异步探测补齐(限并发后台执行,不阻塞响应),确保 WebDAV 等无法自带时长的音源在首次播放前就落库 duration,供音箱等仅依赖服务端时长的消费端自动切歌。

需要认证

此接口需要 Bearer Token 认证

请求体 ​

网络歌曲列表

类型: object[]

字段类型必填说明
albumstring否
artiststring否
cover_urlstring否
dedup_keystring否
durationnumber否
is_videoboolean否
lyricstring否
lyric_remote_urlstring否
lyric_sourcestring否
plugin_entry_pathstring否
source_datastring否
titlestring否
urlstring否

响应 ​

201 - 添加成功 ​

类型: object

字段类型必填说明
countinteger否
songsSong[]否

400 - 请求数据错误 ​

类型: map[string]string

500 - 添加失败 ​

类型: map[string]string

内容类型 ​

  • 请求: application/json
  • 响应: application/json

GET /songs/stats ​

获取曲库汇总统计

返回曲库汇总信息,包括歌曲总数、各类型数量、总时长、总文件大小、歌手/专辑/流派数等

需要认证

此接口需要 Bearer Token 认证

响应 ​

200 - 曲库汇总统计 ​

类型: database.LibraryStats

字段类型必填说明
album_countinteger否
artist_countinteger否
genre_countinteger否
local_songsinteger否
radio_songsinteger否
remote_songsinteger否
total_durationnumber否
total_file_sizeinteger否
total_songsinteger否

500 - 服务器错误 ​

类型: map[string]string

内容类型 ​

  • 响应: application/json