FFmpeg розділить відео і об'єднається назад


8

Я намагаюся використовувати FFmpeg, щоб розділити відео на основі деяких start_timeта end_timeвхідних даних і замінити їх на інші відеофайли. Наприклад, для введення 10 15мені потрібно буде замінити ТОЧНІ секунди 10 to 15на інше відео.

ДОБРЕ. Що мені спадає на думку:

  1. Спочатку розділіть відео (у цьому випадку 0-10, 10-15 та 15-кінці)
  2. Замініть 10-15 на інше відео
  3. Об’єднайте всі під-відеозаписи назад

Перше питання: це найкраще і найшвидше рішення? Чи є у нас простіші команди чи інші інструменти для заміни певного періоду часу на відео іншим відео?

Друге питання: якщо припустити, що FFmpeg - це життєздатне рішення, коли я просто використовую команду ffmpeg -I input.video -ss 10 -t 5 -c copy output.mp4, мій код обробки відео не може читати та обробляти файл. Я використовував mediainfoінструмент для порівняння двох файлів і помітив відмінності в розмірах заголовків, в той час як усі матеріали, пов’язані з кодеком, були однаковими. Я помітив, що розмір HEADER відрізняється, що, очевидно, викликає проблему. Чи є способи змусити розмір заголовка також (окрім кодеків) бути однаковим?

ОНОВЛЕННЯ: Ось оригінальний .mp4файл, який добре працює в емуляторі.


Спершу нам доведеться розібратися з проблемою, яку ви згадуєте у своєму другому запитанні. Будь ласка, покажіть точну команду, яку ви використовуєте, і повний нерозрізаний вихідний командний рядок, який ви отримуєте від ffmpeg. Також покажіть будь-які фактичні помилки, які ви отримуєте під час читання файлу - було б добре точно знати, який саме ваш "код обробки".
slhck

@slhck код обробки відео - це величезна база коду. Я не можу цим поділитися. Просто з деяких причин оригінальний файл читається, а не повторно генерується. Однак я можу поділитися оригінальним .mp4файлом, якщо потрібно.
Аріана

Я використав інструмент mediainfo, щоб порівняти два файли та помітити відмінності у розмірах та заголовку
Ariana

Наявність оригіналу допомогло б, але ми не зможемо усунути проблеми, чому його не можна прочитати, боюся, якщо це якийсь внутрішній код.
slhck

@slhck Я завантажив файл. Моє запитання оновлено
Ariana

Відповіді:


9

Використання trimта concat- вихідні файли з різними кодеками

Для цього переконайтесь, що ваші окремі файли мають однакову роздільну здатність, а в ідеалі - однакову частоту кадрів та кольорову підсистему тощо. Це дозволить уникнути помилок чи збоїв під час конкатенації.

Ви можете зробити все за один раз, не розбиваючи файл, використовуючи trimі concatфільтри:

ffmpeg -i edv_g24.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[v0][v1][v2]concat=n=3:v=1:a=0[out]" \
-map "[out]" output.mp4

Тут trimвикористовується для вказівки окремих частин вхідних відеопотоків ( 0:v, 1:v), які згодом потрібно об'єднати. Ці частини названі v0наскрізь v2. ( setptsФільтр скидає часові позначки цих окремих частин до 0, що потрібно для конкатенації). Пізніше ми об'єднуємо три частини.

Якщо ви хочете обрізати від певної часової позначки до кінця, використовуйте trim=start=15замість того, щоб вказати діапазон.

Якщо у ваших файлах є аудіо, ви повинні обрізати ці потоки окремо:

ffmpeg -i edv_g24_2.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[1:a]atrim=0:5,asetpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; \
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4

Зверніть увагу, що в цьому випадку відео та аудіо будуть перекодовані - обов’язково вкажіть відповідні цілі якості виводу (наприклад, -crfдля x264, x265 або libvpx-vp9). Докладніше про це можна прочитати на FFmpeg Wiki, наприклад, для VP9 або H.264 .

Використання окремих сегментів

Якщо ви хочете розділити кліпи та пізніше зібрати їх:

ffmpeg -i edv_g24.mp4 -ss 0 -to 10 -c copy part1.mp4
ffmpeg -i edv_g24.mp4 -ss 10 -to 15 -c copy part2.mp4
ffmpeg -i edv_g24.mp4 -ss 15 -c copy part3.mp4

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][1:v][2:v]concat=n=3:v=1:a=0[outv]" \
-map "[outv]" -t 30 output.mp4

Якщо у файлах є аудіо, використовуйте той самий підхід, що і вище:

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -t 30 output.mp4

Це знову перекодує відеопотік. Це трохи простіше, але в іншому випадку має бути еквівалентним вищевказаному методу.

Використання concatдемуксера

В принципі, ви також можете спробувати об'єднати бітові потоки, не перекодуючи їх, використовуючи concat demuxer. Створіть названий файл concat.txtта додайте такі записи (відповідні відеокліпам, створеним вище):

file 'part1.mp4'
file 'short-video.mp4'
file 'part3.mp4'

Потім з'єднайте ці окремі файли:

ffmpeg -f concat -i concat.txt -c copy output.avi

Це вимагає, щоб у ваших кліпів був один і той же кодек, роздільна здатність, частота кадрів тощо - тому він не працює з усіма різновидами гетерогенних джерел.

Використання concatпротоколу

Вищезазначений тип конкатенації на рівні файлів може бути досягнутий і за допомогою concatпротоколу з тими ж обмеженнями, що і вище (той же кодек, роздільна здатність тощо):

ffmpeg -i "concat:part1.avi|part2.avi|part3.avi" -c copy output.mp4

Для отримання додаткової інформації про конкатенацію читайте відповідну сторінку Вікі FFmpeg .


Це виглядає дуже повно! Дякую. Я спробую їх!
Аріана

Ідк, чому за допомогою concatметоду видає помилку:[concat @ 00000000025c2560] Line 1: unknown keyword 'part1.mp4 \\ text.txt: Invalid data found when processing input
Аріана

Для "використання окремих сегментів" я бачу зупинку і невеликий виріз виводу. Чи є способи це виправити?
Аріана

Спосіб 1 прекрасно працює. Одне: як ми можемо вказати "до кінця" без зазначення конкретного числа (замість 30 с)
Аріана

1
Вибачте, помилився. Для concatдемуксера синтаксис був іншим. Виправлено зараз. Щоб дійти до кінця, скористайтеся trim=start=15, перегляньте документацію по фільтру обрізки: ffmpeg.org/ffmpeg-filters.html#trim - що стосується проблем із тимчасовим враженням , це дійсно залежить від вашого вихідного матеріалу. У вас не було проблем, пов’язаних із завантаженим кліпом.
slhck
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.