Повтор / цикл ввода видео с помощью 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

... но я получаю сообщение об ошибке "Option loop not found."

Томас Кинг
источник
Используйте quicktime 7 pro и mov контейнер. Таким образом, вы не получите больший размер файла, чем с открытым исходным кодом.
Дмитрий Мышков

Ответы:

70

Concat demuxer

Это позволяет зациклить вход без необходимости перекодирования.

  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.

фильтр фильма

Фильтр фильм имеет вариант цикла. Смотрите ответ ниже Монах Тук. Фильтрация требует перекодирования. Для аудио используйте фильтр amovie.


-stream_loop вариант

Смотрите ответ ниже Thingy и ответ Gyan.

Обратите внимание, что этот параметр был ошибочным (см. Отчеты об ошибках # 5719 , # 6121 и # 7043 ), поэтому он может не работать для старых сборок (что-либо старше, чем версия 201-27 06-27, включая ветку релиза FFmpeg 4.0.x). Для пользователей старых сборок, как упомянуто mulvya в билете # 6121, одним из обходных путей является сначала повторное мультиплексирование в MKV или TS, а затем использование -stream_loopв следующей команде.


-loop вариант

Эта -loopопция специфична для демультиплексора файлов изображений и мультиплексора gif , поэтому ее нельзя использовать для обычных видеофайлов, но ее можно использовать для бесконечного зацикливания серии входных изображений. Этот пример будет повторяться снова и снова, но -t 30будет ограничивать продолжительность вывода до 30 секунд:

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

Или зациклить вывод GIF:

ffmpeg -i input -loop 3 output.gif
llogan
источник
Это нормально работает с файлами 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 <(для i в {1..4}; сделать printf "file '$ PWD' / '% s' \ n" input.mp4; done ) -c копия output.mp4
Пленус Франкли
1
Что касается меня, это работает, чтобы повторять видео на полную ставку, не пропуская славы 4 разаffmpeg -i video.mp4 -filter_complex "loop=4:32767" output.mp4
Влад
Этому выпуску 4 года, и никто не заметил, что ссылка на второй выпуск в -stream_loopразделе указывает на тот же билет, что и первый ...
Леонид Усов
15

По крайней мере , на FFmpeg 2.8.x (но старичок должен тоже работает) , вы можете использовать в 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 перед вводом, эта ошибка исчезнет, ​​но кодер не выйдет. Предоставление ненулевого числа циклов приводит к множеству ошибок, но завершается. Файл не является допустимым выводом.
Гьян
1
Документация для stream_loop гласит: «Цикл 0 означает отсутствие цикла, цикл -1 означает бесконечный цикл».
Гьян
Кажется, неверные входные файлы. Не могли бы вы поделиться им? «Цикл 0 означает отсутствие цикла, цикл -1 означает бесконечный цикл». - кажется, я вижу старые документы :-)
Монах Тук
1
Я забыл: фильтры, предполагающие транскодирование (декодирование / кодирование). По дизайну. Так что вы должны удалить -c copy. Ответ исправлен.
Монах Тук
1
Приятно знать, но это существенное ограничение, если у вас есть большой цикл для генерации.
Гьян
14

В ffmpeg 2.8.4 следующая команда создает output.mp4, который является повторяющейся копией input.mp4 до тех пор, пока процесс ffmpeg не будет остановлен:

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

Эта команда не завершится сама по себе, и выходной файл будет расти бесконечно.

Thingy
источник
2
Кажется, самый быстрый способ
йозеф
2
Самый быстрый метод - это преуменьшение, этот метод увеличивает количество часов до нескольких часов за несколько секунд.
SleighBoy
Это очень удобный метод, потому что нет необходимости создавать файл с повторяющимися строками.
Маркус Зеллер
-1

Q: "... как я могу изменить следующую командную строку, чтобы сделать это? Ffmpeg -i input.mp4 -c copy output.mp4"?

О: Простой метод, позволяющий избежать проблем, с которыми работают Команды, с какой версией является «тривиальным решением»:

ffmpeg -i input.mp4 -i input.mp4 -i input.mp4 -i input.mp4 -c копировать output.mp4

Смотрите также: https://trac.ffmpeg.org/wiki/Concatenate для многих примеров.

обкрадывать
источник
2
Это не делает никакой конкатенации. Необходимо использовать хотя бы один из методов concat: протокол, фильтр или демультиплексор. В этой команде автоматическое отображение ffmpeg выберет одно видео, один аудио и один поток субтитров среди входов. Поскольку они идентичны, это эквивалентно первой команде ОП.
Гьян
Спасибо за тестирование этого Mulvya, так как оно отличается от поведения, описанного в Документах: ffmpeg.org/ffmpeg.html#Description - Если есть сходство в именах файлов с использованием "-i -i /tmp/test%d.mp4" ( и др. al) также возможно.
Роб