本文最后更新于 2023年11月2日 下午
今天刷油管看到了Joma发的新小视频, 感觉非常有意思, 萌生了翻译一下搬运到b站的想法
这里记录一下整个从下载 视频, 音频到编辑, 翻译, 合并双语字幕的整个工作流
看看我翻译的第一个视频
youtube视频下载
现在最稳妥的youtube的视频下载方式就是通过github的这俩插件, 其中前者在github上已经达到了惊人的112kstar, 而后者是前者的优化升级版本
youtube-dl: https://github.com/ytdl-org/youtube-dl
yt-dlp: https://github.com/yt-dlp/yt-dlp
但是经过我的测试, youtube-dl的下载速度不佳(一度40KB/s), 不知道为什么yt-dlp速度快很多(10MB/s) (百兆宽带 + 科学上网)
这里以yt-dlp为例, 展示下如何下载视频, 音频和字幕文件
下载直接到release页下载操作系统对应的可执行文件就好了, 我这里用的windows
命令
请先确认你的终端走了代理, cmd可以参考set https_proxy=xx, powershell可用$env:https_proxy=xx
下载视频和音频
yt-dlp.exe -F https://www.youtube.com/watch?v=asdf: 查看可下载项
yt-dlp.exe -f [ID] https://www.youtube.com/watch?v=asdf 下载第一列ID对应的项
注意到VCDOEC和ACODEC标识了该项是音频or视频, 可以直接通过下面的命令下载并合并音视频:
yt-dlp.exe -f [ID1]+[ID2] https://www.youtube.com/watch?v=asdf
下载字幕
先用yt-dlp.exe --list-subs https://www.youtube.com/watch?v=asdf 查看所有字幕支持的语言
然后yt-dlp.exe --write-subs --sub-format SRT --sub-langs en --skip-download https://www.youtube.com/watch?v=asdf
下载SRT格式的英文字幕, 如果下载下来为VTT格式的, 直接把VTT文档中的前两行删除, 然后文件名后缀为.srt即可
顺带一提: 字幕翻译可以不必在这里下载翻译的字幕, 可以在下面的字幕制作中一起翻译
字幕编辑
推荐一个非常好用的开源字幕编辑器subtitleedit
https://github.com/SubtitleEdit/subtitleedit/releases
支持:
- 导入字幕文件视频并实时编辑查看
- 基于google翻译字幕
- 修改字幕样式
- etc
在编辑好字幕后
- 点击:
文件-保存 保存翻译后字幕
- 点击:
文件-保存原始字幕 保存英文字幕
字幕合并
目前字幕分为翻译和原始两个文件, 我们制作双语字幕期望他们一上一下出现, 可以自己写个简单的python脚本处理, 我这里网上随便找了一个: https://stackoverflow.com/questions/69868981/how-to-merge-multiple-subtitle-files-in-python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
import argparse import sys from datetime import timedelta from pathlib import Path
import srt
def nearest(items, pivot): return min(items, key=lambda x: abs(x.start - pivot))
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='merge SRT subtitles', usage=""" Merge SRT subtitles: \t{0} first.srt second.srt -o merged.srt """.format(Path(sys.argv[0]).name))
parser.add_argument('srt1', metavar='srt1', help='SRT-file-1') parser.add_argument('srt2', metavar='srt2', help='SRT-file-2') parser.add_argument('--output-file', '-o', default=None, help='Output filename') parser.add_argument('--encoding', '-e', default=None, help='Input file encoding') args = parser.parse_args(sys.argv[1:])
srt1_path = Path(args.srt1) srt2_path = Path(args.srt2)
with srt1_path.open(encoding=args.encoding or 'utf-8') as fi1: subs1 = {s.index: s for s in srt.parse(fi1)}
with srt2_path.open(encoding=args.encoding or 'utf-8') as fi2: subs2 = {s.index: s for s in srt.parse(fi2)}
sub: srt.Subtitle start: int for idx, sub in subs2.items():
start: timedelta = sub.start sub_nearest_slot: srt.Subtitle = nearest(subs1.values(), start) sub_nearest_slot.content = f'{sub_nearest_slot.content}<br>{sub.content}' subs1[sub_nearest_slot.index] = sub_nearest_slot
if not args.output_file: generated_srt = srt1_path.parent / (f'{srt1_path.stem}_MERGED_{srt1_path.suffix}') else: generated_srt = Path(args.output_file)
with generated_srt.open(mode='w', encoding='utf-8') as fout: fout.write(srt.compose(list(subs1.values())))
|
然后进行: python3 srt_merge.py subs1.srt subs2.srt -o final.srt即可
注意提前安装一下srt模块: pip install srt
将srt嵌入视频
当我欣喜若狂的将嵌好字幕的视频发到b站后, 发现字幕并没有被显示, 原来使我都没搞清楚外挂字幕和内嵌字幕
软字幕 (内挂字幕)
软字幕是通过stream copy流拷贝的方式进行的, 一般保存为mkv文件, 打开可以发现可以用视频播放器调整字幕大小等.
1 2 3
| ffmpeg -i input.mkv -i subtitles.ass -codec copy -map 0 -map 1 output.mkv
ffmpeg -i infile.mp4 -f srt -i infile.srt -c:v copy -c:a copy -c:s mov_text outfile.mp4
|
这里推荐一个批量嵌入当前文件夹下所有MP4和同名SRT文件的bat:
1
| for %%a in ("*.mp4") do ffmpeg -i %%~na.mp4 -i %%~na.srt -vcodec copy -acodec copy %%~na.mkv
|
硬字幕 (内嵌字幕)
内嵌字幕就是直接把字幕合并死到视频里
可以通过
1
| ffmpeg -i input.mp4 -vf "subtitles=subtitle.srt" output.mp4
|
来操作
如果视频本身就是mkv的, 可以:
1
| ffmpeg -i input.mkv -vf subtitles=input.mkv output.mp4
|
来操作
注意上传到b站等视频平台最好直接硬字幕嵌入再上传.
或者直接上传源视频文件和srt文件(不过b站连<br>都解析不出来, 太菜了)
参考
- https://crifan.github.io/media_process_ffmpeg/website/subtitle/embed/
- https://www.hash070.top/archives/youtube-video-download.html
- https://zhuanlan.zhihu.com/p/422397038