这让我发疯了。
我有一个视频文件,input.mkv
其中包含多个字幕流。我想将其中一个字幕流硬编码到新文件中。我通常这样做:
inputfile="input.mkv"
outputfile="out.mp4"
ffmpeg -i "$inputfile" -vf "subtitles=$(printf "%q" "$inputfile")" "$outputfile"
现在由于input.mkv
有多个子流,我需要指定我想要哪一个。输入ffprobe
:
(为了便于阅读,我将删除一些不相关的(我认为)字段)
$ ffprobe -v quiet -print_format json -show_streams -select_streams s input.mkv | jq -r '.streams | .[]'
{
"index": 2,
...cut...
},
"tags": {
"language": "zh-Hans",
"title": "中文(简体)",
"DURATION": "00:23:40.083000000"
}
}
{
"index": 3,
...cut...
},
"tags": {
"language": "zh-Hant",
"title": "中文(繁體)| 繁化姬",
"DURATION": "00:23:40.083000000"
}
}
{
"index": 4,
...cut...
},
"tags": {
"language": "en",
"title": "English",
"DURATION": "00:23:40.083000000"
}
}
{
"index": 5,
...cut...
},
"tags": {
"language": "th",
"title": "ภาษาไทย",
"DURATION": "00:23:40.079000000"
}
}
{
"index": 6,
...cut...
},
"tags": {
"language": "vi",
"title": "Tiếng Việt",
"DURATION": "00:23:40.039000000"
}
}
{
"index": 7,
...cut...
},
"tags": {
"language": "id",
"title": "Bahasa Indonesia",
"DURATION": "00:23:40.079000000"
}
}
{
"index": 8,
...cut...
},
"tags": {
"language": "ms",
"title": "Bahasa Melayu",
"DURATION": "00:23:40.080000000"
}
}
现在我想要英文子流,所以我认为我需要子流 4:
$ ffmpeg -i "$inputfile" -to 00:00:10 -vf "subtitles=$(printf "%q" "$inputfile"):si=4" out.mp4
但是,这给我带来了一种我无法阅读(或识别)的子语言。尝试了不同的索引后,索引 2 让我得到了英语流:
$ ffmpeg -i "$inputfile" -to 00:00:10 -vf "subtitles=$(printf "%q" "$inputfile"):si=2" out.mp4
我想在脚本中完成所有这些操作,并使用 ffprobe 中的索引来获取正确的流:
$ ffprobe -v quiet -print_format json -show_streams -select_streams s "$inputfile" | jq -r '.streams | .[] | select(.tags.language=="en") | .index'
4
为什么它们不匹配?有没有更好的方法来获取正确的索引?可能总是少 2 个吗?
任何帮助将不胜感激。
//ffmpeg版本信息:
$ ffmpeg -version
ffmpeg version 4.2.7-0ubuntu0.1 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 9 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
configuration: --prefix=/usr --extra-version=0ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
答案1
您的英文字幕流是:
- 文件的第 5 个流(因此索引为 4)(绝对位置)
- 文件中的第三个字幕流(因此索引为 2)(相对位置)
因此存在歧义...subtitles
过滤器需要相对位置。分两步可以更简单:
ffmpeg -i "$inputfile" -map 0:s:language:en -c copy sub.mkv
ffmpeg -i "$inputfile" -vf "subtitles=sub.mkv" "$outputfile"
第一个 ffmpeg 只会保留英文字幕流并将其放入sub.mkv
。然后第二个不必关心索引。