我学习了如何使用 HEVC (x265) 视频编码将 MKV 视频转码为 MP4,以使文件更小,使其与 iOS 兼容。但是,虽然这个过程很棒——而且文件大小很小,压缩也很好——当我尝试将字幕合并到一个特定的视频中时,生成的 MP4 视频我会从 FFmpeg 中得到一堆错误,如下所示:
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3152805999 / timestamp: 3154741000 is out of range for mov/mp4 format
我正在使用 macOS Mojave (10.15.2) 和通过 Homebrew 安装的 FFmpeg 4.2.1,但即使我下载夜间构建(ffmpeg-4.2.1-macos64-static, 20191215-9fe0790) 并改用该二进制文件,问题仍然存在Homebrew 安装版本。
问题是我有这个视频,我过去已成功转换为带有 x264 视频和 AAC 音频的 MP4,并且能够毫无问题地将 SRT 字幕合并到生成的文件中。但是,当我今天使用 HEVC (x265) 视频从相同的确切来源创建 MP4 时,SRT 字幕合并失败,出现“pts 没有价值”和“超出 mov/mp4 格式的范围”错误。
这是我用来从 MKV 源创建 HEVC (x265) MP4 视频的命令:
ffmpeg -i input.mkv \
-map_metadata -1 \
-vf scale=-1:720 \
-c:v libx265 -crf 20 -c:a aac -b:a 128k \
-threads 4 \
-tag:v hvc1 -sn \
-map 0:0 -map 0:1 output_hevc.mp4 \
;
这是过去成功用于将 SRT 字幕合并到现有 MP4 中而无需重新编码的命令:
ffmpeg -i output_hevc.mp4 \
-i input.srt \
-c:v copy -c:a copy \
-c:s mov_text -metadata:s:s:0 language=eng \
output_final.mp4 \
;
我认为问题可能在于大约 50% 的视频没有字幕;只有在第二个 50% 的视频中需要字幕。
有问题的视频长约2小时。并且在前 50 分钟左右,不需要英文字幕。但大约 50 分钟后,字幕开始播放。
所以 SRT 中的字幕是这样开始的:
1
00:52:33,123 --> 00:52:50,123
It was a dark and stormy night…
但是当我运行上面的 FFmpeg 命令时,输出是这样的;有时有点捏造例如的目的:
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Stream #1:0 -> #0:2 (subrip (srt) -> mov_text (native))
Press [q] to stop, [?] for help
frame=25560 fps=0.0 q=-1.0 size= 304640kB time=00:52:00.00 bitrate= 791.7kbits/frame=50730 fps=50726 q=-1.0 size= 681984kB time=time=00:52:00.00 bitrate=1772.4kbit[mp4 @ 0x7facb9002000] Application provided duration: 3152137000 / timestamp: 3152137000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3152805999 / timestamp: 3154741000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3153246998 / timestamp: 3156809000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3154051997 / timestamp: 3159013000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3155556996 / timestamp: 3163817000 is out of range for mov/mp4 format
还有大量类似的信息,直到,等等!合并结束,没有字幕是可见的,就是这样。
这让我发疯!我的意思是,如果我使用相同的命令,但指定从字幕出现的时间点开始的搜索时间,我实际上会在需要它们的视频的 50% 上看到字幕:
ffmpeg -I output_hevc.mp4 \
-i input.srt \
-c:v copy -c:a copy \
-c:s mov_text -metadata:s:s:0 language=eng \
-ss 3120 \
output_final.mp4 \
;
但我当然需要超过 50% 的视频。哎呀,我什至只是尝试了这个命令;如果我将搜索设置为等于或大于 1005 秒的任何值,我可以让字幕与 MP4 合并:
ffmpeg -i output_hevc.mp4 \
-i input.srt \
-c:v copy -c:a copy \
-c:s mov_text -metadata:s:s:0 language=eng \
-ss 1005 \
output_final.mp4 \
;
但是在这种情况下,16.75 分钟(1005 秒)有什么神奇之处呢?
如果我只选择字幕出现在视频的第二个 50% 中的时间,但如果我运行命令合并完整视频,为什么我可以合并字幕?
FWIW,如果我运行类似的命令来创建视频的 MKV,一切都很好!
ffmpeg -i output_hevc.mp4 \
-i input.srt \
-c:v copy -c:a copy -c:s copy \
output.mkv \
;
只是不知何故,这种合并mov_text
似乎使过程失败。
如果我在文件开头添加一个虚假的字幕,如下所示:
0
00:00:00,000 --> 00:16:75,000
Foo!
1
00:52:33,123 --> 00:52:50,123
It was a dark and stormy night…
一切都按预期工作!除了有“Foo!”这个词 显示 50% 的视频。显然不理想。
有没有办法解决?这是一个 FFmpeg 错误,还是 HEVC (x265) 视频与字幕合并的问题?
似乎在 SRT 文件的开头添加了一个伪造的字幕,该字幕从视频的开头到字幕开始的位置解决了这个问题。
这个解决方案显然是一个“黑客”,但它确实有效。
摆脱了在 SRT 文件开头添加虚假字幕的想法,我意识到 SRT 字幕(根据SRT 规范)允许使用 HTML 标记。知道我添加了以下虚假字幕并且一切正常!
而已!只需添加一个空的粗体标签就可以让它全部工作并合并字幕......
但是——正如一开始所说的——这显然是一个 hack,我愿意从其他更了解 FFmpeg 的人那里听到更多信息。我只能假设这个问题没有一个反映期望的行为,并且必须有一种更优雅的方式来处理这样的情况。或者这是一个错误(不是功能)并且应该报告?