У меня есть приложение для конференций WebRTC, которое записывает видео пользователя и выдает из него mp4
.
Я использую кодек h264 и сначала создаю файл mkv
напрямую, используя для этого ffmpeg и оболочку Java (https://github.com/bytedeco/javacpp).
Выход mkv
воспроизводится правильно с использованием VLC, но вообще не воспроизводится в OSX QuickTime. Я пытаюсь конвертировать в MP4, чтобы он нормально работал в OSX. Я пытаюсь избежать перекодирования, поскольку я не слишком медленный процесс, и у меня уже есть видео-пакеты encodec h264, поэтому в этом нет необходимости.
У меня есть очень простой пример файла, который представляет собой видео из 30 кадров, где 1 - это ключевой кадр (I-кадр), а остальные - это P-кадры.
Когда я пытаюсь конвертировать mkv
в mp4
, используя такую команду:
ffmpeg -i input.mkv -vcodec copy output.mp4
Он открывается в QuickTime, но не показывает содержимого (черная рамка, без ошибок)
Когда я перекодирую свой mkv
в тот же формат и профиль с помощью ffmpeg:
ffmpeg -i output.mkv -profile:v baseline output-reencoded.mkv
И снова преобразовать его в mp4:
ffmpeg -i input-reencoded.mkv -vcodec copy output-reencoded.mp4
РАБОТАЕТ. Но это перекодирование, и для больших файлов это занимает много времени.
Я пытаюсь сравнить разницу между моим источником mkv
и источником, обработанным ffmpeg. Первая заметная разница - tbc
(это база времени для кодека ):
$ 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 самостоятельно.