Kombinieren Sie ein Bild und eine Audiodatei, um mit FFmpeg ein Video zu erstellen

183

Das sollte ziemlich trivial sein, aber ich kann keinen Weg finden, es zum Laufen zu bringen.

Ich möchte, dass FFmpeg ein JPEG-Bild und eine Audiodatei als Eingabe verwendet und eine Videodatei mit der gleichen Dauer wie die Audiodatei erstellt (indem das Standbild über die gesamte Dauer gedehnt wird).

Es ist mir egal, welcher Video-Codec für die Ausgabe verwendet wird, aber es ist wichtig, dass ich "copy" als Audio-Codec verwenden kann (dh den Audio-Stream kopieren, ohne ihn zu transkodieren).

Was ist die richtige Befehlszeile, die das tun würde?

Ich habe es versucht:

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

und versuchte , eine Menge Kombinationen mit und ohne -s 640x360, -loop_input, -shortest, -t xxx, -r 0.1(künstlich niedrige Framerate in der Hoffnung , dass das Video länger wäre) und-f image2

Entweder bekomme ich Fehler oder ich bekomme eine Videodatei von der Dauer eines Frames.

Ich habe herumgegoogelt und ein Dutzend Lösungsvorschläge gefunden (angeblich zu genau dieser Frage), von denen keiner funktioniert.

Kann jemand einen Arbeitsbefehl vorschlagen und die Gründe dafür erklären?

Matteo
quelle
Ich habe gerade Ihre Kommandozeile ausprobiert und es hat wie erwartet funktioniert. Dein Problem könnte am Tonformat liegen. Funktioniert das Transcodieren des Sounds?
Captain Giraffe
Mit "wie erwartet" meinen Sie, dass das resultierende Video die gleiche Dauer wie der Audioeingang hat? Hast du es gespielt? Ist es nicht ein Frame lang?
Matteo
Sound-Format ist nicht das Problem, Transcodierung des Sounds funktioniert
Matteo
Ich hatte auch eine Bestellung von Params und es hat mich Stunden gekostet! Schade, dass diese Art von Problemen in der Hilfe nicht behandelt werden. gregoire.org/2009/12/05/fun-with-ffmpeg
Paul Gregoire
3
Dies ist besser als die gewählte Antwort, ich experimentierte und es ist schnell und Dateigröße ist klein ..ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.avi
Muhammad Umer

Antworten:

145

Die Reihenfolge der Optionen in der Befehlszeile ist wichtig. Folgendes funktioniert für meinen Fall:

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

In einem allgemeineren Fall, in dem image.jpgund audio.wavIhre Eingabe sind, können Sie den folgenden Befehl verwenden, der aus dem FFmpeg-Wiki angepasst wurde :

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

Dies würde den libx264Encoder verwenden und eine bessere Komprimierung liefern als der oben verwendete MJPEG-Codec. Das Audio ist AAC, mit dem eingebauten ffmpegAAC-Encoder.

Matteo
quelle
5
Warum sind die Dateien so viel größer als [Bildgröße] + [Audiodateigröße]? Ich würde erwarten, dass die Videokomprimierung mit einem konstanten Bild verrückt wird.
Alec Jacobson
2
Dies hängt vom verwendeten Videocodec ab. Wenn Sie die Befehle in meinen Beispielen kopieren, verwende ich mjpeg als Codec, der jeden Frame separat komprimiert, sodass die Tatsache, dass alle Frames gleich sind, nicht ausgenutzt wird. Außerdem denke ich, dass sogar andere Codecs von Zeit zu Zeit den gesamten Frame neu codieren, dh jeden N-ten Frame, sodass Sie eine viel kleinere Datei erhalten, die aber immer noch viel größer ist als nur die Größe von Bild und Ton. Sie tun dies, weil (a) andernfalls der Decoder die gesamte Datei von Anfang an lesen müsste, auch wenn Sie nur zum letzten Frame springen möchten, und
matteo am
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.
16.
2
benutze ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.avidas funktioniert besser !!!?! ??!?!
Muhammad Umer
2
Diese Antwort wird derzeit auf Meta diskutiert .
DavidPostill
41

Du machst es viel schwerer als es sein muss. FFmpeg ist viel schlauer, als Sie es zu schätzen wissen - es weiß, dass das Video genauso lang sein soll wie Ihre Audiospur.

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

pause

Die einzigen Attribute, die Sie angeben müssen , sind das input filenames, das output codecsund das output filename(wobei das eo ipso das output container, enthält).

Natürlich ist es sinnvoll, mit einem Standbild zu beginnen, das die gleichen Abmessungen aufweist wie Ihr letztendliches Video. Wenn Sie einen dedizierten Bildeditor verwenden, anstatt die Ausgabeabmessungen für FFmpeg anzugeben, müssen Sie sicherstellen, dass Ihre Eingabeabmessungen gerade Zahlen sind .

Die Ausgabegröße ist einer der häufigsten Probleme bei FFmpeg. Einige Codecs sind in den Ausgabedimensionen eingeschränkter als andere, aber keine Ausgabe kann ungeradzahlige Höhen- oder Breitenattribute aufweisen.

Der pauseBefehl am Ende der Batch-Datei hält die CLI geöffnet. Das Debuggen Ihrer Befehlszeile erfolgt am besten durch Lesen der von ihr generierten Fehlermeldungen . Sie sind äußerst spezifisch - und die beste Dokumentation, die FFmpeg bietet -, aber die harte Arbeit der Entwickler wird verschwendet, wenn Sie das Fenster schließen lassen, bevor Sie sie lesen können.

Die Befehlsshell verfügt über einen Schalter cmd /k, der ein geöffnetes Fenster beibehält, in dem Sie dieselben Anweisungen von Ihrem Stapelskript aus an der Eingabeaufforderung ausführen können.

FFmpeg und avconv werden Sie -c:afür -acodecund -c:vfür -vcodecirgendwann benutzen lassen , aber die alten Anweisungen funktionieren gut in den Builds, die ich benutze.

Nota Bene: Jedes Commit weist Besonderheiten auf. Wenn Ihre Befehlszeile ohne ersichtlichen Grund fehlschlägt, ist es oft hilfreich, einen anderen Build zu versuchen - oder der Abzweigung zu libav zu folgen , wo die aktivsten Entwickler von FFmpeg seit einigen Jahren tätig sind. Ihr Transcodierungs-Tool wurde in avconv umbenannt, aber Ihre Batch-Dateien sollten mit beiden funktionieren.


quelle
Ich muss eine andere Version als youurs verwenden (wenn Sie Ihren Befehl ausprobiert haben und dieser so funktioniert, wie Sie ihn beschreiben), da ich, wie bereits in der Frage erwähnt, bereits genau denselben Befehl ausprobiert hatte und ein Video der Dauer erhalte 1 Frame (Bruchteil einer Sekunde), NICHT die Dauer der Audiodatei. Ich habe erwartet, dass es intelligent ist, aber (in meiner Version) erwies es sich als nicht.
Matteo
2
Hey Matteo , ja, ich habe diesen Code ausgeführt, und ja, es funktioniert wie angekündigt. Ich bin mir sicher, dass es viele Halfwits gibt, die so unvorsichtig wären, solche Behauptungen zu erheben, ohne sie zu testen. Deshalb werde ich versuchen, nicht beleidigt zu sein Daten über Eingabedateien und endgültige Ausgabedatei. Meine Eingabedateien, meine Batch-Datei und meine Ausgabedatei befinden sich auf einem GoogleDrive-Laufwerk und können dort kostenlos heruntergeladen werden , wenn Sie sie mit Ihrem FFmpeg-Build testen möchten.
@ShinMuraoka Mine is a win-64 ffmpeg build compiled on: Jan 6 2013, at: 16:16:53Weder Ihre noch Ihre @ Matteo-Lösung hat bei mir funktioniert. Außerdem habe ich Ihre Dateien von Google Drive heruntergeladen, aber sie haben nicht die erwartete Ausgabe geliefert (die Ausgabedatei war schwarz und enthielt nur Audio). Bitte helfen Sie mir dabei, den richtigen Befehl zu finden.
Coding_idiot
2
msgstr "keine Ausgabe kann ungerade Höhen - oder Breitenattribute haben". Stellen Sie pix_fmt auf etwas ein, das kein Chroma-Subsampling hat, wie rgb24 oder yuv444p, und stellen Sie dann sicher, dass der Codec und der Container dies unterstützen und keine weiteren Einschränkungen haben. In Bezug auf pix_fmt ist FFmpeg weniger als intelligent. Es wird davon ausgegangen, dass yuv420p (mit Chroma-Subsampling) verwendet wird, sofern Sie nichts anderes angeben.
Jonathan Baldwin
was ist mit mehreren Bildern? Ich brauche das Bild, um zu einem bestimmten Zeitpunkt zu einem anderen Bild zu wechseln. Ich möchte sie in der Befehlszeile mit jeweils einem Zeitparameter angeben können.
36

Sogar einfacher:

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

FFmpeg versucht automatisch, den besten Codec auszuwählen, abhängig von der Erweiterung Ihrer Ausgabedatei.

Update: Mir ist aufgefallen, dass YouTube Probleme beim Verarbeiten des Videos hat (bleibt bei 95% hängen). Ich denke, dass es nur einen Frame gibt. Die Lösung, die ich gefunden habe, um YouTube glücklich zu machen: Hinzufügen weiterer Frames. Außerdem habe ich hinzugefügt -acodec copy, um die Audioqualität zu erhalten. Du brauchst -shortestoder es schleift für immer. (Sie endet am Ende des kürzesten Streams, nämlich des Audios, da die Bildschleife unendlich ist.) Die Reihenfolge Ihrer Optionen ist für die Geschwindigkeit sehr wichtig, da Filter (und dergleichen) in der von Ihnen angegebenen Reihenfolge verarbeitet werden. Wenn Sie die Reihenfolge dieser Parameter ändern, unterscheiden sich die Ergebnisse erheblich.

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

Beachten Sie auch, dass ich die Bildrate zweimal eingestellt habe, das ist kein Zufall - die erste Bildrate ist für die Eingabe, die zweite für die Ausgabe. Wenn Sie dies richtig machen, sollte es nur einen Frame pro Sekunde des Videos geben, was bedeutet, dass es relativ schnell codiert. Außerdem habe ich hier die Auflösung auf 720p eingestellt, was bedeutet, dass Sie HD-Audio auf YouTube erhalten sollten :-)

PJ Brunet
quelle
Es ist auch möglich, dass Ihre Audiodatei nicht mit Ihrem FLV-Container kompatibel ist. In diesem Fall sollten Sie einfach einen anderen (Ausgabe-) Container wie .webm, .avi oder ein anderes Format ausprobieren, bis Sie ein mit Ihrer Audiodatei kompatibles Containerformat gefunden haben.
PJ Brunet
1
Verwendet dies für ein .JPG und .MP3, um ein MP4 zu machen - hat perfekt funktioniert. Das FLV, das ich aus JPG / MP3 erstellt habe, schien nicht zu funktionieren - möglicherweise gemäß der Warnung in den vorherigen Kommentaren.
2
Die aktualisierte Version funktioniert für Youtube. Ich dachte, es steckt zu 95% fest, aber schließlich hat es funktioniert.
Basj
habe dies: 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)... das funktioniert:ffmpeg -r 1 -loop 1 -i ep1.jpg -i ep1.wav -acodec copy -r 1 -shortest -vf scale=1280:-2 video.mp4
NineCattoRules
was ist mit mehreren Bildern? Ich brauche das Bild, um zu einem bestimmten Zeitpunkt zu einem anderen Bild zu wechseln. Ich möchte sie in der Befehlszeile mit jeweils einem Zeitparameter angeben können.
14

Die Version, die bei mir funktioniert hat:

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

Checke die Option aus -shortest, die vor der Ausgabedatei stehen muss, wenn nicht die folgende Fehlermeldung angezeigt wird:

Die Option "Kürzeste" (Kodierung in kürzester Zeit beenden) kann nicht auf die Eingabedatei "pic.jpg" angewendet werden - Sie versuchen, eine Eingabeoption auf eine Ausgabedatei anzuwenden oder umgekehrt. Verschieben Sie diese Option vor die Datei, zu der sie gehört. Fehler beim Analysieren der Optionen für die Eingabedatei pic.jpg.

fguillen
quelle
Danke dafür. Die meisten anderen Antworten haben bei mir nicht funktioniert (mit ffmpeg unter Alpine Linux). Diese Antwort hat den kürzesten Befehl, der für mich einwandfrei funktioniert hat.
DannyB
8

Aus der ffmpeg-Manpage:

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

Wie Sie festgestellt haben, müssen die Optionen für die Infile-Datei vor der Infile-Datei stehen, für die sie gelten.

Dies ist jedoch kein Fehler, sondern nur ein Mechanismus, mit dem Sie angeben können, auf welche infile-Argumente angewendet werden soll.

ComputerDruid
quelle
was ist mit mehreren Bildern? Ich brauche das Bild, um zu einem bestimmten Zeitpunkt zu einem anderen Bild zu wechseln. Ich möchte sie in der Befehlszeile mit jeweils einem Zeitparameter angeben können.
4

Das hat bei mir funktioniert

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

Ich fand, dass vcodec libx264viel kleinere Dateien erstellt hat als mpjeg(10 MB statt 100 MB).

Oberst Panic
quelle
1
-shortestist eine Ausgabeoption und kann bei der Verwendung als Eingabeoption ignoriert werden.
Logan
1

Ich habe versucht, @matteo zu verwenden , aber ohne Audio, und die Lösung von @Colonel Panic hat am besten funktioniert:

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

Ich musste nur ein Argument für die Dauer in Sekunden ( -t 10) hinzufügen .


quelle
-shortestist eine Ausgabeoption, die Sie jedoch als Eingabeoption verwenden. Verschieben Sie es vor die Ausgabedatei und Sie können die entfernen -t 10, aber dann wird Ihre Antwort so ziemlich die gleiche sein wie die der anderen.
Logan
0

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


quelle
5
Können Sie erklären, wie der hinzugefügte Befehl funktioniert?
Neelsg
Diese Antwort ist nicht viel anders als die anderen einfachen "Kommentar-Antworten" hier.
Logan
0

Wenn jemand sie stapelweise konvertieren möchte, versuchen Sie dies.

Sie können den Eingabe- und Ausgabeordner sowie das Format festlegen, in dem das Video gespeichert werden soll. In diesem Fall habe ich AVI ausgewählt.

Diese Antwort Die Kombination von einem Bild und einer Audiodatei zu einem Video mit FFmpeg hat mir sehr geholfen.

 @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
Suraj Jain
quelle
-1

Versuchen Sie diesen Befehl. Es ist für mich gearbeitet.

-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"
Phani Varma
quelle
2
Dies ist ein unvollständiger Befehl, der möglicherweise nicht funktioniert. Obwohl ich Ihren Befehl korrigieren und debuggen kann, werde ich Ihre Arbeit nicht für Sie erledigen. Bearbeiten Sie Ihre Antwort, und korrigieren Sie sie selbst. Mir ist auch aufgefallen, dass deine Videogröße nicht das ist, was Matteo wollte.
Karl