mcpField
A
auto-dubbing

auto-dubbing

github.com/sonilo-ai创意与媒体1171.1k 次安装1 天前更新
代码仓库

关于 auto-dubbing

Sonilo 的视频配音技能,可将视频翻译并配成一种或多种指定语言,每种语言生成一个 MP4。也可使用已有的目标语言字幕作为配音台词,并选择导出重新校准时间的字幕。

主要功能

  1. 01按指定语言生成配音视频
  2. 02使用自备字幕作为配音台词
  3. 03可选背景音乐闪避与唇形同步
  4. 04可导出重新校准时间的 SRT

适用场景

  1. 01为产品演示制作多语言版本
  2. 02用已审核的翻译脚本制作配音
  3. 03为旁白或录屏视频替换语音

MCP 相关

Sonilo MCP 工具 `dubbing` 接收视频、目标语言及可选字幕等参数,并为每种语言输出配音视频。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sonilo-ai/skills --skill auto-dubbing

安装后在 Claude Code 中输入/auto-dubbing确认已加载。

详细介绍

Sonilo 配音

将视频配成一种或多种其他语言:语音会经过翻译并重新配音,为每种目标语言生成一个新的 .mp4(而不只是音轨或字幕)。如果用户已有获批的译文,请将其作为 subtitles 传入,配音时会直接朗读这些台词,而不是翻译源内容。

设置: 请参阅 setup-api-key 技能。

⚠️ 费用——调用前请阅读: 费用按语言计收。唯一免费的运行是 15 秒预览:自助服务账户首次调用时,若只指定一种语言且不提供 subtitles,系统只会免费翻译视频的前 15 秒,结果中会包含 trial_preview,并显示整个视频的预估费用。此后的所有调用——以及指定多种语言或脚本的任何调用——都会收费。请求四种语言的费用是一种语言的四倍。调用前请与用户确认确切的语言列表;不要为了“提供帮助”而猜测一长串语言。

⏱ 此调用耗时较长。 无论 TIME_OUT_SECONDS 设置得多短,内部轮询都会持续至少两小时——这是配音流水线后端自身的上限。调用运行一小时甚至更久都属正常,并非卡住。不要取消:任务会继续运行并照常计费,取消只会让你无法轻松获取结果(请改用 get_sfx_task,或在托管服务器上使用 get_generation_task 来恢复任务)。

传输方式:MCP 或 CLI

请在会话开始时选择一种,并始终使用该方式。不要在同一任务中混用两种方式,也不要告知用户你的选择。

  1. 本会话中可见 Sonilo MCP 工具(dubbing 等)——使用这些工具。这是首选方式:无需 shell,而且是唯一能承受超长生成时间的方式。如果调用因身份验证失败(而非输入问题)而失败,说明本会话无法使用此传输方式:请改用第 2 种方式,不要重试。
  2. 没有可用的 Sonilo MCP 工具,但 sonilo account 退出码为 0——使用下方的 CLI 命令。API、账户和凭据文件都相同。请用 sonilo account 进行探测,不要用 sonilo whoami:即使未登录,whoami 也会以 0 退出,因此无法区分这两种状态。
  3. 两者都不满足——停止并运行 setup-api-key 技能。不要用 curl 调用 api.sonilo.com 绕过;两种传输方式都会处理上传、轮询和重试,而直接请求不具备这些功能。

⏱ 使用 CLI 时,此调用无法通过一条命令完成。 后端轮询最长可达两小时,而主机的 shell 工具时限远低于此(在 Claude Code 中为十分钟),因此在前台运行 sonilo dubbing 会在任务仍运行且已产生费用时被终止。请分开提交任务并轮询:

# --timeout 是 CLI 自身的等待时间,而不是任务时限:此命令会在主机
# shell 终止进程前返回。id 来自“Submitted task ...”这一行。
sonilo dubbing --video-url https://example.com/clip.mp4 --languages es,fr --timeout 300
sonilo tasks wait <task-id>   # 重复执行,直至任务完成

MCP 方式没有此限制,是配音任务更好的传输方式。

快速开始

MCP 工具调用(推荐)
dubbing(
    video_path="~/Desktop/product-demo.mp4",
    languages=["es", "fr"]
)

使用用户提供的脚本,并为每种语言返回重新调整时间的 .srt:

dubbing(
    video_path="~/Desktop/product-demo.mp4",
    languages=["es", "fr"],
    subtitles={"es": "~/Desktop/demo.es.srt", "fr": "~/Desktop/demo.fr.srt"},
    export_srt=True
)

在托管服务器上,每个字幕值都必须是 https:// URL——该服务器没有文件系统,无法读取路径,且 video_url 同样是其唯一的视频来源。本地视频或 .srt/.vtt 文件可通过托管服务器的 create_upload_url 工具获取此类 URL(步骤见 预检,第 4 步)。本地 sonilo-mcp 服务器则接受本地 .srt/.vtt 路径或 https URL。

Python(pip install sonilo)
from sonilo import Sonilo

with Sonilo() as client:  # reads SONILO_API_KEY
    result = client.dubbing.generate(
        video="product-demo.mp4",
        languages=["es", "fr"],
        # Optional: the lines to speak in each target language. A value is
        # either a local .srt/.vtt path or an https URL.
        subtitles={"es": "demo.es.srt", "fr": "demo.fr.srt"},
        export_srt=True,
        timeout=7200,  # seconds — matches the backend's own ~2h ceiling
    )
    for language, path in result.save_all("./dubbed").items():
        print(language, path)
    # Only present with export_srt. Iterate this map, not the videos: a
    # language whose export was blocked still has its .mp4.
    for language, path in result.save_all_subtitles("./dubbed").items():
        print(language, path)
JavaScript / TypeScript(npm install sonilo)
import { SoniloClient } from "sonilo";
import type { DubbingResult } from "sonilo";

const client = new SoniloClient(); // reads SONILO_API_KEY

const result = await client.dubbing.generate(
  {
    video: "./product-demo.mp4",
    languages: ["es", "fr"],
    // Optional: a local .srt/.vtt path, an https URL, or a File in a browser.
    subtitles: { es: "./demo.es.srt", fr: "https://example.com/demo.fr.vtt" },
    exportSrt: true,
  },
  { timeout: 7_200_000 }, // milliseconds — matches the backend's own ~2h ceiling
);
for (const [language, url] of Object.entries((result as DubbingResult).outputs ?? {})) {
  console.log(language, url);
}
// Only present with exportSrt, and a language whose export was blocked is absent.
for (const [language, url] of Object.entries((result as DubbingResult).subtitles ?? {})) {
  console.log(language, url);
}
CLI(npm install -g sonilo-cli 或 pip install sonilo-cli)
sonilo dubbing --video-url https://example.com/product-demo.mp4 --languages es,fr --output dubbed.mp4
# writes dubbed.es.mp4 and dubbed.fr.mp4

# With the user's own scripts. --subtitle is repeatable, once per language, and
# its value is a local .srt/.vtt path or an https URL.
sonilo dubbing --video-url https://example.com/product-demo.mp4 --languages es,fr --subtitle es=demo.es.srt --subtitle fr=demo.fr.srt --export-srt --output dubbed.mp4
# also writes dubbed.es.srt and dubbed.fr.srt beside the videos, so --output may not end in .srt

--timeout 已默认设为 7200 秒,与后端的上限一致。在普通终端中这样即可;在 Agent 宿主 Shell 中,请使用上文较短的提交并轮询模式,以免 Shell 工具终止前台命令。

cURL(原始 REST API,无 MCP 宿主)
curl -X POST "https://api.sonilo.com/v1/dubbing" \
  -H "Authorization: Bearer $SONILO_API_KEY" \
  -F "[email protected]" \
  -F 'languages=["es","fr"]' \
  -F "subtitles[es][email protected]" \
  -F "subtitles[fr]=https://example.com/demo.fr.vtt" \
  -F "export_srt=true"
# -> {"task_id": "...", "subtitle_preflight": {...}}
#    poll GET /v1/tasks/{task_id} — can take up to ~2 hours

也可以使用 video_url 代替上传文件,但必须是 https——配音流水线会自行获取源文件,并拒绝普通 http。

每种语言使用一个 subtitles[<language>] 字段,每个字段的值可以是上传的 .srt/.vtt 部分,也可以是 https URL 字符串。方括号键为必填项:裸键 subtitles、重复的键或代码不完全匹配的键(subtitles[zh-CN]——代码使用下划线,即 zh_cn)都会被拒绝,不会被静默忽略。

工具

工具描述
dubbing(video_path? | video_url?, languages?, ducking?, lipsync?, subtitles?, export_srt?, output_directory?)为每种指定语言给视频配音;每种语言保存一个 .mp4,设置 export_srt 后还会为每种语言保存一个 .srt。

参数

参数类型默认值说明
video_pathstring—.mp4/.mov/.webm/.m4v/.gif(gif 必须是动画)。最长 300s(5 分钟),同时受账户上传大小上限限制。
video_urlstring—必须是 https(不能只是 http)。video_path/video_url 必须且只能提供一个。
languageslist[str]["zh_cn", "es", "fr"]目标语言代码。支持:en、zh_cn、ja、ko、pt、pt_br、es、es_419、de、fr、it、ru、th、ar、tr、vi、id、ta、ml、kn、gu、pa_in、sd_in、hi。pt_br 是巴西葡萄牙语,es_419 是拉丁美洲西班牙语;普通的 pt/es 未指定地区,因此在地区有影响时,请询问用户需要哪种。ar 是未指定地区的阿拉伯语,而非某个国家的方言,因此无需询问。pa_in 和 sd_in 分别是印度使用的旁遮普语和信德语——这是仅有的变体;如果用户的受众位于巴基斯坦,请说明这两种语言在当地都使用另一种文字书写。hi 是印地语。省略此参数仍会配成 3 种语言,并按 3 种语言计费——如果用户只需要一种,请传入只包含一个元素的列表。
duckingbool关闭配音人声说话时,降低背景音乐/音效的音量。默认关闭:背景音轨始终保留,音量保持不变。无论是否开启,均不额外收费。
lipsyncbooltrue是否重新渲染说话者的嘴部,使其与配音同步。设为 false 可完全保留原画面——视频将以原始分辨率和帧率返回,而不进行重新渲染;只替换音频,因此嘴部仍会按照原语言活动。当画面中没有出镜说话者(屏幕录制、B-roll、旁白),或保留原始画面的精确效果比匹配唇动更重要时,建议使用此选项。无论是否开启,价格相同。
subtitlesdict[str, str]—每种目标语言提供一份台词稿,例如 {"es": "demo.es.srt"}。每个值可以是本地 .srt/.vtt 路径或 https URL(托管的 MCP 服务仅接受 URL)。这些是目标语言的台词稿,包含要说出的台词,而非源语言转录稿——配音会逐字照读,不会进行翻译。键集合必须与 languages 完全一致。请参阅下方规则;任何一条不符合都会在收费前返回 422。
export_srtboolfalse通过强制对齐,为每种语言返回根据交付音频重新调整时间轴的台词,并保持原文不变。需要提供 subtitles——单独传入此参数会返回 422。
output_directorystringSONILO_MCP_BASE_PATH绝对路径,或相对于基础路径的路径。

自带脚本

如果用户已有获批的译文,并希望逐字朗读,请使用 subtitles。如果用户想在朗读前审核或更正译文,但还没有脚本,请先运行 proofread 技能——它会为每种语言返回一个可编辑的 .srt 文件;更正后的文件正是 subtitles 所需的文件(但需去掉源语言文件,因为这里多了一个键)。以下每条规则都会在扣费前检查,因此违反规则会返回 422,不会扣款——但也会让用户多一次往返,而且前两条很容易弄错:

  • 涵盖所有语言,且仅限这些语言。 键集合必须与 languages 完全一致;缺少或多出代码都会被拒绝,并在错误中指出。如果用户提供了三种语言中两种的脚本,请向用户索要第三种,而不要将其省略——还要记住,完全省略 languages 仍表示三种语言(zh_cn、es、fr),因此三种语言都需要脚本。
  • 脚本必须使用目标语言,而不是源语言的转录文本。 将原始英文台词文件放在 "es" 下提交,看起来是有效脚本,却会生成说英语的西班牙语配音。检查会读取文本,并拒绝语言与提交时指定的语言不一致的脚本,但发送前仍要先查看用户提供的内容。
  • 仅限 .srt 或 .vtt,扩展名必须为小写,每个文件最大 1 MiB。其他格式都会被拒绝。
  • export_srt 需要 subtitles。 没有脚本就无法对齐音频,因此单独使用时会返回 422。
  • 导出受阻不会导致任务失败。 配音视频仍会交付并扣费;只是该语言没有 .srt。应将其报告为缺少的附加文件,切勿说成配音失败,也不要为此重新运行任务。
  • 202 会携带 subtitle_preflight——即检查对每个脚本的评估结果;任务完成后也会在 subtitle_export 旁重复提供此信息(每种语言的 status、alignment_loss、issues)。流水线会将这些数值按记录时的任意类型存储为 JSON,因此计数或损失值可能以字符串而非数字的形式返回;展示时不要假定其类型。

工作流提示

  • 如果用户没有说明,请务必询问使用哪些语言,不要依赖 ["zh_cn", "es", "fr"] 默认值——这个默认值会在用户不知情的情况下按三种语言计费。
  • 如果画面中无人说话,可考虑设置 lipsync=false。 屏幕录制、补充镜头和画外音都没有需要匹配的嘴型;对它们进行口型同步只会重新渲染画面,没有任何好处——系统会直接返回未经改动的原始帧,并保留其原始分辨率和帧率。除非用户提出要求,否则不要对访谈类视频关闭该选项:画面中的人物会明显继续说原语言。
  • 用户有脚本时,请向其索取。 如果用户提到已批准的文案、现有本地化版本,或希望逐字照读的译文,那就是 subtitles——流水线自身的翻译会覆盖它。不要自行编写脚本:你写的脚本是用户从未批准过的译文,却会在他们的视频中被说出来。
  • 这不是音乐或音效工具(text-to-music、video-to-music、text-to-sfx、video-to-sfx)。它完全不会处理音乐或音效——只会翻译现有语音并为其重新配音。
  • 请说明所需时间。 提前告知用户,这可能需要约 2 小时,并且可以放心离开——之后仍可取回结果。
  • 免费运行是预览,不是完整视频。 自助账户可免费进行一次单语言调用,且只会翻译前 15 秒。结果包含 trial_preview 时,请明确告知用户:片段是其视频的前 15 秒,full_video_cost_usd 是完整视频的费用——不要把片段说成完整译文。免费运行次数用尽后,没有付款方式的账户会返回 trial_exhausted;如果不确定,请先检查 get_account_services(参见账户),并在调用前提醒用户。

从超时调用中恢复

如果调用自身的长轮询被中断(例如主机本身超时或会话关闭),错误消息或提交时打印到 stderr 的任务 ID 会提供一个 task_id。调用 get_sfx_task(task_id)——在托管服务上则调用 get_generation_task(task_id)——即可检查状态,并在文件就绪后下载;参见 task-recovery。

输出文件

每种请求的语言会生成一个 .mp4 文件,文件名为 dubbing-<first 8 chars of the task id>.<language>.mp4——没有可用于命名文件的提示词,因此所有配音输出都会使用基于任务 ID 的名称。

使用 export_srt 时,每个视频旁边都会生成一个 .srt 文件,文件名使用相同的前缀—— dubbing-<first 8 chars of the task id>.<language>.srt——其中包含该 语言对应的字幕行,并根据交付的音频重新调整时间轴。导出受阻的语言会有视频,但没有 .srt;系统会将此情况作为备注报告,而不是错误。在 CLI 中,SRT 文件与视频一样,跟在 --output 后面(--output dubbed.mp4 会生成 dubbed.es.mp4 和 dubbed.es.srt),因此 --output 本身不能以 .srt 结尾。

免费预览

如果本次运行是账户的免费 15 秒预览,那么任务在所有状态下都会包含 trial_preview:

"trial_preview": {
  "preview_seconds": 15,
  "source_duration_seconds": 60.0,
  "trimmed": true,
  "languages": 1,
  "full_video_cost_usd": 3.49,
  "message": "Free preview: the first 15 seconds of your 60-second video, in 1 language. Translating the full video costs $3.49 — add funds at https://platform.sonilo.com/dashboard/billing"
}

此时 duration_seconds 为 15,而不是源视频的时长;交付的 .mp4 也是前 15 秒。MCP 工具和两个 CLI 都会将 message 与其他状态行一同打印;SDK 会将其作为 DubbingResult.trial_preview 提供。请将此信息转告用户,并提供完整运行的选项 (充值后再次调用——该次运行会计费),不要把片段当作完整视频。

错误处理

常见错误:401 密钥无效,402 余额不足(配音没有可耗尽的试用额度——会立即计费),413 文件过大,422 参数无效或语言代码不受支持(会在扣费前拒绝),429 速率限制。请参阅账户技能。

422 错误中的 code: SUBTITLE_PREFLIGHT_BLOCKED 表示提交的脚本本身未通过检查。消息会列出受阻的语言及其问题代码,details 中包含各语言的报告。此时不会扣费——请修正或替换该脚本后重新提交;不要移除 subtitles 后仍然运行任务,否则系统会在不提示的情况下交付流水线自行翻译的内容,而不是用户批准的台词。

评论

支持 Markdown