我有一个WebRTC会议应用程序,它正在记录用户的视频供稿并从中产生一个mp4
。
我正在使用h264编解码器,首先是直接使用ffmpeg和Java包装器(https://github.com/bytedeco/javacpp)直接生成mkv
文件。
使用VLC可以正确播放输出mkv
,但在OSX QuickTime中根本无法播放。我正在尝试转换为MP4,以使其在OSX中正常工作。我正在尝试避免重新编码,因为我的过程不是很慢,而且我已经有了编码H264视频数据包,因此不需要它。
我有一个非常基本的示例文件,它只是一个30帧的视频,其中第一个是关键帧(I帧),其余的是P帧。
当我尝试使用以下命令将mkv
转换为mp4
时:
ffmpeg -i input.mkv -vcodec copy output.mp4
它在QuickTime中打开,但没有显示任何内容(黑框,没有错误)
当我用ffmpeg将mkv
重新编码为相同的格式和配置文件时:
ffmpeg -i output.mkv -profile:v baseline output-reencoded.mkv
然后将其再次转换为mp4:
ffmpeg -i input-reencoded.mkv -vcodec copy output-reencoded.mp4
有效。但是它是重新编码的,对于大文件来说要花一些时间。
我正在尝试比较源mkv
与ffmpeg处理的源之间的区别。第一个值得注意的区别是tbc
(它是timebase for codec):
$ ffprobe -hide_banner input.mkv
Input #0, matroska,webm, from 'input.mkv':
Metadata:
ENCODER : Lavf58.12.100
Duration: 00:00:00.75, start: 0.000000, bitrate: 228 kb/s
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 1920x1080, 40 fps, 40 tbr, 1k tbn, 2k tbc (default)
Metadata:
DURATION : 00:00:00.750000000
$ ffprobe -hide_banner output-reencoded.mkv
Input #0, matroska,webm, from 'output-reencoded.mkv':
Metadata:
ENCODER : Lavf57.83.100
Duration: 00:00:00.75, start: 0.000000, bitrate: 209 kb/s
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 1920x1080, 40 fps, 40 tbr, 1k tbn, 80 tbc (default)
Metadata:
ENCODER : Lavc57.107.100 libx264
DURATION : 00:00:00.750000000
请注意 tbc 的区别-我的是2k
,而ffmpeg的是80
。
第一个问题是:难道这是QuickTime无法播放的原因吗?
我尝试通过网络上的各种参数“强制”更改此tbc:
ffmpeg -i input.mkv -x264-params timebase=30 -vcodec copy input2.mkv
ffmpeg -i input.mkv -time_base 1/30 -vcodec copy input2.mkv
ffmpeg -i input.mkv -video_track_timescale 30 -vcodec copy input2.mkv
ffmpeg -i input.mkv -video_track_timescale 30 -vcodec copy input2.mkv
没有运气。 output2.mkv
始终与相同的2k tbc
相同。
我也尝试更改帧速率,理论上说ffmpeg的目标是制作80 tbc
,但看起来不是吗?:
$ ffmpeg -i input.mkv -hide_banner -vcodec copy -r 80 input2.mkv
Input #0, matroska,webm, from 'input.mkv':
Metadata:
ENCODER : Lavf58.12.100
Duration: 00:00:00.75, start: 0.000000, bitrate: 228 kb/s
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 1920x1080, 40 fps, 40 tbr, 1k tbn, 2k tbc (default)
Metadata:
DURATION : 00:00:00.750000000
Output #0, matroska, to 'input2.mkv':
Metadata:
encoder : Lavf57.83.100
Stream #0:0: Video: h264 (Constrained Baseline) (H264 / 0x34363248), yuv420p(progressive), 1920x1080, q=2-31, 40 fps, 40 tbr, 1k tbn, 80 tbc (default)
Metadata:
DURATION : 00:00:00.750000000
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame= 30 fps=0.0 q=-1.0 Lsize= 21kB time=00:00:00.72 bitrate= 236.1kbits/s speed=2.58e+03x
video:20kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 4.470772%
$ ffprobe -hide_banner input2.mkv
Input #0, matroska,webm, from 'input2.mkv':
Metadata:
ENCODER : Lavf57.83.100
Duration: 00:00:00.75, start: 0.000000, bitrate: 228 kb/s
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 1920x1080, 40 fps, 40 tbr, 1k tbn, 2k tbc (default)
Metadata:
DURATION : 00:00:00.750000000
也许我只是看错了,而ffprobe
只是在奇怪地计算tbc,但是我找不到这些文件之间的其他差异,而且ffmpeg肯定在做一些“修复” mkv的聪明事。当我自己创建MKV时,我想这样做。