Вопрос или проблема
Для того чтобы объединить (с использованием демультиплексора) видеофайлы с одинаковой частотой кадров, кодеком, шириной и высотой, базой времени (на самом деле некоторые из них являются сегментами одного и того же видеофайла), был использован подход с демультиплексором concat ffmpeg (чтобы избежать повторного кодирования). Проблемы, с которыми столкнулись:
-
Демультиплексор 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 объединить кадры, временные метки которых указаны в текстовом файле ввода демультиплексора?
-
При попытке объединить другую часть из того же входного файла, то есть добавив второй набор 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?
-
Также было замечено, что в то время как входное видео имело битрейт 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 для входного видеофайла]
-
Запрос по значениям 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 для определения границ между сегментами.
Следуя этим шагам, вы сможете избежать проблем с временными метками, сохранять параметры кодека и успешно конкатенировать ваши видеофайлы без повторного кодирования.