Such Music

suchmusic 宿主 API 参考

插件调用宿主能力的全部 API 详解

suchmusic 宿主 API 参考

插件通过全局对象 suchmusic 调用宿主提供的能力。所有 API 调用前需确保已在 permissions 中声明对应权限,否则调用将抛出权限错误。

API 总览

API所需权限敏感操作说明
execProgram(path, args)local_program调用本地可执行程序
execTerminal(command)local_program执行终端命令
fileOp(operation, ...args)file_system本地文件读写操作
fetch(url, options?)fetchHTTP 网络请求
downloadFile(url, destPath)fetch + file_system下载文件到本地
writeMeta(filePath, tags)file_system写入音乐文件元数据
getSetting(key)app_info读取 Such 应用设置
createPlaylist(name, tracks)playlist创建歌单
addToPlaylist(id, tracks)playlist向歌单添加歌曲
updatePlaylistSettings(id, settings)playlist更新歌单设置
listPlaylists()playlist列出所有歌单

⚠️ 标记为「敏感操作」的 API 每次调用都会弹出用户确认窗口,详见 安全模型


本地程序调用

execProgram(path, args)

调用用户本地的可执行文件,传入参数数组。

suchmusic.execProgram(programPath: string, args: string[]): Promise<{ code: number; stdout: string; stderr: string }>

参数:

参数类型说明
programPathstring可执行文件的绝对路径
argsstring[]命令行参数数组

返回值:

字段类型说明
codenumber退出码,0 表示成功
stdoutstring标准输出
stderrstring标准错误输出

ℹ️ 无论程序执行成功与否,Promise 都会 resolve(不会 reject)。需检查 code 判断执行结果。

示例:

async function checkDecryptor(path: string) {
  const result = await suchmusic.execProgram(path, ['--version'])
  if (result.code === 0) {
    console.log('版本:', result.stdout.trim())
  } else {
    console.error('执行失败:', result.stderr)
  }
}

execTerminal(command)

执行任意终端命令,返回标准输出。执行超时 60 秒。

suchmusic.execTerminal(command: string): Promise<string>

参数:

参数类型说明
commandstring完整的 Shell 命令字符串

返回值: Promise<string> — 标准输出内容。执行失败时 Promise reject。

示例:

async function getFileInfo(filePath: string) {
  try {
    const output = await suchmusic.execTerminal(
      `ffprobe -v quiet -print_format json -show_format "${filePath}"`
    )
    const info = JSON.parse(output)
    console.log('文件信息:', info.format)
  } catch (err) {
    console.error('获取文件信息失败:', err.message)
  }
}

文件操作

fileOp(operation, ...args)

对本地文件系统进行读写操作。

suchmusic.fileOp(operation: string, ...args: string[]): Promise<any>

支持的 operation:

operation参数返回值说明
read(filePath)string读取文件内容(UTF-8)
write(filePath, content)true写入内容到文件
copy(srcPath, destPath)true复制文件
delete(filePath)true删除文件
exists(filePath)boolean文件是否存在
listDir(dirPath)string[]列出目录下的文件名

示例:

async function isAlreadyProcessed(filePath: string) {
  const exists = await suchmusic.fileOp('exists', filePath)
  return exists
}

async function readConfig(configPath: string) {
  const content = await suchmusic.fileOp('read', configPath)
  return JSON.parse(content)
}

async function listMusicFiles(dirPath: string) {
  const files = await suchmusic.fileOp('listDir', dirPath)
  return files.filter(f => f.endsWith('.mp3') || f.endsWith('.flac'))
}

writeMeta(filePath, tags)

写入音乐文件的元数据标签(标题、艺术家、专辑、封面等)。

suchmusic.writeMeta(filePath: string, tags: Record<string, any>): Promise<boolean>

参数:

参数类型说明
filePathstring音乐文件路径
tagsobject元数据标签对象

常用 tags 字段:

字段类型说明
titlestring歌曲标题
artiststring艺术家
albumstring专辑名
coverstring | Buffer封面图片(路径或 Buffer)

示例:

async function tagMusicFile(filePath: string) {
  const success = await suchmusic.writeMeta(filePath, {
    title: '歌曲标题',
    artist: '艺术家名称',
    album: '专辑名称'
  })
  if (success) {
    console.log('元数据写入成功')
  }
}

网络请求

fetch(url, options?)

发起 HTTP 请求,与标准 fetch API 行为一致。

suchmusic.fetch(url: string, options?: RequestInit): Promise<Response>

示例:

async function checkServerVersion() {
  const response = await suchmusic.fetch('https://api.example.com/plugin/version')
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`)
  }
  const data = await response.json()
  return data.version
}

async function fetchWithCookie(url: string, cookie: string) {
  const response = await suchmusic.fetch(url, {
    headers: { 'Cookie': cookie }
  })
  return response.json()
}

downloadFile(url, destPath)

下载远程文件并保存到本地路径。需要同时声明 fetchfile_system 权限。

suchmusic.downloadFile(url: string, destPath: string): Promise<{ success: boolean; filePath: string }>

参数:

参数类型说明
urlstring文件下载地址
destPathstring本地保存路径(包含文件名)

返回值:

字段类型说明
successboolean是否下载成功
filePathstring保存的文件路径

示例:

async function downloadDecryptor() {
  const musicFolder = suchmusic.getSetting('musicFolder')
  const destPath = musicFolder + '\\ncmdump-go.exe'

  const result = await suchmusic.downloadFile(
    'https://github.com/example/ncmdump-go/releases/latest/download/ncmdump-go.exe',
    destPath
  )

  if (result.success) {
    window.notify('下载完成: ' + result.filePath, 'success')
  }
}

应用设置

getSetting(key)

读取 Such Music 的全局配置。

suchmusic.getSetting(key: string): any

支持的 key:

Key返回类型说明
musicFolderstring音乐文件夹路径,如 C:\Users\xxx\Music\Such
themestring当前主题:dark / light / system

示例:

async function getMusicFolder() {
  const folder = suchmusic.getSetting('musicFolder')
  console.log('音乐文件夹:', folder)
  return folder
}

initialization() {
  const musicFolder = suchmusic.getSetting('musicFolder')
  this.setProps({ musicFolder })
}

⚠️ getSetting 是同步方法,直接返回结果,不需要 await


歌单操作

createPlaylist(name, tracks?)

创建新的歌单。

suchmusic.createPlaylist(name: string, tracks?: PlaylistTrack[]): Promise<{ id: string; name: string }>

参数:

参数类型说明
namestring歌单名称
tracksPlaylistTrack[]初始曲目列表(可选)

PlaylistTrack 类型:

interface PlaylistTrack {
  id?: string | number | null
  title: string
  artist: string
  album?: string
  cover?: string
  filePath?: string
  durationMs?: number
  source?: string
  sourceSongId?: string | number
}

示例:

async function importPlaylist(name: string, songList: any[]) {
  const tracks = songList.map(song => ({
    title: song.title,
    artist: song.artist,
    album: song.album,
    cover: song.coverUrl,
    filePath: song.localPath,
    durationMs: song.duration,
    source: 'custom',
    sourceSongId: String(song.id)
  }))

  const result = await suchmusic.createPlaylist(name, tracks)
  window.notify(`歌单 "${name}" 创建成功`, 'success')
  return result
}

addToPlaylist(playlistId, tracks)

向现有歌单添加歌曲。

suchmusic.addToPlaylist(playlistId: string, tracks: PlaylistTrack[]): Promise<any>

updatePlaylistSettings(playlistId, settings)

更新歌单设置(名称、描述等)。

suchmusic.updatePlaylistSettings(playlistId: string, settings: Record<string, any>): Promise<any>

listPlaylists()

列出所有歌单。

suchmusic.listPlaylists(): Promise<Playlist[]>

示例:

async function findPlaylistByName(name: string) {
  const playlists = await suchmusic.listPlaylists()
  return playlists.find(p => p.name === name)
}

On this page