TikTok 视频音乐 ID 怎么获取?从视频详情查询原声信息

发布于 2026年10月20日

两条记录就能暴露一个入库错误:视频 7697307919943060767 时长为 9500 毫秒;它关联的原声 7697308007327730462 时长为 9 秒,user_count=30。如果把视频编号直接填进音乐查询,后面的标题、作者和计数就失去了对应关系。这些是 2026-10-21 采集时的观察值,不代表此刻仍可访问或数值不变。

同一个视频对应两个 ID:视频编号不是音乐编号

video-data 接收 video_id,music-data 接收 music_id。前者指向一条视频,后者指向一条音乐或原声记录;不是两个名字描述同一个主键,也不能根据两串数字的前缀推导关系。应从视频返回内容取得关联编号,再查询声音对象。

账号标识也不能混用:username 是用户名,user_id 是数字用户编号,sec_user_id 是另一类用户标识,三者都不是音乐 ID。只有用户名时可用 user-data-by-username 查公开账号,不要把显示昵称当成用户名搜索。本例从已知视频开始,不需要先查账号。

先保留字符串,避免 JavaScript 丢失长数字 ID 精度

两个样本编号都超过 Number.MAX_SAFE_INTEGER。输入、数据库关联字段及输出一律保存字符串,不做加减或数字排序。尤其不能先 response.json() 再 String(id):若响应把 ID 写成无引号整数,精度可能在解析时已经丢失。

下面的服务端 JavaScript 模板用 JSON.parse 的 context.source 保留超出安全范围的整数原文,并先自检运行时支持;旧运行时应换用无损 JSON 解析器,而不是删掉检查。查询参数中的平台密钥从环境变量读取,可从控制台取得;不要放进浏览器脚本、完整请求 URL 日志或公开仓库。打开页面、复制代码不会发起请求,只有主动运行客户端才会查询。

从视频的音乐对象取 ID,再查询原声详情

已观察到 data.aweme_detail,但现有字段说明没有确认其中音乐编号的确切属性名。因此模板不能直接照抄运行:先用你有权查询的视频核验返回的音乐对象,把编号相对 aweme_detail 的属性路径配置为 VIDEO_MUSIC_ID_PATH,同时设置 VIDEO_ID 和 OPENDATA_API_KEY。不要猜成 music.id,也不要用上面的样本音乐编号替代实际关联字段。

const required = (name) => {
  const value = process.env[name];
  if (!value) throw new Error(`Missing ${name}`);
  return value;
};
const key = required("OPENDATA_API_KEY");
const videoId = required("VIDEO_ID");
const musicIdPath = required("VIDEO_MUSIC_ID_PATH");

function preserveIntegers(_key, value, context) {
  if (typeof value === "number" && !Number.isSafeInteger(value)
      && /^-?\d+$/.test(context?.source ?? "")) {
    return context.source;
  }
  return value;
}
if (JSON.parse("7697308007327730462", preserveIntegers)
    !== "7697308007327730462") {
  throw new Error("Use a runtime with JSON.parse context.source support");
}

async function lookup(operationId, params) {
  const url = new URL(
    `https://api.opendata-api.com/api/project/tiktok/${operationId}`
  );
  url.search = new URLSearchParams({ ...params, key }).toString();
  const response = await fetch(url);
  const envelope = JSON.parse(await response.text(), preserveIntegers);
  if (!response.ok || envelope.code !== 200) {
    throw new Error("HTTP or gateway failure");
  }
  const result = envelope.data;
  if (result?.status !== "ok" || result?.data?.status_code !== 0) {
    throw new Error("Business result is not usable");
  }
  return result.data;
}

const video = await lookup("video-data", { video_id: videoId });
const detail = video.aweme_detail;
if (detail?.aweme_id !== videoId) throw new Error("Video identity mismatch");
const musicId = musicIdPath.split(".").reduce((obj, field) => obj?.[field], detail);
if (typeof musicId !== "string" || !/^\d+$/.test(musicId)) {
  throw new Error("Verify the sound identifier field before continuing");
}
const sound = (await lookup("music-data", { music_id: musicId })).music_info;
if (sound?.id_str !== musicId) throw new Error("Sound identity mismatch");
console.log({
  videoId, musicId, title: sound.title, ownerHandle: sound.owner_handle,
  durationSeconds: sound.duration, reportedUsage: sound.user_count,
  fetchedAt: new Date().toISOString()
});

这里分开检查 HTTP、平台 code 和业务 status/status_code,任一失败就停止交接,不能因为 HTTP 200 就继续读取字段。音乐结果用 music_info.id_str 核对身份;标题和 owner_handle 分别回答“叫什么”“归属哪个账号”,返回的 author 也可保存,但账号归属不等于词曲版权归属。字段缺失应保留缺失状态,不补造标题或作者。

如需类似应用的数据接口,可通过联系页面提出需求,平台也支持源码私有化部署。

9500 毫秒的视频与 9 秒原声如何对齐

样本视频时长换算后是 9.5 秒,原声详情的 duration=9 已经是秒。入库时分别命名为 video_duration_ms 和 sound_duration_seconds,展示时才统一单位;这两个名字是业务库字段,不是已确认的视频响应路径。

相差半秒不能证明关联错误,也不能据此推断裁切位置、循环次数或静音片段。先核对 ID,再保留各自精度;不要把原声的整数秒乘以一千后,要求它与视频毫秒数完全相等。实际使用的是哪一段声音,不能只靠这两个时长还原。

user_count=30 不等于视频播放量或触达人数

user_count 是声音记录报告的使用相关计数,不是视频播放次数、独立听众或去重触达。素材分析表应把它与视频互动指标分列,连同 fetchedAt 保存;数值增加也不能直接解释为新增购买者或营销带来的增长。

同样,评论总数不等于本页评论条数。评论接口可能只返回部分样本,reply_comment_total 不代表回复正文已返回,现有证据也未确认总数是否包含未返回的回复。comments=null、has_more=0 只能说明本次没有可继续获取的评论,不能据此断言视频不存在。

边界要写清:歌曲识别、同款视频覆盖与音频使用权

original sound - khaby.lame 是观察到的原声标题,不是正式发行曲目的认证结果。本链路没有音频指纹匹配,不能由标题确定歌名、发行版本、词曲作者或版权方。

若要继续找同款视频,可把核对过的 music_id 交给 music-feed。首请求不传可选 max_cursor;该接口的列表结构、续页字段和终止规则尚无已核验样本,不能承诺完整覆盖,也不能要求返回条数等于 user_count。如果起点是用户作品列表,首次同样省略 max_cursor/min_cursor;续页组合与方向须另行验证,按视频 ID 去重、遇重复检查点停止,不能照搬到音乐列表。

话题视频是另一条关联:按 challenge_name 查询,取返回的 cid 作为 challenge_id 再查话题视频,并非拿音乐 ID 搜话题。按地区取得的热门视频也只是该地区上下文中的样本,不等于当地完整热榜,更不代表观众居住地。

最后,即使详情含有 play_url,也只说明提供了播放地址,不保证长期有效,更不授予下载、剪辑、广告投放或商用授权。公开可见不等于可任意采集和再利用;应用仍需遵守平台条款、隐私要求与内容权利。让“视频关联哪条原声”停在可证实的身份关系上,不把它扩写成歌曲识别、全量传播追踪或音频授权证明。