27

I'm running the following command:

ffmpeg -i audio.mp3 -ar 44100 -f image2 -i logo.jpg -r 15 -b 1800 -s 640x480 foo.mov

Which successfully outputs a video with my recorded audio and an image on it.

When I try and upload this to YouTube it fails to process, regardless of the formats I try: .mov, .avi, .flv, .mp4

Is there some setting I'm missing in the above that would generate a format Youtube will accept? I've tried looking through the ffmpeg documentation but I'm in over my head.

I did an experiment by putting a 2 second video with a 30 second mp3. When I uploaded to youtube, the resulting video was only 2 seconds long. So it may be that YouTube looks only to the video track for the length, and since a picture is only a frame long or whatever, maybe that borks it.

6 Answers 6

13

Here's what worked:

ffmpeg -i audio.mp3 -f image2 -loop 1 -i logo.jpg 
-r 15 -s 640x480 \
-c:v libx264 -crf 18 -tune stillimage -preset medium \
-shortest foo.mov

Specifically, the loop option, which will duplicate the image as frames. It will also then need the shortest option to keep the file from growing and growing (this way it truncates it to the length of the shortest stream – here, the audio file).

The r option changes the frame rate, and crf 18 sets the quality (use a higher value here for lower video quality). See here for more details: FFmpeg: The ultimate Video and Audio Manipulation Tool

3
  • 2
    Doesn't work for me. I get an one-frame movie. Aug 23, 2011 at 22:46
  • I does work for me now.
    – molnarg
    Mar 22, 2014 at 11:03
  • works but is terribly slow, speed about 1x. encoding stillimage to video should take zero seconds, so it should have the same speed as copy. see also: Speed Up FFMpeg Still Image to Video
    – milahu
    Jul 24 at 13:21
5

A piece of code that works for me, from another forum:

ffmpeg -loop 1 -r ntsc -i image.jpg -i song.mp3 -c:a copy -c:v libx264 -preset fast -threads 0 -shortest output.mkv 
4

I took Pavel's code, that worked for me too, and shortened it by trimming needless options:

ffmpeg -loop 1 -shortest -i <audio file> -i <image file> <output video file>

this is a general form that works with any image and audio file as input and produce a video file as output.

That said, since your video stream will be made of a single picture repeated indefinitely, you could set a low frame rate (that is the number of images that appears in a second) with -r. Note that not all output containers allow low frame rates. One that does is avi, so you might do:

ffmpeg -loop 1 -shortest -r 0.1 -i <audio file> -i <image file> output.avi

this would create a video file with a frame rate of 0.1 (i.e. one image each 10 seconds) instead of the default of 25. This will affect file size but not video quality. Eventually, you can set the audio bitrate to get a better audio quality with -ab. This is the command I actually use to make this kind of videos for youtube:

ffmpeg -loop 1 -shortest -r 0.1 -i <audio file> -i <image file> -ab 128k output.avi
3
  • Thanks. I ran ffmpeg -loop 1 -shortest -r 0.1 -i audio.mp3 -i image.jpg output.avi but got 'Option loop not found.' Any ideas? Dec 15, 2012 at 1:12
  • @col If you're still interested: you need the loop option before the image input, not before the audio.
    – slhck
    Mar 20, 2013 at 15:04
  • 1
    this is what worked for me: ffmpeg -i <audio file> -loop 1 -i <image file> -shortest <output video file>
    – Karolinger
    Apr 5, 2013 at 2:18
1

with avconv:

avconv -i input.mp3 -loop 1 -f image2 -i logo.png -r 30 -s 640x480 -ab 128k -ar 44100 -ac 1 -ss 00:00:00.000 -t 01:02:03.123 foo.ogv
8
  • Welcome to SuperUser and thanks for your answer. Some more detail about what you are proposing and why would be helpful. Mar 20, 2013 at 15:23
  • 1
    the response is because of ffmpeg is deprecated
    – ZiTAL
    Mar 22, 2013 at 11:13
  • 2
    No the ffmpeg project is ongoing. There was a dispute that lead to the deprecated message. See stackoverflow.com/questions/9477115/… Mar 22, 2013 at 11:17
  • 2
    Use the -shortest output options instead of manually declaring times (also, use ffmpeg instead of avconv if possible).
    – llogan
    Apr 22, 2016 at 1:05
  • 2
    Made a bash script in case anyone is interested
    – Dallaylaen
    Dec 19, 2016 at 1:21
1

To add something a little shorter, this worked for me:

ffmpeg -i audio.wav -loop 1 -i image.png -shortest foo.flv

The order of options is important.

0

I got this to work after much experimentation: https://www.youtube.com/watch?v=qjlDT819Q3s

  1. Convert image(s) to video as per https://trac.ffmpeg.org/wiki/Create%20a%20video%20slideshow%20from%20images:

    ffmpeg -framerate 1/20 -i png/img-%03d.png -c:v libx264 -vf "fps=25,format=yuv420p" png.mp4

    Here I use several images and make them change every 20s.

  2. Concatenate enough copies of the above video to span the duration of your audio as per https://trac.ffmpeg.org/wiki/Concatenate. Other solutions, like expecting ffmpeg -i wav.wav -i png.mp4 youtube.mp4 to do the right thing, ended up being rejected by YouTube (also, players such as VLC are confused and cannot seek properly). My guess is that time positions need to be adjusted in the copies, which ffmpeg does not do, unless they are concatenated:

    ffmpeg -f concat -i pngs.txt -c copy pngs.mp4

    (where the file pngs.txt is hand-made to contain as many copies as needed: copies = audio length / video length)

  3. Mix your audio with the video obtained in 2 as per https://www.virag.si/2015/06/encoding-videos-for-youtube-with-ffmpeg/:

    ffmpeg -i pngs.mp4 -i wav.wav -shortest -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart youtube.mp4

Now the file youtube.mp4 should be accepted by YT.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .