Повторити / циклічне введення відео з 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.