Повторити / циклічне введення відео з ffmpeg?


52

Я просто хочу зафіксувати mp4 на відео з ffmpeg і зберегти поточні налаштування та кодек.

Наприклад, якщо input.mp4 дорівнює 0:10, і я хотів би його циклічити в 4 рази, щоб output.mp4 був 0:40, як я можу змінити наступний командний рядок, щоб це зробити?

ffmpeg -i input.mp4 -c copy output.mp4

Я намагався...

ffmpeg -loop 4 -i input.mp4 -c copy output.mp4

... але я отримую помилку "Опція циклу не знайдена."


Використовуйте quicktime 7 pro та mov контейнер. Таким чином, ви не отримаєте більший розмір файлу, ніж з відкритим.
Дмитрій Мышков

Відповіді:


69

Конкомат деміксер

Це дозволяє циклічно вводити дані, не потребуючи повторного кодування.

  1. Складіть текстовий файл. Зміст текстового файлу прикладу повторити 4 рази.

    file 'input.mp4'
    file 'input.mp4'
    file 'input.mp4'
    file 'input.mp4'
    
  2. Потім запустіть ffmpeg:

    ffmpeg -f concat -i list.txt -c copy output.mp4
    

Для користувачів Linux

Цей приклад такий же, як вище, але вам не потрібно робити вручну list.txt:

for i in {1..4}; do printf "file '%s'\n" input.mp4 >> list.txt; done
ffmpeg -f concat -i list.txt -c copy output.mp4

З найчастіше використовуваними сучасними оболонками ви навіть можете повністю уникнути створення list.txtфайлу. Наприклад, з bash:

ffmpeg -f concat -i <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -c copy output.mp4

Також дивіться:


петлевий фільтр

Приклад, використовуючи циклічний фільтр для циклу 4 рази, кожен цикл - 75 кадрів, кожен цикл пропускає перші 25 кадрів вводу:

ffmpeg -i input -filter_complex loop=loop=3:size=75:start=25 output
  • Або скористайтеся скороченням: loop=3:75:25
  • Для фільтрування потрібно повторне кодування.
  • Цей фільтр поміщає всі кадри в пам'ять .
  • Використання loop=3буде циклічно 4 рази.
  • Для безперервного циклу використовуйте -1.
  • Ви повинні вказати кількість кадрів для циклу (показано як 75 у прикладі вище). Максимальне значення - 32767.
  • Також див ffmpeg -h filter=loop.

фільм фільму

Фільтр фільм має варіант циклу. Дивіться відповідь нижче від Monah Tuk. Для фільтрування потрібно повторне кодування. Для аудіо використовуйте фільтр amovie.


-stream_loop варіант

Дивіться відповідь Thingy нижче та відповідь Gyan.

Зауважте, що цей параметр виявився помилковим (див. Звіти про помилки № 5719 , # 6121 та # 7043 ), тому він може не працювати для старих збірок (нічого старшого, ніж 2018-27, включаючи відділення випуску FFmpeg 4.0.x). Для користувачів старих збірок, про які згадує mulvya в квитку № 6121, один спосіб вирішити спочатку повторне перетворення файлів на MKV або TS, а потім використання -stream_loopв наступній команді.


-loop варіант

Цей -loopпараметр є специфічним для файлу зображень demuxer та gif muxer , тому його не можна використовувати для типових відеофайлів, але він може використовуватися для нескінченного циклу циклу вхідних зображень. Цей приклад буде циклічно повторюватися, але -t 30обмеження тривалості виведення буде обмежено на 30 секунд:

ffmpeg -loop 1 -i %03d.png -t 30 output.mkv

Або для циклічного виходу GIF:

ffmpeg -i input -loop 3 output.gif

Це добре працює з mp4 файлами?
Томас Кінг

3
Я отримую цю помилку> <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -bash: /dev/fd/63: Permission denied
JZ11

1
@jamesfzhang - Я думаю, це тому, що вам потрібен абсолютний шлях до файлу (як пояснено тут: trac.ffmpeg.org/wiki/Concatenate ). Для цього ви можете написати: ffmpeg -safe 0 -f concat -i <(for i in {1..4}; do printf "file '$ PWD' / '% s' \ n" input.mp4; done ) -c copy output.mp4
Plenus Franckly

1
Як на мене, це працює для того, щоб повторювати повний робочий день відео, не пропускаючи фами 4 разиffmpeg -i video.mp4 -filter_complex "loop=4:32767" output.mp4
Влад

Цьому випуску 4 роки, і ніхто не помітив, що посилання на другий випуск у -stream_loopрозділі вказує на той самий квиток, що і на перший ...
Леонід Усов

15

Принаймні, на FFmpeg 2.8.x (але Oldie також повинен працювати) ви можете використовувати lavfiяк вхідний формат, так і складний графік фільтру, використовуючи movieі setptsфільтри як аргумент для -iпараметра.

Наступна команда, яка виконує цю роботу для вас:

ffmpeg -re -f lavfi -i "movie=filename=input.mp4:loop=0, setpts=N/(FRAME_RATE*TB)" output.mp4

Нульові loop=аргументи означають цикл нескінченності. Значення більше нульових множин повторюють підрахунки. setptsфільтри, необхідні для налаштування PTS для другого та наступного повторень, інакше більшість муксерів виходу з ладу при немонотонному збільшенні PTS: цикл не повертає PTS.

Зауважимо, що використання фільтрів, припускаючи, що обхід кадрів без декодування / кодування неможливий: проектні фільтри мають справу лише з декодованими кадрами.

На FFmpeg 2.8.2 введено новий варіант -stream_loopвведення. Спочатку я вважаю, що це працює простіше і дозволяє копіювати вміст без перекодування:

ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -y output.mp4

Але він не перераховує PTS, а вихідний файл неправильний. Якщо ви додали фільтр для фіксації PTS (див. setpts), Його також потрібно видалити -c copy. Тільки біткойн-фільтри можуть мати справу з кодованими пакетами, але немає жодних потокових фільтрів, щоб виправити PTS (див. Https://ffmpeg.org/ffmpeg-bitstream-filters.html )

У будь-якому випадку ffmpeg при другому проході виходить з помилки:

input.mp4: Resource temporarily unavailable

Відома для мене робота : використовувати контейнер для вхідного файлу без обмежень PTS (потоковий контейнер). Один з них, відомий мені, - це MPEG-TS. Отже, ви можете просто перетворити ваш файл MP4 в MPEG-TS:

ffmpeg -i input.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input.ts

І використовуйте наступну команду, щоб скласти файл нескінченності:

ffmpeg -re -stream_loop -1 -i input.ts -c copy -strict -2 -bsf:a aac_adtstoasc -y output.mp4

(фільтри бітових потоків слід використовувати лише за потреби, на моїх зразках це потрібно)

FFmpeg> = 2.8.2 в цьому випадку потрібно.


1
Запуск цієї команди дає мені помилку: "[mp4 @ 00000000053fa1a0] Не вдалося знайти тег для кодека rawvideo у потоці № 0, кодек наразі не підтримується в контейнері". Якщо я додаю -vcodec h264 перед входом, ця помилка зникає, але кодер не виходить. Постачання ненульового підрахунку циклу створює багато помилок, але робить вихід. Файл не є коректним висновком.
Gyan

1
Документація для stream_loop говорить: "Петля 0 означає відсутність циклу, цикл -1 означає нескінченний цикл".
Gyan

Здається, неправильні вхідні файли. Не могли б ви поділитися цим? "Петля 0 означає відсутність циклу, цикл -1 означає нескінченний цикл." - здається, я бачу старі документи :-)
Monah Tuk

1
Я забув: фільтри припускаючи перекодування (декодування / кодування). За конструкцією. Тож треба видалити -c copy. Відповідь фіксована.
Monah Tuk

1
Приємно знати, але це суттєве обмеження, якщо у вас є великий цикл для генерації.
Gyan

14

З ffmpeg 2.8.4 наступна команда створює output.mp4, що є повторюваною копією input.mp4, доки процес ffmpeg не буде зупинений:

ffmpeg -stream_loop -1 -i input.mp4 -c copy output.mp4

Ця команда не припиняється самостійно, і вихідний файл зростатиме нескінченно.


2
Здається, найшвидший метод
Йозеф

2
Найшвидший метод - заниження, цей спосіб за кілька секунд збільшує багатогодинні відеоролики.
SleighBoy

Це чудовий зручний метод, оскільки немає необхідності створювати файл із повторюваними рядками.
Маркус Зеллер

-1

Q: "... як я міг змінити наступний командний рядок, щоб це зробити? Ffmpeg -i input.mp4 -c копія output.mp4"?

Відповідь: Простий метод, який дозволяє уникнути проблем, з якими Команди працюють, з якою версією є "тривіальним рішенням":

ffmpeg -i input.mp4 -i input.mp4 -i input.mp4 -i input.mp4 -c копія вихід.mp4

Дивіться також: https://trac.ffmpeg.org/wiki/Concatenate для багатьох прикладів.


2
Це не робить ніякої конкатенації. Потрібно використовувати хоча б один із методів лаконічності: протокол, фільтр або деміксер. У цій команді автоматичне відображення ffmpeg вибере одне відео, одне аудіо та один потік субтитрів із входів. Оскільки вони однакові, це рівнозначно першій команді ОП.
Gyan

Дякуємо за тестування, що Mulvya відрізняється від поведінки, описаної в Документах: ffmpeg.org/ffmpeg.html#Description - Якщо в іменах файлів є подібність, використовуючи "-i -i /tmp/test%d.mp4" ( та ін.) Можливо також.
Роб
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.