Gtt format and translate
Skill inceptiongt/format-and-translate-subtitle/skills/gtt-format-and-translate
npx -y skills add inceptiongt/format-and-translate-subtitle --skill gtt-format-and-translateAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
将 YouTube 英文字幕转换为双语字幕(中文+英文),核心功能:英文片段的组合、重新断句、计算时间戳;翻译,通过 baoyu-skill 精译;中英文语义对齐、长句拆分、长度控制利于显示。 Convert YouTube English subtitles into bilingual subtitles (Chinese + English). Core features: combining English segments, re-phrasing, and calculating timestamps; translation using the baoyu-skill for high-quality results; semantic alignment between Chinese and English, splitting long sentences, and length control for optimal display.
SKILL.md
15.8 KB, as published. Nobody here has run it
format-and-translate
将 YouTube 英文字幕转换为双语字幕(中文+英文),核心是 7 步工作流。 输入为 en.json3、info.json(可选) 文件,可通过 yt-dlp 下载;输出为字幕的 srt 和 json。
用法
/format-and-translate <en_json3_path> [info_json_path] [--steps 1-7] [--output-dir <dir>]
参数说明:
en_json3_path:YouTube json3 格式的英文字幕文件路径(必填)info_json_path:包含 chapters 信息的 JSON 文件路径(可选,无则跳过章节标题)--steps:指定执行哪些步骤,格式1-7(默认全部)。可指定范围如3-7,或单步如5--output-dir:中间文件输出目录(默认为<en_json3_dir>/Subtitle)
示例:
/format-and-translate example/video.en.json3 example/video.info.json
/format-and-translate example/video.en.json3 --steps 5-7
/format-and-translate /absolute/path/to/video.en.json3 --output-dir /tmp/output/
Script Directory
Scripts in scripts/ subdirectory. {baseDir} = this SKILL.md's directory path. Resolve ${BUN_X} runtime: if bun installed → bun; if npx available → npx -y bun; else suggest installing bun. Replace {baseDir} and ${BUN_X} with actual values.
执行前准备
- 解析
$ARGUMENTS,提取en_json3_path、info_json_path(可能为空)、--steps范围、--output-dir - 将
en_json3_path转为绝对路径;提取其所在目录en_json3_dir - 若未指定
--output-dir,则:output_dir = <en_json3_dir>/Subtitle - 验证
en_json3_path文件存在 - 若未提供
info_json_path,则在en_json3_dir下寻找对应的info.json:从en_json3_path文件名去掉.en.json3后缀,加上.info.json(例如video.en.json3->video.info.json);若文件存在则使用,否则设为空字符串"" - 确认
bun可用:bun --version - 创建 output 目录:
mkdir -p <output_dir> - 告知用户将执行哪些步骤
步骤范围解析规则:
--steps 1-7(默认):执行所有步骤--steps 3-7:从第 3 步开始--steps 5:仅执行第 5 步- 若 output 目录中已有某步骤的输出文件,且用户未明确指定该步骤,可跳过并提示
Workflow
Step 1: 整理输入的 json3 文件 (Code)
输入、输出:en.json3 -> 1.en.indexed.md + 1.en.indexed.json
执行方式(Code):
${BUN_X} {baseDir}/scripts/step1.ts <en_json3_path> <output_dir>
Step 2: 英文断句 (LLM + Code)
输入、输出:1.en.indexed.md -> 2.en.indexed.flag.md -> 2.en.indexed.flag.full.md
执行方式:
-
读取提示词:
{baseDir}/prompts/step2_segmentation.md -
使用
{baseDir}/scripts/chunk.ts对<output_dir>/1.en.indexed.md进行分块(max-words 3000),输出到<output_dir>/step2_chunks/:${BUN_X} {baseDir}/scripts/chunk.ts <output_dir>/1.en.indexed.md --max-words 3000 --output-dir <output_dir>/step2_chunks -
对每个 chunk,按提示词处理:根据句意确定
[end]边界位置;对每个 chunk 并行启动子 agent(subagent),每个 agent:- 读取提示词
- 读取对应 chunk 文件
- 输出到
<output_dir>/step2_chunks/chunk-NN-flagged.md - 等待全部完成后,按顺序合并为
<output_dir>/2.en.indexed.flag.md
-
展开完整文本并检查
[end]flag 准确性:${BUN_X} {baseDir}/scripts/runExpandFlagFull.ts <output_dir>/1.en.indexed.json <output_dir>/2.en.indexed.flag.md <output_dir>/2.en.indexed.flag.full.md输出格式为
[n:+m1+m2+-m3] sentence_text,其中:n为合并后的句子序号+mi表示来源原始条目 mi(其[end]已匹配,或无 flag)+-mi表示来源原始条目 mi,但其 compact flag 中的[end]未被匹配 输出:<output_dir>/2.en.indexed.flag.full.md(合并后句子 + 来源索引)
-
根据
2.en.indexed.flag.full.md评估断句质量,决定后续操作:5.1:匹配率检查(全量重跑判断)
运行统计脚本:
${BUN_X} {baseDir}/scripts/analyzeFlags.ts <output_dir>/2.en.indexed.flag.full.md <output_dir>/2.en.indexed.flag.analy.json输出(保存至
<output_dir>/2.en.indexed.flag.analy.json):{ "totalMi": X, "unmatchedMiCount": Y, "matchedRate": 0.ZZ, "unmatchedSentences": [{ "n": N, "words": W, "text": "...", "miList": [...] }], "longSentencesCount": Z, "longSentences": [{ "n": N, "words": W, "text": "...", "miList": [...] }] }(exit code 0 表示 matchedRate ≥ 0.8,1 表示 < 0.8)若
matchedRate < 0.8(读取2.en.indexed.flag.analy.json中matchedRate)(LLM 标记的[end]大量无法匹配):- 清空
<output_dir>/step2_chunks/ - 重新分块,改为
--max-words 2000:${BUN_X} {baseDir}/scripts/chunk.ts <output_dir>/1.en.indexed.md --max-words 2000 --output-dir <output_dir>/step2_chunks - 重复步骤 3 和步骤 4(LLM 处理 + 展开 flag.full.md)
- 若重跑后仍 < 80%,输出警告,继续执行5.2(局部修复),不再全量重跑。
5.2:对断句质量差的片段局部重新断句
① 判断:读取
2.en.indexed.flag.analy.json,若unmatchedSentences和longSentences均为空,跳过以下步骤。② 备份(若文件存在则备份):
cp <output_dir>/2.en.indexed.flag.md <output_dir>/2.en.indexed.flag.{timestamp}.md cp <output_dir>/2.en.indexed.flag.full.md <output_dir>/2.en.indexed.flag.full.{timestamp}.md cp <output_dir>/2.en.indexed.flag.analy.json <output_dir>/2.en.indexed.flag.analy.{timestamp}.json # 以下两个文件在第一次迭代时不存在,第二次及以后迭代时需要备份: cp <output_dir>/2.en.indexed.part.md <output_dir>/2.en.indexed.part.{timestamp}.md cp <output_dir>/2.en.indexed.part.flag.md <output_dir>/2.en.indexed.part.flag.{timestamp}.md③ 提取需修复片段(
unmatchedSentences和longSentences中各条目的miList):${BUN_X} {baseDir}/scripts/extractPartialIndexed.ts <output_dir>/2.en.indexed.flag.analy.json <output_dir>/1.en.indexed.md <output_dir>/2.en.indexed.part.md输出:
<output_dir>/2.en.indexed.part.md(需重新断句的原始行,保留原始 mi 索引)④ 重新断句:对
2.en.indexed.part.md直接运行步骤 3 的 LLM 断句(不分块,启用单个子 agent),得到:<output_dir>/2.en.indexed.part.flag.md⑤ 合并:将
2.en.indexed.part.flag.md合并回2.en.indexed.flag.md(以2.en.indexed.flag.md中已匹配的 mi 条目为基础,用part.flag.md中的条目添加或替换对应 mi):${BUN_X} {baseDir}/scripts/mergePartialFlags.ts <output_dir>/2.en.indexed.part.flag.md <output_dir>/2.en.indexed.flag.md <output_dir>/2.en.indexed.flag.analy.json⑥ 重新生成 flag.full.md:
${BUN_X} {baseDir}/scripts/runExpandFlagFull.ts <output_dir>/1.en.indexed.json <output_dir>/2.en.indexed.flag.md <output_dir>/2.en.indexed.flag.full.md⑦ 重新统计:
${BUN_X} {baseDir}/scripts/analyzeFlags.ts <output_dir>/2.en.indexed.flag.full.md <output_dir>/2.en.indexed.flag.analy.json⑧ 再次判断:若仍存在
unmatchedSentences或longSentences,从步骤②重复执行;最多再执行两次(共最多 3 次)。 - 清空
Step 3: 生成格式化 JSON (Code)
输入、输出:1.en.indexed.json + 2.en.indexed.flag.md -> 3.en.formatted.json
执行方式(Code):
${BUN_X} {baseDir}/scripts/step3.ts <output_dir>/1.en.indexed.json <output_dir>/2.en.indexed.flag.md <output_dir>/3.en.formatted.json
Step 4: 生成待翻译 Markdown (Code)
输入、输出:3.en.formatted.json + info.json -> 4.en.formatted.indexed.md
执行方式(Code):
# 有 info.json:
${BUN_X} {baseDir}/scripts/step4.ts <output_dir>/3.en.formatted.json <info_json_path> <output_dir>/4.en.formatted.indexed.md
# 无 info.json:
${BUN_X} {baseDir}/scripts/step4.ts <output_dir>/3.en.formatted.json "" <output_dir>/4.en.formatted.indexed.md
Step 5: 翻译 (LLM)
输入、输出:4.en.formatted.indexed.md -> 5.en.formatted.indexed.zh.md
工具:baoyu-skills:baoyu-translate skill
执行方式:
调用 baoyu-translate skill,处理 <output_dir>/4.en.formatted.indexed.md
额外要求(必须在调用时明确指定):
- 保持序号一一对应:
[N]英文 ↔[N]中文,不合并不拆分行;使用grep -c '^\[\d\+\.\?\d\?\]' file.md验证 行数 是否一致。 - 保留所有
[数字]序号前缀 - 翻译
# 章节标题行 - 输出格式与输入完全一致
Step 6: 中文分句与对齐 (LLM + Code)
输入、输出:4.en.formatted.indexed.md + 5.en.formatted.indexed.zh.md -> 6.en.formatted.indexed.zh.segmention.full.md
提示词:{baseDir}/prompts/step6_segmentation_alignment.md
执行方式:
-
读取提示词:
{baseDir}/prompts/step6_segmentation_alignment.md -
检查 chunks。判断 Step 5 是否产生了 chunks:检查 baoyu-translate 实际输出目录(
<output_dir>/4.en.formatted.indexed-zh-CN/chunks/chunks/,或 baoyu-translate 实际输出目录下chunks/chunks/)是否存在chunk-NN.md文件。分支 A:有英文 chunks(利用现有 chunks)
运行以下脚本,将
5.en.formatted.indexed.zh.md按现有的英文 chunk 边界拆分为对应的中文 chunks:${BUN_X} {baseDir}/scripts/splitZhByChunks.ts <output_dir>/5.en.formatted.indexed.zh.md <en_chunks_dir>/chunks <output_dir>/step6_chunks其中
<en_chunks_dir>为 baoyu-translate 输出目录下的chunks/子目录(如<output_dir>/4.en.formatted.indexed-zh-CN/chunks)。输出为:<output_dir>/step6_chunks/chunk-NN-zh.md分支 B:无英文 chunks(生成 chunks)
使用
{baseDir}/scripts/chunk.ts对<output_dir>/4.en.formatted.indexed.md进行分块(max-words 2000),输出到<output_dir>/step6_chunks/:${BUN_X} {baseDir}/scripts/chunk.ts <output_dir>/4.en.formatted.indexed.md --max-words 2000 --output-dir <output_dir>/step6_chunks运行以下脚本,将
5.en.formatted.indexed.zh.md按上述生成的英文 chunk 边界拆分为对应的中文 chunks:${BUN_X} {baseDir}/scripts/splitZhByChunks.ts <output_dir>/5.en.formatted.indexed.zh.md <output_dir>/step6_chunks <output_dir>/step6_chunks -
处理 chunks 2.2 对每对 chunk 并行启动子 agent,每个 agent:
- 读取提示词
- 读取对应英文 chunk:
<en_chunks_dir>/chunks/chunk-NN.md或者<output_dir>/step6_chunks/chunk-NN.md - 读取对应中文 chunk:
<output_dir>/step6_chunks/chunk-NN-zh.md(最终翻译,非草稿) - 按提示词进行分句对齐,输出到
<output_dir>/step6_chunks/chunk-NN-segmented.md2.3 等待全部完成后,按顺序合并为<output_dir>/6.en.formatted.indexed.zh.segmention.md
-
展开完整双语对照文本和生成分析报告:
${BUN_X} {baseDir}/scripts/runExpandSegmentFull.ts <output_dir>/3.en.formatted.json <output_dir>/5.en.formatted.indexed.zh.md <output_dir>/6.en.formatted.indexed.zh.segmention.md <output_dir>/6.en.formatted.indexed.zh.segmention.full.md -
匹配率检查与局部重试
根据
6.en.formatted.indexed.zh.segmention.full.md评估对齐质量,决定后续操作:5.1:匹配率检查(全量重跑判断)
读取
6.en.formatted.indexed.zh.segmention.analy.json中的matchedRate。若
matchedRate < 0.8(LLM 标记的分隔符大量无法匹配):- 清空
<output_dir>/step6_chunks/ - 重新分块,改为
--max-words 1500:${BUN_X} {baseDir}/scripts/chunk.ts <output_dir>/4.en.formatted.indexed.md --max-words 1500 --output-dir <output_dir>/step6_chunks - 重新拆分中文 chunks:
${BUN_X} {baseDir}/scripts/splitZhByChunks.ts <output_dir>/5.en.formatted.indexed.zh.md <output_dir>/step6_chunks <output_dir>/step6_chunks - 重复步骤 3 和步骤 4(LLM 处理 + 展开 full.md)
- 若重跑后仍 < 80%,输出警告,继续执行 5.2(局部修复),不再全量重跑。
5.2:对质量差的片段局部重新对齐
① 判断:读取
6.en.formatted.indexed.zh.segmention.analy.json,若unmatchedSegmentsList为空,跳过以下步骤。② 备份(若文件存在则备份):
cp <output_dir>/6.en.formatted.indexed.zh.segmention.md <output_dir>/6.en.formatted.indexed.zh.segmention.{timestamp}.md cp <output_dir>/6.en.formatted.indexed.zh.segmention.full.md <output_dir>/6.en.formatted.indexed.zh.segmention.full.{timestamp}.md cp <output_dir>/6.en.formatted.indexed.zh.segmention.analy.json <output_dir>/6.en.formatted.indexed.zh.segmention.analy.{timestamp}.json # 以下文件在第一次迭代时不存在,第二次及以后迭代时需要备份: cp <output_dir>/6.en.part.md <output_dir>/6.en.part.{timestamp}.md cp <output_dir>/6.zh.part.md <output_dir>/6.zh.part.{timestamp}.md cp <output_dir>/6.en-zh.part.segmented.md <output_dir>/6.en-zh.part.segmented.{timestamp}.md③ 提取需修复片段:
${BUN_X} {baseDir}/scripts/extractPartialSegments.ts <output_dir>/6.en.formatted.indexed.zh.segmention.analy.json <output_dir>/4.en.formatted.indexed.md <output_dir>/5.en.formatted.indexed.zh.md <output_dir>/6.en.part.md <output_dir>/6.zh.part.md④ 重新对齐:对
6.en.part.md和6.zh.part.md运行步骤 3 的 LLM 对齐(不分块,启用单个子 agent),输出到:<output_dir>/6.en-zh.part.segmented.md⑤ 合并:将修复后的片段合并回主文件:
${BUN_X} {baseDir}/scripts/mergePartialSegments.ts <output_dir>/6.en-zh.part.segmented.md <output_dir>/6.en.formatted.indexed.zh.segmention.md⑥ 重新生成 full.md 和 analy.json:
${BUN_X} {baseDir}/scripts/runExpandSegmentFull.ts <output_dir>/3.en.formatted.json <output_dir>/5.en.formatted.indexed.zh.md <output_dir>/6.en.formatted.indexed.zh.segmention.md <output_dir>/6.en.formatted.indexed.zh.segmention.full.md⑦ 再次判断:若仍存在
unmatchedSegmentsList,从步骤②重复执行;最多再执行两次(共最多 3 次)。 - 清空
Step 7: 生成最终 SRT (Code)
输入、输出:3.en.formatted.json + 6.en.formatted.indexed.zh.segmention.md + 5.en.formatted.indexed.zh.md -> 7.final.srt
执行方式(Code):
${BUN_X} {baseDir}/scripts/step7.ts <output_dir>/3.en.formatted.json <output_dir>/6.en.formatted.indexed.zh.segmention.md <output_dir>/5.en.formatted.indexed.zh.md <output_dir>/7.final.srt
统计汇报 (Code)
输入、输出:1.en.indexed.json + 3.en.formatted.json + 7.final.json -> statistic.json
执行方式(Code):
${BUN_X} {baseDir}/scripts/report.ts <output_dir>/1.en.indexed.json <output_dir>/3.en.formatted.json <output_dir>/7.final.json <output_dir>/statistics.json