- 一条龙流水线 — 从直播 URL 到中文字幕、AI 总结,全程命令行串联,无需手动倒腾中间文件。
- 日语识别更准 — 默认 kotoba-whisper-v2.2 蒸馏模型,自动补日语句读后再断句,字幕是完整句子而非碎片。
- 句子完整不截断 — 长音频用 Silero VAD 探出人声间隙、分段流式转写,切点落在无人说话处,边转边落盘,精度与整段转写一致。
- 唱歌场次友好 — 内置 audio-separator 人声分离,长音频自动切段防爆内存、输出比特率对齐原音频,去掉 BGM / 伴奏再识别。
- 省心的中文化 — AI 逐条翻译保留时间轴,并能按时间线 / 概述 / 高光 / 歌单等预设一键总结整场直播。
- 专为 50 系显卡调优,兼顾 Apple Silicon — Nvidia 走
pytorch-cu128(CUDA 12.8),onnxruntime 复用 torch 自带 CUDA 运行时,开箱即用 GPU 加速;macOS(M 系列)自动切到 MPS 加速栈。
- 📥 内置 yt-dlp 下载后端,支持 Twitch / YouTube 等更多平台的视频与直播回放
- 🎵
download默认提取最佳音频为 MP3,直接复用转字幕、翻译、总结流水线 - 🔧 可用
--或--yt-dlp-args透传 yt-dlp 原生参数 - 🎤 使用 Whisper 进行语音识别,默认
kotoba-whisper-v2.2(日语识别更准的蒸馏模型) - ✂️ 句子级断句,按句末标点 / 停顿 / 长度上限智能切分,保证句子完整不被拦腰截断
- ✒️ 蒸馏模型只产短语级时间戳且不带标点,自动用标点模型补日语句读(。!?)后再断句,时间戳原样保留
- 🪓 长音频按 VAD 人声间隙切分、分段流式转录:实时进度、边转边写盘,切点落在无人说话处,精度不受影响
- 🔗 下载与字幕一条龙:一条命令从直播 URL 直达 SRT 字幕
- 🌐 调用大模型把日语 SRT 翻译成中文 SRT,逐条对应、保留原时间轴(默认 DeepSeek,可接其他 OpenAI 兼容端点)
- 🤖 调用大模型对 SRT 字幕做 AI 总结,提示词走 JSON 预设(时间线 / 概述 / 高光 / 歌单),长字幕自动分块(默认 DeepSeek,可接其他 OpenAI 兼容端点)
- 🖼️ 可把总结 Markdown 渲染为分享图片:Markdown 先转 HTML,再由 Chromium 截图输出 PNG
- 🎚️ 用 audio-separator 分离人声,可单独导出,也可在转录前
--separate预处理去掉 BGM / 唱歌干扰 - 🧹 自动清理重复字符与乱码,并抑制模型的幻觉式重复
- 🎮 可选剔除 VALORANT 游戏内系统播报 / 技能语音(如「残り1名」「グレネード配置」),让字幕聚焦主播人声
- 📄 输出标准 SRT,可直接拖入播放器或视频剪辑软件
按以下步骤从零部署,全程约几分钟(不含模型下载):
1. 准备系统依赖
- uv(包管理 + 运行器)— 装好后
uv --version应有输出 - ffmpeg — 须在 PATH 中,
ffmpeg -version应有输出(yt-dlp 音频提取/转码、音频切分都依赖它) - yt-dlp — 须在 PATH 中,
yt-dlp --version应有输出;建议自行保持最新版:pip install -U yt-dlp - GPU — 转字幕、分离人声需要。Nvidia 显卡(
nvidia-smi应能看到显卡)或 Apple Silicon(M 系列芯片,走 MPS 加速)二选一
2. 克隆并同步依赖
git clone https://github.com/kanbereina/KITS.git
cd KITS
uv sync # 创建虚拟环境并装齐所有依赖(含 dev 组)
pip install -U yt-dlp # 安装/更新 yt-dlp;它更新频繁,不随 uv lock 固定版本uv sync 会按平台自动选对依赖:
- Linux / Windows(Nvidia) — 从
pytorch-cu128源装 CUDA 12.8 版 PyTorch,以及 audio-separator(含 onnxruntime-gpu)、punctuators 等。无需手动装 CUDA Toolkit——onnxruntime 复用 torch 自带的 CUDA 运行时。 - macOS(Apple Silicon) — 无 CUDA 轮子,自动从 PyPI 默认源装自带 MPS 的 PyTorch,配 CPU/CoreML 版 onnxruntime 与
audio-separator[cpu]。转录走 MPS 加速;人声分离可用但比 Nvidia 慢。
3. 验证安装
uv run kits --help # 看到子命令说明即安装成功
# Nvidia 应输出 CUDA: True;Apple Silicon 应输出 MPS: True
uv run python -c "import torch; print('CUDA:', torch.cuda.is_available(), '| MPS:', torch.backends.mps.is_available())"
yt-dlp --version # 应输出版本号;下载站点适配异常时先 pip install -U yt-dlp4.(可选)配置大模型 API Key
translate / summarize 需要大模型 API Key,默认走 DeepSeek。使用命令时传入或设置环境变量:
export DEEPSEEK_API_KEY=sk-xxxx # Windows PowerShell: $env:DEEPSEEK_API_KEY="sk-xxxx"也可用
KITS_LLM_API_KEY/OPENAI_API_KEY,或用--base-url接入其他 OpenAI 兼容端点(OpenAI / Ollama / vLLM 等),详见下方「接入其他 OpenAI 兼容端点」。
首次运行转字幕会自动从 Hugging Face 下载模型(kotoba-whisper 约几个 GB + 标点模型约 1GB),需要联网;之后走本地缓存。
5.(可选)安装总结图片渲染依赖
summarize --render-image 通过 Markdown → HTML → 浏览器截图生成 PNG,需要安装可选的 Markdown / Playwright 依赖和 Chromium 浏览器:
uv sync --extra image
uv run --extra image playwright install chromium| 项 | 要求 | 说明 |
|---|---|---|
| Python | 3.12 ~ 3.14 | 由 uv 管理虚拟环境 |
| GPU | 支持 CUDA 的 Nvidia 显卡,或 Apple Silicon(M 系列) | 转字幕 / 分离人声强制要求;仅下载不需要 |
| CUDA | 12.8(仅 Nvidia) | Linux/Win 的 PyTorch 从 pytorch-cu128 源安装,勿换 PyPI 默认源;macOS 不需要 |
| ffmpeg | 在 PATH 中 | yt-dlp 音频提取/转码、音频切分 |
| yt-dlp | 在 PATH 中,建议最新版 | 下载 Twitch / YouTube 等视频或直播回放;自行 pip install -U yt-dlp 更新 |
| API Key | 大模型(可选) | 仅 translate / summarize 需要,默认 DeepSeek |
| markdown-it-py + Playwright + Chromium | 可选 | 仅 summarize --render-image 需要,用于 Markdown 渲染与 HTML 截图 |
工具提供五个子命令:download(下载直播)、subtitle(音频转字幕)、translate(日语字幕译中文)、separate(人声分离)和 summarize(AI 总结字幕)。每个命令都带一个简写别名,可互换使用。
| 命令 | 别名 | 用途 | 最简示例 | 需 GPU | 需 API Key |
|---|---|---|---|---|---|
download |
dl |
用 yt-dlp 下载视频/直播回放,默认导出 MP3 | uv run kits dl "<url>" -o name |
否¹ | 否 |
subtitle |
srt |
音频转带时间戳的 SRT 字幕 | uv run kits srt -i audio.mp3 |
是 | 否 |
translate |
tr |
日语 SRT 翻译成中文 SRT | uv run kits tr -i live.srt |
否 | 是 |
separate |
sep |
从音频分离出人声,去 BGM / 伴奏 | uv run kits sep -i audio.mp3 |
是 | 否 |
summarize |
sum |
对 SRT 做 AI 总结(时间线 / 歌单等) | uv run kits sum -i live.srt |
否 | 是 |
¹
download本身不需要 GPU;但加--srt(下载后自动转字幕)会调用 Whisper,需要 GPU。
download 统一调用 PATH 中的 yt-dlp 命令。默认选择最佳音频并提取为 MP3,产物可直接交给 subtitle / translate / summarize 流水线;Twitch VOD、YouTube 和其他 yt-dlp 支持的网站都走同一条路径。
# 下载视频/直播回放音频,默认输出 downloads/live.mp3
uv run kits download "https://www.youtube.com/watch?v=..." -o live
# 一条龙:下载音频 -> 生成 SRT 字幕
uv run kits download "https://www.twitch.tv/videos/..." -o live --srt
# 透传 yt-dlp 原生参数:`--` 后的内容原样交给 yt-dlp
uv run kits download "https://youtu.be/..." -- -f bestaudio --extract-audio
# 也可以用字符串形式透传,适合脚本里集中配置
uv run kits download --yt-dlp-args="-f bestaudio --extract-audio" "https://youtu.be/..."产物默认放在 downloads/ 目录下。yt-dlp 分片下载并发默认固定为 5;需要调整时可透传 --concurrent-fragments N。
| 参数 | 默认值 | 说明 |
|---|---|---|
url |
(必填) | yt-dlp 支持的视频/直播回放 URL |
-o, --output |
output |
输出文件名(不含扩展名) |
--dir |
downloads |
下载 / 输出目录 |
--yt-dlp-args |
无 | 额外透传给 yt-dlp 的原生参数字符串 |
--srt |
关闭 | 额外生成 SRT 字幕(自动转录下载后的音频) |
-- ... |
无 | -- 后的参数原样透传给 yt-dlp |
--srt会调用 Whisper 转录,需要 GPU。yt-dlp 对正在直播中的流支持取决于站点与 yt-dlp 本身;下载站点适配异常时先运行pip install -U yt-dlp更新。KITS 侧主要复用已下载音频做转录、翻译与总结。还支持下方subtitle的全部断句参数(--max-gap等)。
已有音频文件时,直接转 SRT。输入为必填项,用 -i 指定:
uv run kits subtitle -i your_audio.mp3默认输出到 subtitle.srt,可用 -o 自定义:
uv run kits subtitle -i your_audio.mp3 -o output.srt也可以用
uv run python main.py subtitle -i ...,效果等价(main.py是薄入口)。
| 参数 | 默认值 | 说明 |
|---|---|---|
-i, --input |
(必填) | 输入音频文件路径 |
-o, --output |
subtitle.srt |
输出 SRT 文件路径 |
--model |
kotoba-tech/kotoba-whisper-v2.2 |
转录模型,可选 kotoba-tech/kotoba-whisper-v2.2 / kotoba-tech/kotoba-whisper-v2.0(同构,均走 chunk 级时间戳 + 标点恢复) |
--language |
japanese |
识别语言 |
--beams |
3 |
beam search 数量,默认 3 更稳;1 为贪心解码,更快 |
--max-gap |
0.7 |
判定断句的最大停顿(秒),越小切得越碎 |
--max-chars |
60 |
单条字幕最大字符数 |
--max-duration |
15.0 |
单条字幕最大时长(秒) |
--max-seconds-per-char |
0.5 |
单条字幕每字符最大时长(秒),收缩 kotoba 虚高的字幕时长(详见下方「修正时间戳漂移」);<=0 关闭 |
--target-chunk |
300.0 |
分段目标时长(秒),长音频每段约这么长 |
--max-chunk |
600.0 |
单段硬上限(秒),段内无人声间隙时在此强切 |
--vad-threshold |
0.5 |
VAD 语音概率阈值(0~1),高于此算人声;越大越严格(检出人声更少、间隙更多) |
--min-silence |
0.5 |
短于此(秒)的停顿并入人声、不算切点间隙;越大间隙越少、段越接近整段 |
--filter-game |
关闭 | 剔除指定游戏的播报 / 技能语音,按游戏名启用、可多次指定(整条完全匹配才删) |
--separate |
关闭 | 转录前先用 audio-separator 分离人声(去 BGM / 唱歌干扰,需安装 audio-separator + GPU) |
--separate-model |
UVR-MDX-NET_Main_427.onnx |
人声分离模型文件名,仅在 --separate 时生效 |
--separate-segment-size |
512 |
人声分离分块大小,越大越快越吃显存,仅在 --separate 时生效 |
--separate-overlap |
0.1 |
人声分离分块重叠(0~1),越小越快,仅在 --separate 时生效 |
--separate-segment-minutes |
15 |
人声分离长音频切段时长(分钟),防爆内存(<=0 关闭),仅在 --separate 时生效 |
--separate-output-bitrate |
自动对齐原音频 | 人声输出比特率(如 128k),无损格式忽略,仅在 --separate 时生效 |
--no-punctuate |
(默认补标点) | 关闭标点恢复;模型本身已输出标点时可关 |
--punct-model |
xlm-roberta 日语句读 | 标点恢复模型 |
默认 kotoba-tech/kotoba-whisper-v2.2。可用 --model 切换到 kotoba-tech/kotoba-whisper-v2.0,方便对比识别效果:
# 默认 v2.2
uv run kits subtitle -i live.mp3 -o v22.srt
# 换用 v2.0
uv run kits subtitle -i live.mp3 -o v20.srt --model kotoba-tech/kotoba-whisper-v2.0两者同构(large-v3 全编码器 + 2 层解码器),均走 chunk 级时间戳 + 标点恢复链路。download --srt 也支持 --model。仅限白名单内的模型,传入其他名字会报错。
默认模型 kotoba-whisper-v2.2 是蒸馏模型,日语识别更准,但只产出短语级时间戳且不带句末标点。无标点会让断句只能靠长度上限硬切,字幕被压成一条条 15 秒的长块。
为此转录后会自动用标点模型(kotoba 官方同款 xlm-roberta 日语句读模型)给每个短语补上 。!?、,时间戳原样保留,让断句在句末标点处自然切开。实测一段 120 秒音频,补标点后字幕从 7 条细化到 19 条、被硬切的从 5 条降到 2 条。
# 默认补标点,无需额外参数
uv run kits subtitle -i live.mp3
# 若换用本身已带标点的模型,可关闭标点恢复
uv run kits subtitle -i live.mp3 --no-punctuate首次运行会下载标点模型(约 1GB)。标点模型在 CPU 上即可快速推理。
kotoba 蒸馏模型有个固有毛病:短语的结束时间戳常虚高,end 会溢出到人声结束之后的静音里——十来个字的短句被标成几十秒,字幕在播放器里迟迟不消失、甚至盖过下一句造成时间倒退。
为此对明显偏长的字幕做两级收缩,只缩短显示时长、不改文本与起点,按可靠性分工:
- VAD 人声边界(首选):长音频转录时已探出的人声区间是真实测量值。对极虚高的字幕(每字符时长超过
1.0秒),直接把 end 夹回「人声实际结束处」。实测这比单纯按语速估算更贴近真实结尾(误差 0.10.3 秒 vs 2.53.5 秒)。 - 字符速率(兜底):VAD 对不上时(如短音频没跑 VAD、或人声边界落在句外),改按
--max-seconds-per-char(每字符最多 0.5 秒,日语正常语速 ≥2 字/秒)估算朗读时长上限收缩。
两者互斥、择一生效,对正常语速的字幕都不动。VAD 修正在已分离人声(--separate 或先用 separate 子命令)上最准,原始音频里 BGM / 唱歌会干扰人声边界判定。--max-seconds-per-char 设 <=0 可关闭字符速率兜底(此时仅保留 --max-duration 硬上限)。
长音频会自动分段转录、逐段流式写盘(实时进度、边转边落盘,中途中断已转部分仍是合法 SRT)。有两种分段模式:
默认:逐 VAD 人声窗口(对齐最准,纯说话场次推荐)
用 Silero VAD 探出一个个「话语级人声窗口」,只转人声窗口、丢弃窗口间静音,每个窗口以其真实起点做偏移锚点。好处:时间戳锚定真实人声边界,根治 Whisper「前导静音把首句标成 0:00」的漂移(实测人声 23.5s 才开始时,首条字幕正确落在 23.5s 而非 0)。
⚠️ 唱歌延音会丢字幕:Silero VAD 按「说话」训练,对唱歌的持续长元音系统性漏判(不判为语音)→ 那段不建窗口、字幕整段丢失。实测调低--vad-threshold也救不回(延音语音概率本就接近 0)。歌枠 / 含大量唱歌的内容请用--full-transcribe。
--full-transcribe:整段连续转录(不丢唱歌,歌枠推荐)
按非语音间隙把长音频切成 ~5 分钟大段、整段连续喂给 kotoba(段内含静音也一起转)。不靠 VAD 决定「转不转」,故唱歌延音也能识别出歌词、不丢字幕。代价:段首若有前导静音,该段首句时间戳可能偏早(kotoba 对前导静音的固有毛病)。
# 默认(纯说话场次,对齐最准)
uv run kits subtitle -i live.mp3
# 歌枠 / 含唱歌(不丢唱歌字幕)
uv run kits subtitle -i live.mp3 --full-transcribe两种模式 VAD 都固定走 CPU(silero 是 LSTM、GPU 反慢,4 小时音频约 2 分钟扫完),扫描时显示 VAD 扫描 N% 进度。
直播玩 VALORANT 时,麦克风会混入大量游戏音——系统播报(「残り1名」「ディフェンダーの勝利」)和特工技能语音(「アラームボット配置」「グレネード配置」)。这些不是主播说的话,对「直播字幕」是噪声,还会在后续翻译时白白消耗 token。用 --filter-game 指定游戏名即可剔除:
# 指定游戏名(大小写不敏感,支持简写 valo)
uv run kits subtitle -i live.mp3 --filter-game valorant
uv run kits subtitle -i live.mp3 --filter-game valo
# 多款游戏可重复指定(词表合并)
uv run kits subtitle -i live.mp3 --filter-game valorant --filter-game valo目前内置词表:valorant(简写 valo)。传入未收录的游戏名会报错并列出当前支持的名字。
采用整条完全匹配策略:仅当一条字幕(去空格、去首尾标点后)恰好等于内置词表中的某条播报词时才删除,最大限度避免误删主播人声。因此:
- ✅ 整条纯播报(如
セントリー設置)会被删 ⚠️ 播报与人声混在同一条(如中央に敵だ…ご視聴ありがとうございました)会整条保留⚠️ 词表未收录的转录变体可能漏删
默认关闭,仅在玩对应游戏的场次按需开启。新增游戏只需在 filters.py 的 GAME_CALLOUTS / _GAME_ALIASES 登记词表与别名。
把已有的日语 SRT 字幕调用大模型翻译成中文 SRT,逐条对应、保留原时间轴。需要大模型 API Key(默认 DeepSeek):
# 用环境变量提供 Key(推荐)
export DEEPSEEK_API_KEY=sk-xxxx
uv run kits translate -i live.srt
# 或用命令行参数传入 Key,并自定义输出
uv run kits translate -i live.srt -o live_cn.srt --api-key sk-xxxx不指定 -o 时,输出默认在原文件名后插入 .zh,如 live.srt → live.zh.srt。
| 参数 | 默认值 | 说明 |
|---|---|---|
-i, --input |
(必填) | 输入 SRT 字幕文件路径 |
-o, --output |
原名.zh.srt |
输出 SRT 文件路径 |
--api-key |
读环境变量 | LLM API Key,缺省读 KITS_LLM_API_KEY / OPENAI_API_KEY / DEEPSEEK_API_KEY |
--base-url |
DeepSeek | OpenAI 兼容端点 base_url,缺省读 KITS_LLM_BASE_URL,见下方「接入其他 OpenAI 兼容端点」 |
--model |
deepseek-chat |
LLM 模型名 |
--batch-size |
20 |
每批翻译的字幕条数 |
翻译只替换文本、保留时间戳。字幕按批发送给模型逐条翻译,某条译文缺失时会回退保留原日语,避免时间轴错位。
用 audio-separator(UVR/MDX 模型)从音频中分离出人声,去掉 BGM / 伴奏。适合鹿乃唱歌场次:先分离人声再转录,可显著降低背景音乐对识别的干扰。默认模型 UVR-MDX-NET_Main_427.onnx(MDX 架构,走 onnxruntime GPU 加速)。
# 分离人声,默认输出 MP3 到 output/(原名_(Vocals).mp3)
uv run kits separate -i live.mp3
# 直接指定输出文件路径(与其他命令一致,-o 给文件名)
uv run kits separate -i live.mp3 -o vocals.mp3
# 指定格式与模型
uv run kits separate -i live.mp3 -o vocals.wav --model Kim_Vocal_2.onnx首次运行会自动下载分离模型。Nvidia 用 CUDA GPU + audio-separator[gpu],macOS(Apple Silicon) 用 audio-separator[cpu](CPU/CoreML,较慢);均已在依赖中按平台分流,uv sync 即装。
| 参数 | 默认值 | 说明 |
|---|---|---|
-i, --input |
(必填) | 输入音频文件路径 |
-o, --output |
--dir/原名_(Vocals).格式 |
输出人声文件路径,指定时输出格式按其扩展名 |
--dir |
output |
人声输出目录(未指定 -o 时生效) |
--model |
UVR-MDX-NET_Main_427.onnx |
分离模型文件名(audio-separator 模型库中的文件名) |
--format |
MP3 |
输出音频格式(WAV / MP3 / FLAC 等) |
--segment-size |
512 |
分块大小,越大越快越吃显存(显存紧张可降到 256) |
--overlap |
0.1 |
MDX(.onnx) 分块重叠(0~1),越小越快、接缝质量略降 |
--segment-minutes |
15 |
长音频按此时长(分钟)切段逐段分离再合并,防爆内存(<=0 关闭) |
--output-bitrate |
自动对齐原音频 | 输出比特率(如 128k),默认探测原音频并向上取整到 2 的幂;无损格式忽略 |
长音频(如 4 小时录播)一次性分离会撑爆内存,故默认按
--segment-minutes切段、逐段分离再用 ffmpeg 无缝合并;中间产物为无损 WAV,最终只编码一次。输出比特率默认对齐原音频(人声分离后内容简单,不超过原始比特率即可保真),避免固定高码率导致文件虚大。也可以不单独跑
separate,直接在subtitle/download上加--separate,转录前自动分离人声。
把已有 SRT 字幕交给大模型做总结,方便快速回顾整场直播。提示词走 JSON 预设,长字幕会自动分块总结再合并。需要大模型 API Key(默认 DeepSeek,命令可简写为 sum):
export DEEPSEEK_API_KEY=sk-xxxx
# 默认预设(timeline,时间线分段总结),输出到 live.summary.md
uv run kits summarize -i live.srt
# 指定预设:summary 概述 / highlights 高光 / setlist 歌单(用别名 sum)
uv run kits sum -i live.srt --preset setlist -o setlist.md
# 总结完成后同时渲染分享 PNG(需先安装 image extra 和 Chromium)
uv run --extra image kits summarize -i live.srt --render-image
# 用自定义提示词 JSON 覆盖内置预设
uv run kits summarize -i live.srt --prompt-file my_prompts.json --preset mine内置预设:
| 预设 | 说明 |
|---|---|
timeline |
按话题分段、每段带时间戳的时间线总结(默认) |
summary |
几段连贯文字的整体概述 |
highlights |
高光时刻 / 要点列表,带时间戳 |
setlist |
歌单提取,识别演唱的歌曲并按时间列出 |
| 参数 | 默认值 | 说明 |
|---|---|---|
-i, --input |
(必填) | 输入 SRT 字幕文件路径 |
-o, --output |
原名.summary.md |
输出总结文件路径 |
--api-key |
读环境变量 | LLM API Key,缺省读 KITS_LLM_API_KEY / OPENAI_API_KEY / DEEPSEEK_API_KEY |
--base-url |
DeepSeek | OpenAI 兼容端点 base_url,缺省读 KITS_LLM_BASE_URL,见下方「接入其他 OpenAI 兼容端点」 |
--model |
deepseek-chat |
LLM 模型名 |
--preset |
配置 default | 总结预设名(timeline / summary / highlights / setlist) |
--prompt-file |
无 | 自定义提示词 JSON,覆盖内置预设 |
--max-chars |
8000 |
单块送审最大字符数,超长字幕按此分块 |
--render-image |
关闭 | 总结 Markdown 写盘后同时渲染 PNG 图片 |
--image-output |
总结文件同名 .png |
总结图片输出路径 |
--image-width |
1200 |
图片正文宽度(px) |
--image-theme |
light |
图片主题,可选 light / dark |
--image-scale |
2.0 |
浏览器截图缩放比例,数值越大图片越清晰也越大 |
自定义提示词 JSON 格式:顶层
presets是「预设名 → {description, system}」字典,可选default(默认预设名)和reduce_system(多块合并时的提示词)。用户预设与内置预设浅合并,同名覆盖。
translate / summarize 的大模型调用走 OpenAI 标准 /chat/completions 协议,默认指向 DeepSeek。通过 --base-url(或环境变量 KITS_LLM_BASE_URL)可接入任意 OpenAI 兼容端点,如 OpenAI 官方、本地 Ollama、vLLM、LM Studio 等:
# OpenAI 官方
uv run kits summarize -i live.srt --base-url https://api.openai.com/v1 --model gpt-4o-mini --api-key sk-xxxx
# 本地 Ollama(本地端点通常无需鉴权,可不传 --api-key)
uv run kits summarize -i live.srt --base-url http://localhost:11434/v1 --model qwen2.5
# 本地 vLLM
uv run kits translate -i live.srt --base-url http://localhost:8000/v1 --model Qwen/Qwen2.5-7B-Instructbase_url 只需给到 /v1 这层,工具会自动补 /chat/completions(若已带该路径则原样使用)。API Key 解析优先级:--api-key > KITS_LLM_API_KEY > OPENAI_API_KEY > DEEPSEEK_API_KEY;默认 DeepSeek 端点仍要求 Key,自定义端点允许空 Key。
⚠️ 安全提示:--base-url是你显式指定的外发端点,API Key 与字幕内容会发往该地址。接入第三方 / 远程端点前请确认其可信。
# 转录日语直播音频,输出到指定文件
uv run kits subtitle -i live_2026.mp3 -o live_2026.srt
# 句子偏碎时,调大停顿阈值让句子更连贯
uv run kits subtitle -i live_2026.mp3 --max-gap 1.0
# 玩 VALORANT 的场次,剔除游戏系统播报 / 技能语音
uv run kits subtitle -i live_2026.mp3 --filter-game valorant
# 转录英语内容
uv run kits subtitle -i talk.mp3 --language english
# 唱歌场次:先分离人声再转录,降低 BGM 干扰
uv run kits subtitle -i live_2026.mp3 --separate
# 转录完后做一份时间线总结,方便回顾
uv run kits sum -i live_2026.srt
# 提取整场直播的歌单
uv run kits sum -i live_2026.srt --preset setlistsrc/kits/
__init__.py # 包入口,导出字幕相关纯逻辑 API
subtitle.py # 纯逻辑:单词时间戳 -> 完整句子 -> SRT,含 SRT 解析与增量写入(无 torch 依赖,可单测)
filters.py # 纯逻辑:剔除游戏内系统播报 / 技能语音(无 torch 依赖,可单测)
llm.py # 公共 OpenAI 兼容 LLM 客户端:base_url + 鉴权 + HTTP + 错误处理(仅 httpx,translate/sum 共用)
transcriber.py # Whisper 模型加载 + GPU 转录,长音频按 VAD 人声间隙切分、分段流式产出 chunk 级时间戳
vad.py # 语音活动检测:Silero VAD 探人声区间,作分段切点 + 修正字幕时间戳漂移(延迟导入 torch/silero-vad)
punctuator.py # 标点恢复:给无标点的转录 chunk 补日语句读(延迟导入 punctuators),时间戳不变
downloader.py # yt-dlp 下载后端,默认产出 MP3 音频
translator.py # 把日语 SRT 翻译成中文 SRT(经 llm 客户端,默认 DeepSeek)
separator.py # 人声分离:封装 audio-separator(延迟导入,默认只出 Vocals 轨)
summarizer.py # 总结 SRT,提示词走 JSON 预设、长字幕 map-reduce 分块(经 llm 客户端,默认 DeepSeek)
data/
prompts.json # 内置总结提示词预设(timeline / summary / highlights / setlist)
cli.py # 命令行入口(download / subtitle / translate / separate / summarize 子命令,各带简写别名)
main.py # 薄入口,委托给 kits.cli
各模块职责清晰、相互解耦:
downloader.YtDlpDownloader调用 yt-dlp 下载更多平台的视频/直播回放,默认产出 MP3 音频,不依赖 torchtranscriber.Transcriber.transcribe()把音频转成(chunk/短语级)时间戳列表;长音频走plan_audio()(VAD 探人声间隙、规划分段)+transcribe_segments()(逐段流式产出)vad.VADetector.detect_speech()用 Silero VAD 探人声区间:取补集得非语音间隙喂分段规划,并作真实人声边界把 kotoba 虚高的字幕 end 夹回(延迟导入重依赖)punctuator.Punctuator.restore()给无标点的 chunk 补日语句读,时间戳不变(延迟导入重依赖)subtitle.segment_sentences()负责断句、write_srt()/SrtWriter负责落盘(后者支持分段增量写)、parse_srt()负责把 SRT 读回句子列表llm.LLMClient集中 OpenAI 兼容端点的鉴权与请求(默认 DeepSeek,可配--base-url);translator.LLMTranslator与summarizer.Summarizer复用它separator.VocalSeparator.separate()用 audio-separator 分离人声(延迟导入重依赖)summarizer.Summarizer.summarize()按预设提示词总结字幕,长字幕分块再合并cli把它们串成流水线:download --srt即「yt-dlp 下载音频 -> 转字幕」,subtitle --separate即「分离人声 -> 转字幕」
字幕按以下优先级切分句子,确保完整性:
- 句末标点:遇到
。!?」等结尾标点即认为一句结束(蒸馏模型无标点时,先经标点恢复补上) - 停顿:与上一段的间隔超过
--max-gap时断句 - 长度上限:超过
--max-chars或--max-duration时,优先在逗号/读点处切开,避免单条字幕过长
依赖底层的 ffmpeg/transformers 解码,常见的 .mp3、.wav、.m4a、.flac 等均可。
1
00:00:00,000 --> 00:00:02,600
こんにちは、今日は配信です。
2
00:00:05,000 --> 00:00:06,800
ありがとうございました报错 未检测到可用 GPU:需要 CUDA(Nvidia) 或 MPS(Apple Silicon) 设备!
程序检测不到可用 GPU。Nvidia 用户请确认显卡驱动、CUDA 已正确安装且 PyTorch 是 GPU 版本(torch.cuda.is_available() 应为 True);Apple Silicon 用户请确认 torch.backends.mps.is_available() 为 True。纯 CPU 环境不支持转录(太慢)。
模型下载失败 检查网络连接(需要访问 Hugging Face)。如已有本地缓存,下载失败时会自动回退到缓存。
字幕太碎 / 太长
用 --max-gap 调节断句松紧(调大更连贯),用 --max-chars、--max-duration 控制单条字幕的上限。