Как создать совместимое видео AVC для мультиплексирования без повторного кодирования

Я хочу закодировать видео, которое будет совместимо с видео, созданными на моем телефоне. Таким образом, я могу мультиплексировать новое видео с оригиналом без повторного кодирования исходного видео. Я использую FFmpeg с кодировщиком libx264 . Ниже приведены характеристики MediaInfo исходного видео, созданного моим телефоном:

ID                                       : 1
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : Baseline@L3.1
Format settings                          : 1 Ref Frames
Format settings, CABAC                   : No
Format settings, Reference frames        : 1 frame
Format settings, GOP                     : M=1, N=30
Codec ID                                 : avc1
Codec ID/Info                            : Advanced Video Coding
Duration                                 : 52 s 369 ms
Bit rate                                 : 10.0 Mb/s
Width                                    : 1 280 pixels
Height                                   : 720 pixels
Display aspect ratio                     : 16:9
Frame rate mode                          : Variable
Frame rate                               : 30.000 FPS
Minimum frame rate                       : 29.625 FPS
Maximum frame rate                       : 30.405 FPS
Standard                                 : NTSC
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive
Bits/(Pixel*Frame)                       : 0.362
Stream size                              : 62.4 MiB (98%)
Title                                    : VideoHandle
Language                                 : English
Encoded date                             : UTC 2020-10-27 19:43:55
Tagged date                              : UTC 2020-10-27 19:43:55
Color range                              : Limited
Color primaries                          : BT.709
Transfer characteristics                 : BT.709
transfer_characteristics_Original        : BT.601
Matrix coefficients                      : BT.709
mdhd_Duration                            : 52369
Codec configuration box                  : avcC

До сих пор я выяснил следующее, что, я думаю, приблизило меня:

ffmpeg -i in.mp4 -c:v libx264 -profile:v baseline -level:v 3.1 -refs 1 \
  -vsync 2 -filter:v scale="-1:720",pad="1280:720:720/2+ow/2",format="yuv420p" \
  -x264-params keyint="30":scenecut="0" -c:a copy out.mp4

У меня проблемы с установкой частоты кадров. Он должен быть переменным при 30 кадрах в секунду. Я нашел этот вопрос в отношении переменной частоты кадров. Но на него нет ответа. Установка -minrate& -maxrateне помогает. На выходе получается постоянная частота кадров при 30 FPS. Ниже приведены примеры параметров.

  • Выводит постоянную скорость при 30 кадрах в секунду:
    -vsync 2 -r 30 -minrate 29.625 -maxrate 30.405
    
  • Выводит переменную скорость @ 29,970:
    -vsync 2 -r 30.405
    

Я также считаю, что должен использовать -crfили -qp, но не уверен в правильности значений.

Редактировать:

Команда, показанная выше, приводит к следующим спецификациям:

ID                                       : 1
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : Baseline@L3.1
Format settings                          : 1 Ref Frames
Format settings, CABAC                   : No
Format settings, Reference frames        : 1 frame
Format settings, GOP                     : M=1, N=30
Codec ID                                 : avc1
Codec ID/Info                            : Advanced Video Coding
Duration                                 : 8 s 700 ms
Duration_FirstFrame                      : 33 ms
Bit rate                                 : 2 606 kb/s
Width                                    : 1 280 pixels
Height                                   : 720 pixels
Display aspect ratio                     : 16:9
Frame rate mode                          : Constant
Frame rate                               : 30.000 FPS
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive
Bits/(Pixel*Frame)                       : 0.094
Stream size                              : 2.69 MiB (95%)
Title                                    : VideoHandle
Writing library                          : x264 core 160
Encoding settings                        : cabac=0 / ref=1 / deblock=1:0:0 / analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=0 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=6 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=30 / keyint_min=3 / scenecut=0 / intra_refresh=0 / rc_lookahead=30 / rc=crf / mbtree=1 / crf=23.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00
Language                                 : English
Codec configuration box                  : avcC

Есть ли здесь что-то еще, что не совместимо с оригинальным видео?


Источники, которые мне помогли:

Редактировать (2020-11-6 23:40 UTC):

Прочитав ответ Гьяна , я использовал -video_track_timescaleпараметр, чтобы установить tbnзначение, соответствующее исходному видео. Но объединенное видео по-прежнему отображается некорректно. Я пропустил что-то, что должно совпадать? Сейчас просматриваю ffprobeвывод.

Оригинальное видео:

$ ffprobe -hide_banner -i VID_20201027_124301.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'VID_20201027_124301.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2020-10-27T19:43:55.000000Z
    location        : +42.5418-122.5700/
    location-eng    : +42.5418-122.5700/
    com.android.version: 7.1.2
  Duration: 00:00:52.40, start: 0.000000, bitrate: 10187 kb/s
    Stream #0:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1280x720, 10002 kb/s, SAR 1:1 DAR 16:9, 30 fps, 30 tbr, 90k tbn, 180k tbc (default)
    Metadata:
      creation_time   : 2020-10-27T19:43:55.000000Z
      handler_name    : VideoHandle
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2020-10-27T19:43:55.000000Z
      handler_name    : SoundHandle

Видео в кодировке FFmpeg:

$ ffprobe -hide_banner -i VID_20201027_124914-encoded.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'VID_20201027_124914-encoded.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.29.100
  Duration: 00:00:08.70, start: 0.000000, bitrate: 2732 kb/s
    Stream #0:0(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 2596 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
    Metadata:
      handler_name    : VideoHandle
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandle

Редактировать (2020-11-7 00:05 UTC):

Провел еще несколько тестов и обнаружил, что когда я объединяю видео с помощью FFmpeg, оно работает. Но если я объединяю с помощью другого мультиплексора, например, Avidemux или MKVToolNix , этого не происходит. Я думаю, что Gyan ответил на этот вопрос, но я собираюсь оставить его открытым еще немного, чтобы посмотреть, есть ли какие-либо сведения о том, почему видео не работает с другими мультиплексорами, поскольку я предпочитаю использовать их.

Используемые конечные параметры ffmpeg:

ffmpeg -i in.mp4 -c:v libx264 -profile:v baseline -level:v 3.1 \
  -refs 1 -r 30 -video_track_timescale 90k \
  -filter:v scale="-1:720",pad="1280:720:720/2+ow/2",format="yuv420p" \
  -x264-params keyint="30":scenecut="0" -c:a copy out.mp4

параметры keyint и scenecut -x264-params и частота кадров не требуются

Редактировать:

Создан вопрос о том, что конкатенация не работает с Avidemux и MKVToolNix здесь .

Ответы (1)

Чтобы объединить несколько файлов для ожидаемого воспроизведения в обычных проигрывателях, следующие свойства должны совпадать:

видео: кодек, профиль кодека, уровень кодека, разрешение, количество ссылок, формат пикселей, временная шкала /временная шкала.
аудио: кодек, профиль кодека, количество и расположение каналов, формат и частота дискретизации.

Продвинутые игроки могут допустить промежуточные изменения некоторых из вышеперечисленных параметров.

Mediainfo не покажет вам шкалу времени, это значение tbn, показанное ffmpeg для потока. Частота кадров не обязательно должна совпадать или быть постоянной для любого данного составного потока. Размер GOP или частота ключевых кадров могут не совпадать. Ни значение битрейта, ни режим (CRF, VBR и т. д.) не должны совпадать. minrateи maxrateзажимать битрейт, а не частоту кадров.

Хорошо, ffmpeg показывает 30 fps, 30 tbr, 90k tbn, 180k tbcвидео, созданное моим телефоном. Я использовал -video_track_timescale 90kвариант, и выходное видео показывает 29.89 fps, 30 tbr, 90k tbn, 60 tbc. Но объединенное видео по-прежнему не отображается правильно ни в VLC, ни в MPlayer. Все остальное, что вы описали, совпадает. Тоже tbcдолжно совпадать?
Я обновил свой вопрос, чтобы показать ffprobeрезультат двух видео.
Новая информация: после вашего ответа объединение с FFmpeg работает. Спасибо. Однако, если я использую другую утилиту для мультиплексирования, такую ​​как Avidemux или MKVToolNix , объединенное видео отображается неправильно. Любая идея, почему это может быть?
Уровень кодека по-прежнему соответствует действительности? Я смог использовать concatдемультиплексор для объединения двух видео, в которых все совпадало, кроме уровня кодека (и SAR/DAR).
Строго говоря, чтобы избежать сбоев в работе декодеров с аппаратными ограничениями, уровень и профиль последующих файлов не должны превышать уровень и профиль первого файла.