Опции демультиплексора concat ffmpeg, необходимые для обеспечения соблюдения временной метки конца, параметры кодека должны сохраняться такими же, как во входных данных (битрейт, временная база и т.д.)

Вопрос или проблема

Для того чтобы объединить (с использованием демультиплексора) видеофайлы с одинаковой частотой кадров, кодеком, шириной и высотой, базой времени (на самом деле некоторые из них являются сегментами одного и того же видеофайла), был использован подход с демультиплексором concat ffmpeg (чтобы избежать повторного кодирования). Проблемы, с которыми столкнулись:

  1. Демультиплексор concat ffmpeg не учел время выхода, указанное в текстовом файле демультиплексора ввода!

    input.txt (для демультиплексора concat) содержал (входной виде файл назывался numbered.mp4, каждый кадр был пронумерован как 000, 001 и т.д., разрешение h264 high кодирования 640p, длительность 10 секунд, 240 кадров, 24fps файл):

    ffconcat version 1.0
    file 'numbered.mp4'
    inpoint  2.083333
    outpoint 2.166667
    

    (временные метки пятых (кадры pts 49 в видео, это ключевой кадр) до 52-х (кадры pts 51 в видео, неключевой кадр)

    Команда, выполненная (в Windows):

    ffmpeg -f concat -safe 0 -fflags +genpts   -i <input.. txt> -c copy   -video_track_timescale 24  <out..mp4>
    

    Вывод:

    frame=    5 fps=0.0 q=-1.0 Lsize=      28KiB time=00:00:00.12 bitrate=1857.8kbits/s speed=  56x
    

    Как сказано, есть 5 кадров! ffmpeg взял 2 дополнительных кадра из входа!

    Может кто-нибудь поделиться правильными параметрами, которые следует указать команде демультиплексора concat ffmpeg (а также в его текстовом файле ввода демультиплексора), чтобы точно позволить ffmpeg объединить кадры, временные метки которых указаны в текстовом файле ввода демультиплексора?

  2. При попытке объединить другую часть из того же входного файла, то есть добавив второй набор inpoint, outpoint (время inpoint всегда ключевого кадра), даже pts сбились в результирующем выводе!

    Содержимое файла ввода демультиплексора concat (имя входного видеофайла было numbered.mp4):

    ffconcat version 1.0
    file 'numbered.mp4'
    inpoint  0
    outpoint 0.125000
    file 'numbered.mp4'
    inpoint  2.083333
    outpoint 2.166667 
    

    команда выполнена:

    ffmpeg -f concat -safe 0 -fflags +genpts   -i <input.. txt> -c copy   -video_track_timescale 24  <out..mp4>
    

    вывод ffprobe (обрезанный):

    key_frame=1, pts=0
    pts_time=0.000000
    key_frame=0, pts=1
    pts_time=0.041667
    key_frame=0, pts=2
    pts_time=0.083333
    key_frame=0, pts=3
    pts_time=0.125000
    key_frame=0, pts=4
    pts_time=0.166667
    key_frame=1, pts=3
    pts_time=0.125000
    key_frame=0, pts=6
    pts_time=0.250000
    key_frame=0, pts=5
    pts_time=0.208333
    key_frame=0, pts=7
    pts_time=0.291667
    key_frame=0, pts=7
    pts_time=0.291667
    

    Показывает, что оба pts и pts_times сбиты (хотя части входного видео находятся на большом расстоянии друг от друга без наложений).

    Может кто-то предоставить точные параметры, которые следует указать команде демультиплексора concat ffmpeg для объединения видео файлов из файла ввода демультиплексора [все с одинаковыми параметрами в этом тесте, на самом деле inpoints из одного файла! ] без возникновения этих проблем с pts?

  3. Также было замечено, что в то время как входное видео имело битрейт 412654 (412.654kbps), команда демультиплексора concat привела к выходному файлу с битрейтом 1318777 (1.318 Mbps), более чем в три раза превышающим битрейт входных видеофайлов.

    Можете ли вы поделиться точными параметрами, которые следует указать команде демультиплексора concat ffmpeg, чтобы сохранить все (почти) параметры кодека такими же, как у входного видео, и только выполнять объединение в соответствии с временными метками секунд.миллисекунд, предоставленными без потери кадров, без добавления каких-либо кадров вне этого диапазона временных меток, без изменения базового времени или частоты кадров?

    Примечание: когда -video_track_timescale 24 не предоставляется в качестве ввода для команды демультиплексора concat, базовое время в результирующем выходном видео было более крупным значением (1000+) вместо базового времени входных файлов 24!

    (когда временные метки Pts сбиты, в команде демультиплексора concat отображались ошибки несоответствия DTS:
    [vost#0:0/copy @ 000002c1b9b41140] Несоответствие DTS; предыдущий: 2, текущий: 1; изменение на 3. Это может привести к некорректным временным меткам в выходном файле..)

    Примечание: цель состоит в том, чтобы использовать демультиплексор concat, чтобы избежать повторного кодирования видео, окончательное использование будет заключаться в том, чтобы объединить некоторые сегменты входного видеофайла с несколькими другими видеофайлами [все с одинаковым fps, разрешением, кодеком, размерами, базой времени, выбрав эти параметры с помощью ffprobe для входного видеофайла]

  4. Запрос по значениям inpoint, outpoint в файле ввода демультиплексора concat ffmpeg:

    Логично ли брать значения pts_time <секунды.миллисекунды>, присутствующие в выводе команды ffprobe, и использовать их в файле ввода демультиплексора ffmpeg concat для значений inpoint/outpoint?

    Причина задавать этот вопрос заключается в том, что эти значения pts_time ffprobe учитывают временные значения кадров, такие как 42 миллисекунды, 41 мс и т.д. в том же файле, поэтому вместо сложных расчетов времён кадров, я подумал о том, чтобы взять эти значения pts_time из вывода команды ffprobe.


Вывод ffprobe входного видеофайла был (уменьшен, тестовый видеофайл был прикреплён):

"codec_name": "h264",
 "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
"profile": "High",
"codec_type": "video",
"codec_tag_string": "avc1",
"codec_tag": "0x31637661",
"width": 640,
"height": 480,
"coded_width": 640,
"coded_height": 480,
"closed_captions": 0,
"film_grain": 0,
"has_b_frames": 2,
"sample_aspect_ratio": "1:1",
"display_aspect_ratio": "4:3",
"pix_fmt": "yuv420p",
"level": 41,
"color_range": "tv",
"color_space": "smpte170m",
"chroma_location": "left",
"field_order": "progressive",
"refs": 1,
"is_avc": "true",
"nal_length_size": "4",
"id": "0x1",
"r_frame_rate": "24/1",
"avg_frame_rate": "24/1",
"time_base": "1/24",
"start_pts": 0,
"start_time": "0.000000",
"duration_ts": 240,
"duration": "10.000000",
"bit_rate": "409628",
"bits_per_raw_sample": "8",
"nb_frames": "240",
"extradata_size": 49,

Ответ или решение

Для достижения оптимальных результатов при конкатенации видеофайлов с использованием демультиплексора FFmpeg, необходимо учесть несколько важных моментов, чтобы гарантировать соблюдение временных меток и сохранение параметров кодека. Вот изучение предложенных вами вопросов и рекомендации по их решению:

1. Уважение временных меток (inpoint/outpoint)

Чтобы гарантировать, что FFmpeg будет правильно учитывать временные метки, необходимо проверить, правильно ли вы задали значения inpoint и outpoint в вашем текстовом файле демультиплексора. Эти значения должны строго соответствовать временным меткам вашего видео. Если FFmpeg игнорирует эти метки, возможно, причина в том, что временные метки должны находиться на ключевых кадрах.

Пример правильного формата input.txt:

ffconcat version 1.0
file 'numbered.mp4'
inpoint 2.083333
outpoint 2.166667

2. Конкатенация нескольких сегментов

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

ffconcat version 1.0
file 'numbered.mp4'
inpoint 0
outpoint 0.125000
file 'numbered.mp4'
inpoint 2.083333
outpoint 2.166667

3. Сохранение параметров кодека

Чтобы сохранить параметры кодека, такие как битрейт (bitrate) и time_base, используйте следующие опции командной строки:

ffmpeg -f concat -safe 0 -fflags +genpts -i input.txt -c copy -video_track_timescale 24 output.mp4

Ваша команда уже верная, но убедитесь, что все файлы, включенные в input.txt, одинаковы по кодеку и параметрам, что позволит избежать проблем с несовместимостью.

4. Ошибки некорректных временных меток

Ошибки, связанные с "Non-monotonic DTS", возникают из-за того, что временные метки в процессе конкатенации обрабатываются некорректно. Это может происходить, если inpoint и outpoint не являются ключевыми кадрами. Убедитесь, что все указанные вами временные точки соответствуют ключевым кадрам в исходных видеофайлах.

5. Использование временных меток из ffprobe

Использование pts_time из выходных данных ffprobe является разумным подходом, поскольку эти временные метки являются точными значениями времени в формате seconds.milliseconds:

ffprobe -show_entries frame=pts_time -of csv=p=0 input.mp4

Заключение

Чтобы корректно конкатенировать видеофайлы с использованием FFmpeg concat demuxer, следуйте этим рекомендациям:

  • Убедитесь, что inpoint и outpoint указывают на ключевые кадры.
  • Поддерживайте единообразие кодека и параметров между всеми видеофайлами.
  • Используйте точные временные метки из ffprobe для определения границ между сегментами.

Следуя этим шагам, вы сможете избежать проблем с временными метками, сохранять параметры кодека и успешно конкатенировать ваши видеофайлы без повторного кодирования.

Оцените материал
Добавить комментарий

Капча загружается...