Объедините одно изображение + один аудиофайл, чтобы сделать одно видео, используя FFmpeg

179

Это должно быть довольно тривиально, но я не могу найти способ заставить его работать.

Я хочу, чтобы FFmpeg взял одно изображение JPEG и аудиофайл в качестве входных данных и сгенерировал видеофайл той же длительности, что и аудиофайл (растягивая неподвижное изображение на всю длительность).

Меня не очень волнует, какой видеокодек используется для вывода, но очень важно, чтобы я мог использовать «копировать» в качестве аудиокодека (т.е. копировать аудиопоток без его перекодирования).

Какова правильная командная строка, которая сделала бы это?

Я старался:

ffmpeg -i image8.jpg -i sound11.amr -acodec copy test.avi

и пробовал много комбинаций с и без -s 640x360, -loop_input, -shortest, -t xxx, -r 0.1(искусственно низкой скоростью передачи кадров в надежде , что видео будет больше) и-f image2

Либо я получаю ошибки, либо получаю видеофайл продолжительностью один кадр.

Я погуглил и нашел дюжину предложенных решений (предположительно по этому же вопросу), ни одно из которых не работает.

Кто-нибудь может предложить рабочую команду и объяснить обоснование этого?

Matteo
источник
Я только что попробовал вашу командную строку, и она работала, как ожидалось. Ваша проблема может быть связана со звуковым форматом. Работает ли транскодирование звука?
Капитан Жираф
Под «как и ожидалось» вы подразумеваете, что итоговое видео имеет ту же продолжительность, что и аудиовход? Вы играли в это? Разве это не один кадр?
Маттео
Формат звука не проблема, транскодирование звука работает
matteo
У меня тоже был порядок выдачи параметров, и это стоило мне часов! Жаль, что такого рода проблемы не рассматриваются в справке. gregoire.org/2009/12/05/fun-with-ffmpeg
Пол Грегуар
2
это лучше, чем выбранный ответ, я экспериментировал, и это быстро, а размер файла небольшой ..ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.avi
Мухаммед Умер

Ответы:

142

Порядок параметров в командной строке имеет значение. Следующие работы для моего случая:

ffmpeg -loop 1 -y -i image8.jpg -i sound11.amr -shortest -acodec copy -vcodec mjpeg result.avi

В более общем случае, где image.jpgи когда audio.wavвы вводите данные, вы можете использовать следующую команду, адаптированную из вики FFmpeg :

ffmpeg -loop 1 -i image.jpg -i audio.wav -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest out.mp4

Это будет использовать libx264кодировщик и обеспечит вам лучшее сжатие, чем кодек MJPEG, использованный выше. Звук AAC, со встроенным ffmpegкодером AAC.

matteo
источник
5
Почему файлы оказываются намного больше, чем [размер изображения] + [размер аудиофайла]? Я ожидаю, что сжатие видео сойдет с ума с постоянным кадром?
Алек Джейкобсон
2
Это зависит от используемого вами видеокодека. Если вы копируете команды в моих примерах, я использую mjpeg в качестве кодека, который сжимает каждый кадр отдельно, поэтому он не использует тот факт, что все кадры равны. Кроме того, я думаю, что даже другие кодеки будут время от времени перекодировать весь кадр, то есть каждый N-й кадр, так что вы получите файл намного меньшего размера, но все же намного больший, чем просто размер изображения + звука. Они делают это потому, что (а) в противном случае декодеру потребуется прочитать весь файл с самого начала, даже если вы просто хотите перейти к последнему кадру, и
matteo
2
Option shortest (finish encoding within shortest input) cannot be applied to input file image.jpg -- you are trying to apply an input option to an output file or vice versa. Move this option before the file it belongs to.
Вим
2
использовать ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.aviэто работает лучше !!!?! ??!?!
Мухаммед Умер
2
Этот ответ в настоящее время обсуждается на мета.
Дэвид Постилл
41

Ты делаешь это намного сложнее, чем должно быть. FFmpeg намного умнее, чем вы можете себе представить - он знает, что вы хотите, чтобы видео было той же длины, что и ваша звуковая дорожка.

ffmpeg -i still.png -i narrate.wav -acodec libvo_aacenc -vcodec libx264 final.flv

pause

Единственные атрибуты вы есть , чтобы указать , являются input filenames, то output codecsи output filename(что ео силу самого включает в себя output container,).

Конечно, имеет смысл начать с неподвижного изображения, которое имеет те же размеры, что и ваше возможное видео; если вы используете специальный редактор изображений вместо указания выходных размеров для соответствия FFmpeg, вам необходимо убедиться, что ваши входные размеры являются четными числами .

Размер вывода является одним из самых распространенных зависаний FFmpeg; некоторые кодеки более ограничены в выходных измерениях, чем другие, но ни один из выходных данных не может иметь атрибутов высоты или ширины с нечетным числом.

pauseКоманда в конце пакетного файла держит открытую CLI - лучший способ отладки командной строки, читая сообщения об ошибках , которые он генерирует. Они чрезвычайно специфичны - и лучшая документация, которую имеет FFmpeg - но тяжелая работа разработчиков будет потрачена впустую, если вы позволите закрыть окно, прежде чем сможете их прочитать.

Командная оболочка имеет переключатель, cmd /kкоторый поддерживает открытое окно, в котором вы можете выполнить те же самые инструкции из вашего пакетного сценария в командной строке.

FFmpeg и avconv заставят вас использовать -c:aв конечном итоге -acodecи -c:vдля -vcodec, но старые инструкции хорошо работают в сборках, которые я использую.

Nota Bene: Каждый коммит имеет свои особенности. Если ваша командная строка дает сбой без видимой причины, часто бывает полезно попробовать другую сборку или перейти к libav , где последние два года самые активные разработчики FFmpeg работали . Их инструмент транскодирования был переименован в avconv, но ваши командные файлы должны работать с любым из них.


источник
Я, должно быть, использую версию, отличную от youurs (если вы попробовали свою команду, и она работает так, как вы описали), потому что, как я уже упоминал в этом вопросе, я уже попробовал вашу точно такую ​​же команду, и я получаю видео продолжительности из 1 кадра (доли секунды), НЕ продолжительность аудиофайла. Я ожидал, что это будет разумно, но (в моей версии) это оказалось не так.
Маттео
2
Привет, Маттео , да, я выполнил этот код, и да, он работает как рекламируется. Я уверен, что есть много полузащитников, которые были бы настолько небрежны, чтобы выдвигать такие претензии без их тестирования, поэтому я постараюсь не обижаться :) В полном посте ниже я предоставлю ссылки Pastebin на вывод консоли FFmpeg и MediaInfo данные о входных файлах и окончательный выходной файл. Мои входные файлы, мой пакетный файл, мой выходной файл находятся на GoogleDrive, где они свободно загружаются , если вы хотите проверить их на соответствие вашей сборке FFmpeg.
@ShinMuraoka Mine is a win-64 ffmpeg build compiled on: Jan 6 2013, at: 16:16:53Ни ваше решение, ни решение @matteo не помогли мне. Кроме того, я загрузил ваши файлы с Google Диска, но он не дал ожидаемого результата (выходной файл был черным и содержал только аудио). Пожалуйста, помогите мне определить правильную команду для использования.
coding_idiot
2
msgstr "ни один вывод не может иметь атрибуты высоты или ширины нечетного числа" Не верно. Установите для pix_fmt что-то, что не имеет подвыборки цветности, например, rgb24 или yuv444p, затем убедитесь, что кодек и контейнер поддерживают это и не имеют дальнейших ограничений. Что касается pix_fmt, FFmpeg менее чем умный; он предполагает yuv420p (который имеет подвыборку цветности), если вы не укажете обратное.
Джонатан Болдуин
как насчет нескольких изображений? Мне нужно, чтобы изображение изменилось в определенное время на другое изображение. Я хотел бы иметь возможность указать их в командной строке с параметром времени для каждого.
36

Еще проще:

ffmpeg -i ep1.png -i ep1.wav ep1.flv

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

Обновление: я заметил, что YouTube испытывает затруднения при обработке видео (застревает на 95%), я думаю, потому что есть только один кадр. Решение, которое я нашел, чтобы сделать YouTube счастливым: добавить больше кадров. Также я добавил, -acodec copyчтобы сохранить качество звука. Тебе нужно -shortestили оно зациклится навсегда. (Он останавливается в конце самого короткого потока, который является аудио, потому что цикл изображения бесконечен.) Порядок ваших параметров очень важен для скорости, так как фильтры (и такие) обрабатываются в указанном вами порядке. Если вы измените порядок этих параметров, результаты резко отличаются.

ffmpeg -r 1 -loop 1 -i ep1.jpg -i ep1.wav -acodec copy -r 1 -shortest -vf scale=1280:720 ep1.flv

Также обратите внимание, что я установил частоту кадров дважды, это не случайно - первая частота кадров для входа, вторая для выхода. Если вы делаете это правильно, видео должно содержать только один кадр в секунду, что означает, что оно кодируется относительно быстро. Также я установил здесь разрешение 720p, что означает, что вы должны получать HD-аудио на YouTube :-)

PJ Brunet
источник
Также возможно, что ваш аудиофайл не будет совместим с вашим контейнером .flv. В этом случае вам следует просто попробовать другой (выходной) контейнер, например .webm, .avi или любой другой формат, пока вы не найдете формат контейнера, совместимый с вашим аудиофайлом.
PJ Brunet
1
Использовал это для .JPG и .MP3, чтобы сделать MP4 - работал отлично. FLV, который я создал из JPG / MP3, похоже, не работал - что может быть в соответствии с предупреждением предыдущих комментариев.
2
Обновленная версия работает, для Youtube. Я думал, что это застряло на 95%, но в конце концов это сработало.
Basj
получил это: No pixel format specified, yuvj420p for H.264 encoding chosen. Use -pix_fmt yuv420p for compatibility with outdated media players. [libx264 @ 0x2b5c940] height not divisible by 2 (700x457)... это работает:ffmpeg -r 1 -loop 1 -i ep1.jpg -i ep1.wav -acodec copy -r 1 -shortest -vf scale=1280:-2 video.mp4
NineCattoRules
как насчет нескольких изображений? Мне нужно, чтобы изображение изменилось в определенное время на другое изображение. Я хотел бы иметь возможность указать их в командной строке с параметром времени для каждого.
14

Версия, которая работала для меня:

 ffmpeg -loop 1 -y -i pic.jpg -i sound.amr -shortest video.mp4

Оформить заказ опция -shortestдолжна быть перед выходным файлом, если нет, я получаю следующую ошибку:

Самый короткий параметр (завершить кодирование при самом коротком вводе) не может быть применен к входному файлу pic.jpg - вы пытаетесь применить параметр ввода к выходному файлу или наоборот. Переместите эту опцию перед файлом, которому она принадлежит. Ошибка анализа параметров входного файла pic.jpg.

fguillen
источник
Спасибо за это. Большинство других ответов не работали для меня (используя ffmpeg на Alpine Linux). Этот ответ имеет самую короткую команду, которая работала для меня безупречно.
DannyB
8

Из справочной страницы ffmpeg:

ffmpeg [[infile options][-i infile]]... {[outfile options] outfile}...

Как вы обнаружили, варианты infile должны предшествовать infile, к которому они применяются.

Это не ошибка, а всего лишь механизм, с помощью которого вы можете указать, к каким аргументам infile будут применяться.

ComputerDruid
источник
как насчет нескольких изображений? Мне нужно, чтобы изображение изменилось в определенное время на другое изображение. Я хотел бы иметь возможность указать их в командной строке с параметром времени для каждого.
4

Это сработало для меня

ffmpeg -loop 1 -shortest -y -i image.jpg -i audio.mp3 -acodec copy -vcodec libx264 video.avi

Я обнаружил, что vcodec libx264создал файлы намного меньшего размера, чем mpjeg(10 МБ, а не 100 МБ).

Полковник паника
источник
1
-shortestявляется опцией вывода и может игнорироваться как опция ввода, так как вы ее используете.
Llogan
1

Я пытался сделать как @matteo , но без звука, и решение @Colonel Panic работало лучше всего:

ffmpeg -loop 1 -shortest -y -i still.png -vcodec libx264 -t 10 video.avi

Я только должен был добавить аргумент продолжительности в секундах ( -t 10).


источник
-shortestэто опция вывода, но вы используете ее в качестве опции ввода. Переместите его перед выходным файлом, и вы можете удалить -t 10, но тогда ваш ответ будет почти таким же, как и остальные.
Llogan
0

ffmpeg -loop 1 -i img.jpg -i audio.wav -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest out.mp4


источник
5
Можете ли вы объяснить, как работает добавленная вами команда?
neelsg
Этот ответ не сильно отличается от других простых «комментариев-ответов» здесь.
Llogan
0

Если кто-то хочет конвертировать их, попробуйте это.

Вы можете установить входную и выходную папку, а также формат, в котором вы хотите, чтобы видео было. В этом случае я установил AVI.

Этот ответ Объединение одного изображения + одного аудиофайла для создания одного видео с использованием FFmpeg мне очень помогло.

 @echo off
 set "sourcedir=C:\Users\CodeHard\Desktop\BOX\Newfolder"  
 set "outputdir=C:\Users\CodeHard\Desktop\BOX\Converted" 

 PUSHD "%sourcedir%"

 for %%F in (*.mp3) DO ffmpeg -r 1 -loop 1 -i abc.jpeg -i "%%F" -acodec copy -r 1 -shortest -vf scale=1280:720 "%outputdir%\%%F.avi"  

 POPD
Сурадж Джейн
источник
-1

Попробуйте эту команду. Это работает для меня.

-y -i /storage/emulated/0/images.jpg -i /storage/emulated/0/audio.wav -acodec aac -vcodec mpeg4 -s 480*320 -f mp4 -r 2 /storage/emulated/0/output.mp4"
Фани Варма
источник
2
Это неполная команда, которая не может работать. Хотя я могу исправить и отладить вашу команду, я не буду выполнять вашу работу за вас, поэтому, пожалуйста, отредактируйте свой ответ и исправьте его самостоятельно. Я также заметил, что размер вашего видео не тот, что хотел Маттео.
Карел