I know its a "lame" question, but: lets say, I have a wmv, avi, etc BIG file. I want to convert it to .MP4, with the possible smallest file size, and of course with the same quality with audio/video. How to? What codec should I use? Im using FFmpeg
FFMPEG – How to Get the Smallest Video with Same Quality
ffmpeg
Related Solutions
First of all, install a more recent version of FFmpeg – grab a static build from the download page.
The use of vpre
presets (which is a way to set default values for ffmpeg settings, not encoder settings) is not really necessary; you usually want to use the -preset
options defined by the encoders.
The reasons you get low output quality are the following, for your two cases respectively:
In the first case you use
crf 25
, a Constant Rate Factor that's going to give you worse quality than the default for the x264 encoder (which is 23). The CRF controls the quality. Try setting a lower CRF, maybe 20, 18, etc. Here, lower means better quality, but it'll increase the file size. A change of 6 in the CRF gives you twice/half the original average bitrate, roughly speaking.You'll have to set a lower CRF because of the generation loss. You're encoding something that was already encoded, so you're again throwing away visual information. That's never good, but if you have to, you're going to have to set a higher quality so as not to remove too much information from the input video.
In the second case you're trying to set a constant bit rate of 2 MBit/s. Your input video roughly has the same bit rate. Now, x264 delivers much better visual quality than an MPEG-4 Visual encoder for the same bitrate, but due to the generation loss, again, you might want to use an even higher bitrate than the original – otherwise you'll end up compressing away too much information.
Furthermore, constant bitrate encoding might result in some passages looking good, but other parts of the video looking worse. If you don't let the encoder freely choose the amount of bits it wants to spend on something, you're going to sacrifice quality at the expense of knowing the target file size.
x264 does have a constant bit rate mode, but it's considered inferior to the other encoding methods. Actually, two-pass encoding isn't meant to target optimal quality, so scratch that.
That all being said, try something along the following:
ffmpeg -i input.avi -c:v libx264 -crf 19 -preset slow -c:a libfdk_aac -b:a 192k -ac 2 out.mp4
If libfdk_aac
is not available, use this instead:
ffmpeg -i input.avi -c:v libx264 -crf 19 -preset slow -c:a aac -b:a 192k -ac 2 out.mp4
The main quality control knob will be your CRF setting. Experiment with that and use a lower value if you need better quality.
You can also choose the veryslow
preset, which will give you better compression, but the encoding will obviously take longer.
If you can't manage to get a decent quality file at a reasonable file size, then you're out of luck. Better keep the original file as-is, without re-encoding. There's no magic "keeping the same quality" tool when you're compressing something that's already compressed.
The problem is that the default bitrate for the MPEG-2 is rather low (as with most other video encoders in ffmpeg, the H.264 one being an exception). MPEG-2 is also not the best choice as a codec these days.
Better quality for MPEG-2
You have a few options if you want to stick with MPEG-2:
Increase the bitrate. You're now using
-b:v 2500k
. If it's HD video, you will not get far with only 2.5 MBit/s. You need at least double that or even more to make the result look good. For example, use-b:v 6000k -target pal-dvd
.For 720p, I think that you should still use a higher bitrate. Remember that DVDs use MPEG-2 and come in about 4.7 GB for 2hrs of movie, so you end up with around 5–8 MBit/s. MPEG-2 is really not very compression-efficient and works better at higher bitrates.
Use a specific quality setting. Change
-b:v …
to-qscale:v 2
. The number here ranges from 1 to 31 and higher means lower quality. There's no point going beyond 4 or 5. If you don't care for the bitrate start with 2 and see if that works for you.
Messing with the number of B-frames, motion estimation method or GOP size may tweak the quality a little but won't result in big changes.
Silent audio
Use -f lavfi -i aevalsrc=0
to generate a silent audio stream. For example:
ffmpeg -i "in.wmv" -f lavfi -i aevalsrc=0 -shortest -c:v mpeg2video -qscale:v 2 -c:a libmp3lame "out.mpg"
You may need to add -target pal-dvd
to the above command to force a certain buffer size.
I chose MP3 as codec. MPEG files cannot contain audio other than MPEG Layer I and II audio as well as PCM streams, so using a silent Ogg Vorbis file will not work unless you convert the audio stream as well (which is not what you're doing when you use -c:a copy
).
Use a different video codec
I'm surprised that a TV that plays video files will read MPEG-2 but not anything else. At least MPEG-4 Part II video should be supported (that's what you know as "DivX" – an MPEG-4 Part II encoder). So you could try:
ffmpeg -i "in.wmv" -f lavfi -i aevalsrc=0 -shortest -c:v libxvid -qscale:v 2 -c:a libmp3lame "out.mp4"
Your TV might actually also support H.264, but only a certain profile. Try using the baseline
profile, for example:
ffmpeg -i "in.wmv" -f lavfi -i aevalsrc=0 -shortest -c:v libx264 -profile:v baseline -crf 23 -c:a aac -strict experimental "out.mp4"
In the above example I've used the CRF option to set the quality instead of qscale
. See the H.264 encoding guide for more.
Best Answer
You can try to encode with libx264 CRF 18. The CRF parameter sets the quality and influences the file size. Lower values mean higher quality, and typical values are from 18 to 28. The default is 23.
CRF 18 is well known for producing a (arguably) "visually lossless" result:
Notice that I used a
veryslow
preset which will give you the smallest file possible. You can leave it out if you want to encode faster, but the file size will be larger, too.Also, I decided to copy the audio track instead of reencoding it (
-c:a copy
), mainly because I assume it's already AAC/MP3 stereo in your sample.If the output is too big for you, try with a higher CRF value (up to 23) but the quality will suffer.