Об'єднайте одне зображення + один аудіофайл, щоб зробити одне відео за допомогою FFmpeg


183

Це має бути досить тривіально, але я не можу знайти спосіб змусити його працювати.

Я хочу, щоб 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

Або я отримую помилки, або отримую відеофайл тривалістю одного кадру.

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

Чи може хто-небудь запропонувати робочу команду і пояснити обґрунтування, що її лежить


Я просто спробував ваш командний рядок, і він працював так, як очікувалося. Ваша проблема може полягати у форматі звуку. Чи працює перекодування звуку?
Капітан Жираф

Під "як очікувалося" ви маєте на увазі, що отримане відео має таку саму тривалість, що й аудіовхід? Ви грали в нього? Хіба це не один кадр?
Маттео

Формат звуку - це не проблема, перекодування звуку працює
маттео

У мене теж було замовлення випуску парам, і це коштувало мені годин! Шкода, що подібні проблеми не розглядаються в довідці. gregoire.org/2009/12/05/fun-with-ffmpeg
Пол Грегуар

3
це краще, ніж обрана відповідь, я експериментував, і це швидко, а розмір файлів невеликий ..ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.avi
Мухаммед Умер

Відповіді:


145

Порядок параметрів у командному рядку має значення. У моєму випадку працює наступне:

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.


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.
wim

2
використовувати ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.aviце працює краще !!!?! ??!?!
Мухаммед Умер

2
Зараз ця відповідь обговорюється на мета.
DavidPostill

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кінцевому підсумку, але старі інструкції чудово працюють у побудовах, які я використовую.

Нота Бене: Кожен комітет має свої ідіосинкратії. Якщо ваш командний рядок не працює з жодної видимої причини, часто корисно спробувати іншу збірку - або перейдіть по роздрібному напрямку до libav , де найактивніші розробники FFmpeg були останні кілька років. Їх інструмент перекодування перейменований на avconv, але ваші пакетні файли повинні працювати з будь-яким.


Я повинен використовувати іншу версію, ніж ваша (якщо ви спробували свою команду, і вона працює так, як ви описуєте), тому що, як я вже згадував у запитанні, я вже спробував вашу точно таку ж команду, і я отримую відео тривалості 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 Drive, але він не дав очікуваного виводу (вихідний файл був чорним, містив лише аудіо). Будь ласка, допоможіть мені у з'ясуванні правильної команди, яка буде використовуватися.
coding_idiot

2
"жоден вихід не може мати атрибути висоти чи ширини непарних чисел" Не відповідає дійсності. Встановіть 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 :-)


Також можливо, ваш аудіофайл не буде сумісний з вашим .flv-контейнером. У цьому випадку вам слід просто спробувати інший (вихідний) контейнер, наприклад .webm, .avi або будь-який інший формат, поки ви не знайдете формат контейнера, сумісний з вашим аудіофайлом.
PJ Brunet

1
Використовували це для .JPG та .MP3, щоб зробити MP4 - працювали чудово. FLV, який я створив з JPG / MP3, здається, не працює - що може бути відповідно до попереднього попередження про коментарі.

2
Оновлена ​​версія працює для Youtube. Я думав, що він застряг на 95%, але нарешті він спрацював.
Баш

отримав це: 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.


Дякую за це Більшість інших відповідей не працювали для мене (використовуючи ffmpeg на альпійському Linux). Ця відповідь має найкоротшу команду, яка працювала для мене бездоганно.
DannyB

8

З manf-сторінки ffmpeg:

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

Як ви виявили, параметри інфайлу повинні бути перед інфіле, до якого вони застосовуються.

Це не помилка, однак це лише механізм, за допомогою якого можна вказати, до яких аргументів infile застосовуються.


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

4

Це працювало для мене

ffmpeg -loop 1 -короткий -y -i image.jpg -i audio.mp3 -acodec копія -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

Ця відповідь не сильно відрізняється від інших простих "коментарів-відповідей" тут.
логіан

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
Це неповна команда, яка не могла б працювати. Хоча я можу виправити та налагодити вашу команду, я не буду виконувати вашу роботу за вас, тому будь ласка, відредагуйте свою відповідь та виправте її самостійно. Я також помітив, що розмір вашого відео - це не те, що хотів мати Маттео.
Карел
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.