使用ffmpeg从MP4视频中提取SubRip (SRT)字幕是否可行?

13

我已经查看了FFMpeg文档和许多论坛,并找到正确的命令行来从.MP4视频中提取字幕,应该是这样的:

ffmpeg -i video.mp4 -vn -an -codec:s:0 srt out.srt

然而,我遇到了以下错误,这让我怀疑这是否可行:

Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

使用ffmpeg -codecs,我可以确认ffmpeg应该能够编码subrip字幕。

使用ffmpeg -i video.mp4,我可以看到视频中嵌入了两个字幕轨道:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.mp4':
...
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 720x572 [SAR 64:45 DAR 256:143], 1341 kb/s, 25 fps, 25 tbr, 90k tbn, 180k tbc
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 191 kb/s
Stream #0:2(fra): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 191 kb/s
Stream #0:3(eng): Subtitle: dvd_subtitle (mp4s / 0x7334706D)
Stream #0:4(und): Subtitle: mov_text (text / 0x74786574)

编辑

我已经尝试了在评论中给出的简化命令行,但仍然遇到相同的错误。在此处提供详细的详细输出链接以便查看运行该命令所产生的详细信息。我还尝试完全禁用结果输出中的元数据和章节,但仍然会产生相同的错误。


3
对我来说,简单的 ffmpeg -i in.mp4 out.srt 命令可以正确地工作。(ffmpeg 版本为 2.0.1) - pogorskiy
尝试使用 ffmpeg ... -loglevel debug ... 获取有关错误的更多信息。 - pogorskiy
我尝试了两个建议,但是我无法找出明显的错误。也许这是由于ffmpeg试图在生成的srt文件中输出章节标记所致?我已经包含了详细的调试输出。 - Maxime Labelle
1
看起来没有明显的问题,但是也许可以尝试从http://ffmpeg.org/download.html下载更近期的版本,并使用`ffmpeg -i video.mp4 -map 0:s:0 output.srt`只使用第一个字幕流进行输出。(顺便说一下,关于ffmpeg CLI的问题不适合在SO上讨论,所以我已经投票将其移动到[SU]。) - slhck
抱歉我的帖子有些离题。我会确保在SU中提出那些问题。我会尝试更近期的ffmpeg版本。谢谢。 - Maxime Labelle
请在回复用户时使用@符号(例如@slhck),否则他们将无法收到回复。另外,请不要在Super User上重新提问您的问题。只需等待-一旦有足够的人投票支持,它就会自动迁移。谢谢。 - slhck
4个回答

24

我最终明白了为什么没有成功:

如果源视频的字幕采用基于文本的编码表示,那么指定的命令行就可以完美地使用。然而,正如在ffmpeg -i命令行输出中所看到的那样,这些字幕是用"dvd_subtitle"格式进行编码的。

dvd_subtitle格式将每个字幕都存储为位图。因此,ffmpeg无法将这些位图翻译成文本。

对于这个任务,必须借助基于OCR的软件来帮助用户从位图表示中识别出每个字幕并将其转化为文本。

(源视频中还有一个次要的基于文本的字幕,但我不知道它来自哪里,并且大多数流行播放器都看不到它。就所有意图和目的而言,这个"mov_text"字幕似乎只是一个存根占位符,可能是从原始DVD转换时的副产品)


我认为文本轨道是章节标记,但不确定。 - mcdado

5
只是提醒一下,(由于声誉尚未评论),但从MP4中提取SRT将导致文件格式为MOV_Text而不是常规的SRT。它仍然会被添加并正常工作,但这就像将mp4更改为m4v。虽然通常可以使用,但在代码中工作方式不同。Mov_text非常难以手动调整字体/大小等等。最好的方法是从网上下载并测试SRT!这将起作用,但会导致mov_text编码的srt文件:
ffmpeg -i in.mp4 out.srt

1
您可以通过指定-c:s text来删除导致格式混乱的字体标签,例如:ffmpeg -i in.mp4 -map 0:4 -c:s text out.4.srt - jerblack

3

如果输入文件中有太多的流,请尝试使用映射选项...

语法如下:

ffmpeg -i video.mp4 -map 0:4 out.srt

由于您的视频中有两个字幕流,第一个在0:3上是dvdsubtitle格式,无法转换为srt格式,因此我们将转换第二个字幕流,即0:4上的mov_text格式,它是软字幕,可以轻松转换...


0
一直在测试FFmpeg视频srt提取(在Linux上)。 你能相信某个mkv视频有40个srt字幕吗?
将FFmpeg和Linux bash的一些东西结合起来,我想出了这个方法,以便将所有的字幕都分别提取为srt文件:
    echo "Video(s) to extract subs from?"
    echo "(with extension, specific or wildcard, e.g.: *.mkv, *.mp4)" 
    
    read -e -i "*.???" -p "" VID_IN

echo

echo "Just a moment..."
    
    for cnt in {2..10} # loops through nrs 2 to 10. Subtitles often start at '-map 0:2' (if there is 1 video en 1 audio in the vidcontainer!)
    do
    
    for i in ${VID_IN}; do ffmpeg -txt_format text -i "$i" -map 0:${cnt} "${i%.*}_Track${cnt}_subtitle.srt" 2> /dev/null; done
    
    done

echo

echo -e "Ready.
Subtitles extracted."

别问我在哪里看到“-txt_format text”。不确定是否真的必要。我知道如果你使用它,你必须将其放在“-i”选项之前。 我的代码从第二个映射开始计数,srt文件以映射的计数号作为文件名“Track”-数字。 视频、电影字幕并不总是指定语言('und')。因此需要有轨道编号。 你可以使计数的数量变小或者变大。当然,变大会花费更长的时间。如果你有一个几乎包含任何语言字幕的视频,你就需要选择较大的计数值;) “2> /dev/null”抑制了FFmpeg的错误。 其他字幕格式?待定。可以保存(甚至转换?..)为srt格式。之后可以重新命名。 还有其他方法,但对于多个srt轨道,这对我来说是有效的。已在mp4和mkv文件上进行了测试。结果相同。
再见。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接