After lots of trial and error each time I convert a video to WebM, I finally got around to posting this so I don’t forget next time. In a nutshell, here’s the conversion command that works for me:
avconv -i myvideo.mp4 -acodec libvorbis -aq 5 -ac 2 -qmax 25 -threads 2 myvideo.webm
What is this doing? Let’s go through it bit by bit. Assuming we have a video called myvideo.mp4, the simplest way to convert to WebM is with this little line:
avconv -i myvideo.mp4 myvideo.webm
Easy, but the quality will likely be rubbish hence the use of a few flags. The flags can be divided into three sorts: audio, video and the transcoding itself.
Audio flags
Concentrating on the audio first, we should specify the audio codec which for WebM is Ogg Vorbis:
-acodec libvorbis
In later versions the audio codec is Ogg Vorbis by default but personally I specify it just in case.
The quality can be adjusted with the -aq
flag from -1 to 10 with a higher number meaning better quality. I’ve found 4 or 5 to be more than adequate.
The number of channels, e.g. mono (1) and stereo (2), is controlled with the -ac
flag.
Video flags
Moving on to the video quality and thankfully it’s nice and simple. Like the audio, we can specify a quality level. With the libvpx library used for WebM, this is actually a quantization level, set with the -qmin
and -qmax
flags ranging from 0 to 51. In my tests, setting qmin
makes no difference so I ignore it. Setting qmax
effectively controls the maximum compression that will be applied to each frame. In other words, a higher qmax
means higher compression, which results in lower quality and smaller file size. Obviously you should adjust this to whatever’s best for your circumstances, but I’ve found 25 to be a good starting point.
Note that with both the audio and video, setting flags for bitrate (-ab
for audio, -b
for video) makes little or no difference. Instead, setting quality flags indicates the use of a variable bitrate.
Transcoding flags
Finally, I tend to also use the -threads
flag. This simply sets how many CPU threads to use when transcoding. If your PC has multiple cores then a higher number means faster processing but with less spare capacity for running other programs. Incidentally it’s also possible to do 2-pass encoding with WebM using the -pass
flag.
FFmpeg naming confusion
Note that due to what seem to be political reasons, using the ffmpeg command in Ubuntu results in a sad message.
Was:
*** THIS PROGRAM IS DEPRECATED *** This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Now:
ffmpeg: command not found
It turns out that FFmpeg is very much alive, as is Libav (avconv), both with similar goals but with slightly different ways of doing it. I don’t follow the details and arguments but for practical purposes, using either the ffmpeg
or avconv
command is fine for converting videos to WebM with the above flags (at the time of writing). Of course, this may change eventually but for the sake of regular users, I hope not.
Unfortunately whatever FFmpeg/Libav disagreement there was has resulted in ffmpeg being removed from Ubuntu and possibly other Linux distros. For the transcoding commands in this post at least, the parameters are the same so if you have problems using avconv try with ffmpeg and vice versa.
Hi, can you please tell me how to use the same in command prompt using windows.
here is the code which i am using “ffmpeg -i input.mp4 -vcodec libvpx -acodec libvorbis -f webm movie.webm”
If i use the command it gives this error..
“Unknown input or output format: webm”
Hi Chiranjivi,
I’m not familiar with Windows but it sounds like the WebM (VP8) codec is not installed. I found instructions on the official WebM site for installing DirectShow filters which should be what you need: http://www.webmproject.org/tools/
I suggest giving this a try and I’d be interested to hear if it does or doesn’t work.
Thank you! You just fixed the problem that has been plaguing me for the last few months– namely, that every video converted I tried produced a .webm file four times larger than the source .mp4, with worse quality. Video looks good, and the file size is roughly the same. Thank you!!
You’re welcome!
It took me a lot of trial and error so it’s very satisfying to know I’ve helped someone. Thanks for letting me know.
Hi,
This was very helpful. I actually used it in my PHP script and it worked like a champ. On 2 threads too.
If someone wants to convert MP4 to another MP4 with a higher quality video try this:
input.mp4 -c:v libx264 -crf 17 output.mp4
I am wandering if you can help me with the command to convert my mp4 to ogv? So far I have your code snippet above (thanks again) and my MP4 one above.
I have tried:
-c:v libtheora -q:v 10 -c:a libvorbis -q:a 10
It looks good, the audio plays but the video stops after 1 second.
Any help greatly appreciated!
Your fellow developer,
Nick
is there any way to put the loader if conversion process running this is my code
var video_path=video[‘path’];
console.log(‘path sync function: ‘ + video_path);
var fileNameIndex = video_path.lastIndexOf(“/”) + 1;
//var fileNameIndex = path_f.lastIndexOf(“/”) + 1;
var filename = video_path.substr(fileNameIndex);
//var path = filename;
console.log(‘filename: ‘ + filename);
var webm_file =”public/upload/”+filename;
console.log(‘webm_file.myyy.webm: ‘ + webm_file);
var mp_file =”public/upload/”+Math.random()*1000000000000000000+’.mp4′;
console.log(‘mp_file.myyy.mp4: ‘ + mp_file);
var convert = “c:/ffmpeg/bin/ffmpeg -i ” + webm_file + ” ” + mp_file ;
console.log(‘convert: ‘ + convert);
//var path = convert;
var test=exec(convert);
console.log(‘test: ‘ + test);
var fileNameIndex_db = mp_file.lastIndexOf(“/”) + 1;
var filename_db = mp_file.substr(fileNameIndex_db);
var path= “upload/”+filename_db;
console.log(‘path save in db: ‘+path);
Thanks, these settings work perfectly for converting MP4 videos for my blog.
Hi Carlo.
I’m glad to hear that and thanks for taking the time to comment.
This was very helpful. I actually used it in my PHP script and it worked like a champ.
Thanks! Your page here was very helpful for taming the obnoxious mp4 videos my Android phone makes. Here’s a little write up of what I did, which includes a 1MB video example demonstrating the difference between naive conversion and some of your options.
This was a very helpful writeup on using ffmpeg and converting mp4 to webm. Thank you for sharing it.
Howdy there — nice article…but, with updated information. For Ubuntu – FFMPEG has been reinstated in the repository. `sudo apt-get install ubuntu-restricted-extras ubuntu-restricted-addons`.
Cheers
Thanks for the information, not only did it help me learn to convert to webm, but was very helpful in explaining the flags used in FFMPEG!