Frage Kombiniere ein Bild + eine Audiodatei, um ein Video mit FFmpeg zu erstellen


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

Ich möchte FFmpeg ein JPEG-Bild und eine Audiodatei als Eingabe nehmen und eine Videodatei von der gleichen Dauer wie die Audiodatei erzeugen (indem Sie das Standbild für die gesamte Dauer strecken).

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 (d. H. 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 viele Kombinationen mit und ohne -s 640x360, -loop_input, -shortest, -t xxx, -r 0.1 (künstlich niedrige Bildrate 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 gegoogelt und ein Dutzend von vorgeschlagenen Lösungen gefunden (angeblich zu genau dieser Frage), von denen keine funktioniert.

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


151
2018-05-04 17:19


Ursprung


Ich habe gerade Ihre Befehlszeile ausprobiert und es hat wie erwartet funktioniert. Ihr Problem könnte im Soundformat liegen. Funktioniert das Transkodieren des Sounds? - Captain Giraffe
Mit "wie erwartet" meinen Sie, dass das resultierende Video dieselbe Dauer wie der Audioeingang hat? Hast du es gespielt? Ist es nicht ein Bild lang? - matteo
Sound-Format ist nicht das Problem, Transkodieren des Sounds funktioniert - matteo
Ich hatte auch eine Bestellung von params und es kostete mich Stunden! Schade, dass diese Art von Problemen in der Hilfe nicht behandelt wird. gregoire.org/2009/12/05/fun-mit-ffmpeg - Paul Gregoire
Das ist besser als die gewählte Antwort, ich experimentierte und es ist schnell und die Dateigröße ist klein.ffmpeg -y -i image.png -i audio.mp3 -c:a copy result.avi - Muhammad Umer


Antworten:


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

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

In einem allgemeineren Fall, wo image.jpg und audio.wav sind Ihre Eingabe, können Sie den folgenden Befehl verwenden, angepasst von das FFmpeg Wiki:

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 die verwenden libx264 Encoder und bieten Ihnen eine bessere Komprimierung als der oben verwendete MJPEG-Codec. Das Audio ist AAC, mit dem eingebauten ffmpeg AAC-Encoder.


117
2017-12-16 14:21



Wie kommt es, dass die Dateien so viel größer sind als [Größe des Bildes] + [Größe der Audiodatei]? Ich würde erwarten, dass die Videokompression mit einem konstanten Rahmen verrückt wird? - Alec Jacobson
Das hängt vom verwendeten Video-Codec ab. Wenn Sie die Befehle in meinen Beispielen kopieren, verwende ich mjpeg als Codec, der jedes Bild einzeln komprimiert, so dass es keinen Vorteil aus der Tatsache zieht, dass alle Bilder gleich sind. Außerdem denke ich, dass sogar andere Codecs das ganze Bild von Zeit zu Zeit neu codieren würden, d. H. Jedes N-te Bild, so dass Sie eine viel kleinere Datei erhalten, aber immer noch viel größer als nur die Bild- und Tongröße. Sie tun dies, weil (a) der Decoder sonst die ganze Datei von Anfang an lesen müsste, auch wenn Sie nur zum letzten Bild springen wollen, und - matteo
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
Diese Antwort wird gerade gegeben besprochen auf Meta. - DavidPostill♦
@matteo klicke unter "Antworten" auf "Bearbeiten" und in der unteren rechten Ecke findest du einen Button mit der Aufschrift "community whatever", den du umschalten und speichern kannst - TankorSmash


Du machst es Weg Schwerer als es sein muss. FFmpeg ist viel schlauer als du es dir zutraust - es weiß, dass du willst, dass das Video die gleiche Länge wie deine Audiospur hat.

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

pause

Die einzigen Attribute Sie haben zu spezifizieren sind die input filenames, das output codecs, und das output filename (welche eo ipso beinhaltet die output container,).

Na sicher, Es ist sinnvoll, mit einem Standbild zu beginnen, das die gleichen Dimensionen wie Ihr Video aufweist. Wenn Sie einen dedizierten Bildeditor anstelle von Ausgabedimensionen für FFmpeg verwenden, müssen Sie dies tun Stellen Sie sicher, dass Ihre Eingabe-Dimensionen gerade Zahlen sind.

Ausgabegröße ist einer der häufigsten Fehler von FFmpeg; einige Codecs sind in Ausgabedimensionen eingeschränkter als andere, aber Keine Ausgabe kann ungerade Höhen- oder Breitenattribute haben.

Das pause Befehl Am Ende der Batch-Datei hält das CLI geöffnet - das Die beste Möglichkeit, die Befehlszeile zu debuggen, besteht darin, die Fehlermeldungen zu lesen es erzeugt. Sie sind extrem spezifisch - und die beste Dokumentation, die FFmpeg hat - aber die harte Arbeit der Entwickler ist verschwendet, wenn Sie zulassen, dass das Fenster geschlossen wird, bevor Sie es lesen können.

Die Befehlsshell hat einen Schalter cmd /k Dies führt ein geöffnetes Fenster, in dem Sie dieselben Anweisungen von Ihrem Batch-Skript an der Eingabeaufforderung ausführen können.

FFmpeg und avconv wird dich beide benutzen lassen -c:azum -acodec und -c:vzum -vcodec irgendwann, aber die alten Anweisungen funktionieren gut in den Builds, die ich verwende.

Nota Bene: Jedes Commit hat Idiosynkrasien. Wenn Ihre Befehlszeile ohne ersichtlichen Grund fehlschlägt, ist es oft hilfreich, einen anderen Build zu versuchen - oder folgen Sie der Verzweigung zu libav, wo FFmpegs aktivste Entwickler in den letzten Jahren waren. Ihr Transcodierungswerkzeug wurde umbenannt avconv aber Ihre Batch-Dateien sollten mit beiden zusammenarbeiten.


32
2018-05-26 02:09



Ich muss eine andere Version als yeurs verwenden (wenn du deinen Befehl ausprobiert hast und es so funktioniert, wie du es beschreibst), weil ich, wie ich schon in der Frage erwähne, genau deinen gleichen Befehl ausprobiert habe und ein Video von der Dauer bekomme von 1 Bild (ein Bruchteil einer Sekunde), NICHT die Dauer der Audiodatei. Ich habe erwartet, dass es intelligent ist, aber (in meiner Version) hat es sich als nicht erwiesen. - matteo
Hey MatteoJa, ich habe diesen Code ausgeführt, und ja, es funktioniert wie angekündigt. Ich bin mir sicher, dass es viele Halbvögel gibt, die so leichtsinnig sind, solche Behauptungen zu machen, ohne sie zu testen, also werde ich versuchen, nicht beleidigt zu werden :) In einem vollständigen Post unten werde ich Pastebin-Links zur FFmpeg-Konsolenausgabe und MediaInfo liefern Daten über Eingabedateien und endgültige Ausgabedatei. Meine Eingabedateien, meine Batchdatei und meine Ausgabedatei befinden sich auf Google Drive, wo sie sich befinden frei herunterladbar, wenn Sie sie gegen Ihren FFmpeg Build testen möchten.
@ShinMuraoka Mine is a win-64 ffmpeg build compiled on: Jan 6 2013, at: 16:16:53 Weder deine Lösung noch @matteo Lösung haben für mich funktioniert. Außerdem habe ich Ihre Dateien von Google Drive heruntergeladen, jedoch nicht die erwartete Ausgabe (die Ausgabedatei war schwarz und enthält nur Audio). Bitte hilf mir, den richtigen Befehl herauszufinden. - coding_idiot
"Keine Ausgabe kann ungerade Höhen- oder Breitenattribute haben" Nicht wahr. Setzen Sie pix_fmt auf etwas, das kein Chroma-Subsampling hat, wie rgb24 oder yuv444p, dann stellen Sie sicher, dass der Codec und der Container es unterstützen und keine weiteren Einschränkungen haben. In Bezug auf pix_fmt ist FFmpeg weniger als intelligent; Es wird yuv420p (mit Chroma-Subsampling) vorausgesetzt, es sei denn, Sie sagen etwas anderes. - Jonathan Baldwin
Was ist mit mehreren Bildern? Ich brauche das Bild, um zu einem bestimmten Zeitpunkt zu einem anderen Bild zu wechseln. Ich würde gerne in der Lage sein, sie in der Kommandozeile mit einem Zeitparameter für jeden zu spezifizieren.


Sogar einfacher:

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

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

Update: Ich habe bemerkt, dass YouTube Schwierigkeiten hat, das Video zu verarbeiten (bleibt bei 95% stecken), weil es nur einen Frame gibt. Die Lösung, die ich gefunden habe, um YouTube glücklich zu machen: füge mehr Frames hinzu. Außerdem habe ich hinzugefügt-acodec copy um die Audioqualität zu erhalten. Du brauchst -shortest oder es läuft für immer. (Sie stoppt am Ende des kürzesten Streams, dem Audio, da die Bildschleife unendlich ist.) Die Reihenfolge Ihrer Optionen ist sehr wichtig für die Geschwindigkeit, da Filter (und so) 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 nur ein Bild pro Sekunde des Videos vorhanden sein, was bedeutet, dass es relativ schnell codiert. Auch hier setze ich die Auflösung auf 720p, was bedeutet, dass du HD-Audio auf YouTube bekommen solltest :-)


28
2018-01-28 20:16



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 versuchen, bis Sie ein Containerformat gefunden haben, das mit Ihrer Audiodatei kompatibel ist. - PJ Brunet
Benutzte dies für ein .JPG und .MP3 um ein MP4 zu machen - funktionierte perfekt. Das FLV, das ich aus dem JPG / MP3 erstellt habe, scheint nicht zu funktionieren - was laut vorheriger Kommentarwarnung sein könnte.
Die aktualisierte Version funktioniert, für Youtube. Ich dachte, es war bei 95% stecken, aber schließlich hat es funktioniert. - Basj
habe das: 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 würde gerne in der Lage sein, sie in der Kommandozeile mit einem Zeitparameter für jeden zu spezifizieren.


Die Version, die für mich funktionierte:

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

Überprüfen Sie die Option -shortest Muss vor der Ausgabedatei stehen, wenn nicht, bekomme ich den folgenden Fehler:

Die kürzeste Option (Codierung innerhalb der kürzesten Eingabe 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 der Datei, zu der sie gehört. Fehler beim Parsen der Optionen für die Eingabedatei pic.jpg.


13
2018-05-22 00:40



Danke dafür. Die meisten anderen Antworten funktionierten nicht für mich (mit ffmpeg auf Alpine Linux). Diese Antwort hat den kürzesten Befehl, der für mich fehlerlos funktioniert hat. - DannyB


Auf der Hilfeseite ffmpeg:

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

Wie Sie herausgefunden haben, müssen die Infile-Optionen vor dem Infile stehen, auf das sie angewendet werden.

Dies ist jedoch kein Fehler, sondern nur ein Mechanismus, mit dem Sie angeben können, auf welche Infielargumente sich beziehen.


7
2018-04-15 22:15



Was ist mit mehreren Bildern? Ich brauche das Bild, um zu einem bestimmten Zeitpunkt zu einem anderen Bild zu wechseln. Ich würde gerne in der Lage sein, sie in der Kommandozeile mit einem Zeitparameter für jeden zu spezifizieren.


Das hat für mich funktioniert

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

Ich habe vcodec gefunden libx264 erstellt viel kleinere Dateien als mpjeg (10 MB statt 100 MB).


4
2017-09-18 11:44



-shortest ist eine Ausgabeoption und kann als Eingabeoption ignoriert werden, wenn Sie sie verwenden. - LordNeckbeard


Ich habe versucht, es zu tun @matteo, aber ohne Audio, und @ Colonel PanikDie Lösung hat am besten funktioniert:

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

Ich musste nur ein Dauerargument in Sekunden hinzufügen (-t 10).


1
2017-07-22 12:15



-shortest ist eine Ausgabeoption, die Sie jedoch als Eingabeoption verwenden. Verschieben Sie es vor der Ausgabedatei und Sie können das entfernen -t 10, aber dann wird deine Antwort fast genauso sein wie die anderen. - LordNeckbeard


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


0
2017-07-12 16:20



Können Sie erklären, wie der von Ihnen hinzugefügte Befehl funktioniert? - neelsg
Diese Antwort ist nicht viel anders als die anderen einfachen "Kommentar-Antworten" hier. - LordNeckbeard


Falls jemand sie im Stapel konvertieren möchte, versuchen Sie es.

Sie können den Eingangs- und den Ausgangsordner sowie das Format festlegen, in dem das Video enthalten sein soll. In diesem Fall stelle ich es auf AVI ein.

Diese Antwort Kombiniere ein Bild + eine Audiodatei, um ein Video mit FFmpeg zu erstellen Hat mir viel 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

0
2018-05-24 07:43





Probieren Sie diesen Befehl aus. 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"

-1



Dies ist ein unvollständiger Befehl, der nicht funktionieren könnte. Obwohl ich Ihren Befehl reparieren und debuggen kann, werde ich Ihre Arbeit nicht für Sie erledigen, also bearbeiten Sie Ihre Antwort und beheben Sie sie selbst. Mir ist auch aufgefallen, dass deine Videogröße nicht das ist, was matteo wollte. - karel