0

I want to combine an audio file and one image file into a video. Output will be in .webm format so I will be using libvpx. The video must have one frame with the best/lossless quality.

So far I have tried these, but I got bad results or no results at all:

1st command:

ffmpeg -i image.jpg -i audio.ogg -c:v copy -c:a copy outputvideo.webm

This is not working. It gives this error:

[webm @ 0000000002c7f8a0] Only VP8 or VP9 video and Vorbis or Opus audio and Web
VTT subtitles are supported for WebM.
...
Could not write header for output file #0 (incorrect codec parameters ?): Error
number -22 occurred

2nd command:

ffmpeg -i image.jpg -i audio.ogg -c:v libvpx -c:a copy outputvideo.webm

This produces poor quality, not acceptable for me.

3rd command:

ffmpeg -i image.jpg -i audio.ogg -c:v libvpx -crf 4 -c:a copy outputvideo.webm

So I added -crf 4 parameter. I expected that would produce visually lossless video. In fact, it has no effect at all. -crf 4 and -crf 63 produces same results.

Then I have tried the similar settings with the libvpx-vp9 codec, but no luck. Even the -lossless 1 parameter does nothing for improving quality.

4 Answers 4

0

1st command: jpg is not contains webm. http://en.wikipedia.org/wiki/WebM

2nd command: You can use -loop 1 in front of inputfile, and use -shortest behind inputfile.

ffmpeg -loop 1 -i image.jpg -i audio.ogg -shortest -c:v libvpx -c:a copy outputvideo.webm

If you want to set fps, use fps filter.

ffmpeg -loop 1 -i image.jpg -i audio.ogg -vf fps=10 -shortest -c:v libvpx -c:a copy outputvideo.webm

3rd command: You can use quality best. http://ffmpeg.org/ffmpeg-codecs.html#libvpx

ffmpeg -loop 1 -i image.jpg -i audio.ogg -shortest -c:v libvpx -quality best -c:a copy outputvideo.webm
2
  • Your commands creates more than just one frame. Since my audio files are too long, the video stream size will be at least 2x larger than the given .jpg file, with worse quality. BTW, I tried to set fps at smaller values than 1, but it didn't work. I have tried both, -r 1/60 parameter and -vf fps="fps=1/60" filter. I don't know why.
    – destor
    Jan 18, 2015 at 4:36
  • I don't know why libvpx doesn't set fps at smaller values than 1, using libx264 sets fps at smaller values than 1. wiki:Create a video slideshow from images ffmpeg -loop 1 -i image.jpg -i audio.ogg -vf -vf "fps=1/60" -pix_fmt yuv420p -shortest -c:v libx264 -c:a copy outputvideo.mkv
    – nico_lab
    Jan 18, 2015 at 10:45
0

I'm not sure if it's a bug, but using -qscale:v instead of -crf works for libvpx. Qscale works the opposite way to CRF, higher is larger / better quality. Try the second command with -qscale:v 10 instead of the -crf option.

0

ffmpeg -i image.jpg -i audio.ogg -c:v libvpx -crf 4 -c:a copy outputvideo.webm

So I added -crf 4 parameter. I expected that would produce visually lossless video. In fact, it has no effect at all. -crf 4 and -crf 63 produces same results.

Then I have tried the similar settings with the libvpx-vp9 codec, but no luck. Even the -lossless 1 parameter does nothing for improving quality.

To get lossless quality, try adding -b:v 0 when using VP9 assuming your .jpg has a standard video resolution size or is the exact resolution you want your output video to be i.e. 1920x1080 .jpg for 1080p video output and has a limited dynamic range for color.

ffmpeg -r 1 -loop 1 -i image.jpg -i audio.ogg -c:a copy -r 1 -c:v libvpx-vp9 -crf 0 -b:v 0 -shortest outputvideo.webm

Notes/Explanation:

While I've read the comments about how the -loop and -shortest made the video stream at least twice the size of the .jpg and with lower quality, this is partially addressed by setting the frame rate for the video and audio file to 1. Hence why -r 1 is set twice, once for video and once for audio. However this will also increase your encoding time.

While it might seem ludicrous that the file be so big, you have set a standard of having lossless quality which demands that no compression be done. In video compression, codecs work by removing the similarities of uncompressed frames and keeping only the differences and then encoding those difference in a compressed format. By creating a lossless video file, you are basically telling the encoder not to do any compression of those frames and thus creates the equivalent of taking your .jpg file and copying it in a folder 25 times (the default frame when using -loop 1) for every second of video. With long audio files, you can imagine that a 25x 200kb .jpg turns into 5MB per second and 300 MB per minute. Hence, for lossless video, your best bet is to use 1 frame per second as deemed by my suggested command. If the file size is too big, then change the quality level to 31 or set -cfr 31

As for why it was worse quality, I don't have enough information to say specifically (version of ffmpeg, resolution of .jpeg) but it may be because you did not set any sort of scaling options when running ffmpeg and results in it applying the default limited dynamic range (16-235) for color, sets dithering as automatic, and bicubic is used for the scaling algorithm. So if your image has a full dynamic range of 0-255 then that explains why no improvements in image quality would result regardless of the -crf value you set previously as it was probably removing a handful of colors not available with a limited dynamic range profile.

Since you indicated in Command 3 that you had success creating a video without using the loop option, you may want to try omitting the usage of -loop and -shortest and using all the same parameters that you had before in command 3 but then specify some scaling options to see what results.

Commands Explained

  • The valid values for -crf is actually 0-63 whereas you could still use 4 for a lower file size if "0" produces too large of a file. Needless to say, the VP9 recommended target quality is 33 for 1080p when using CQ mode for Video On Demand.
  • With -b:v 0 you are mark the video bitrate as 0 to explicitly set "Q" mode which allows the quantizer to determine the flow of data that it wishes to process which means it will use as much bitrate as needed to maintain the quality target specified. However...
  • ...we did not specify the target quality with -quality because the default is "good" and it's said here that the target level of "best" is more of a research tool, with marginal improvement over a -quality good target
  • Use of -r 1 twice was intentional in order to ensure an image is displayed throughout the entire video by setting both video and audio to a frame rate of 1 (as previously explained)
0

You could try to get quality by manually setting video bitrate -b:v 2000M.

As for FPS, seems like it doesn't affect size much.

Experimented a bit with -b:v and framerates:

ffmpeg -loop 1 -i ./frames/0254.png -i camera-shutter-click-07.wav -r 10000 -pix_fmt yuv420p -shortest -vcodec libvpx -strict -2 -acodec vorbis  outputvideo6.webm

ffmpeg -loop 1 -i ./frames/0254.png -i camera-shutter-click-07.wav -pix_fmt yuv420p -shortest -vcodec libvpx -strict -2 -acodec vorbis  outputvideo5.webm

ffmpeg -loop 1 -i ./frames/0254.png -i camera-shutter-click-07.wav -r 10000 -pix_fmt yuv420p -shortest -b:v 2000M -vcodec libvpx -strict -2 -acodec vorbis  outputvideo7.webm

First two videos are 25fps and 10000fps but their filesizes are almost equal: 101.3 and 102.7kB But since in third bitrate is higher it's size 339.7kB

ffmpeg -i outputvideo5.webm -i outputvideo6.webm -i outputvideo7.webm
ffmpeg version 2.5.git Copyright (c) 2000-2015 the FFmpeg developers
  built on Jan 11 2015 19:12:34 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
  configuration: --prefix=/home/alexandrov/ffmpeg_build --extra-cflags=-I/home/alexandrov/ffmpeg_build/include --extra-ldflags=-L/home/alexandrov/ffmpeg_build/lib --bindir=/home/alexandrov/bin --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-x11grab
  libavutil      54. 16.100 / 54. 16.100
  libavcodec     56. 20.100 / 56. 20.100
  libavformat    56. 18.100 / 56. 18.100
  libavdevice    56.  3.100 / 56.  3.100
  libavfilter     5.  7.100 /  5.  7.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, matroska,webm, from 'outputvideo5.webm':
  Metadata:
    encoder         : Lavf56.18.100
  Duration: 00:00:01.32, start: 0.000000, bitrate: 613 kb/s
    Stream #0:0: Video: vp8, yuv420p, 1280x720, SAR 1:1 DAR 16:9, 25 fps, 25 tbr, 1k tbn, 1k tbc (default)
    Stream #0:1: Audio: vorbis, 48000 Hz, stereo, fltp (default)
Input #1, matroska,webm, from 'outputvideo6.webm':
  Metadata:
    encoder         : Lavf56.18.100
  Duration: 00:00:01.30, start: 0.000000, bitrate: 631 kb/s
    Stream #1:0: Video: vp8, yuv420p, 1280x720, SAR 1:1 DAR 16:9, 10k fps, 25 tbr, 1k tbn, 1k tbc (default)
    Stream #1:1: Audio: vorbis, 48000 Hz, stereo, fltp (default)
Input #2, matroska,webm, from 'outputvideo7.webm':
  Metadata:
    encoder         : Lavf56.18.100
  Duration: 00:00:01.30, start: 0.000000, bitrate: 2088 kb/s
    Stream #2:0: Video: vp8, yuv420p, 1280x720, SAR 1:1 DAR 16:9, 10k fps, 25 tbr, 1k tbn, 1k tbc (default)
    Stream #2:1: Audio: vorbis, 48000 Hz, stereo, fltp (default)

You must log in to answer this question.

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