9

When trying to convert a .webm video (two colored animation) to a .mp4 video using ffmpeg (3.4.2 on mac) the result is somewhat blurry. I did research this topic and tried different approaches to solve this. Here is the most promising command:

ffmpeg -i vidoe.webm -qscale 1 video.mp4

However, the quality change is still tremendous, see the difference below.

webm

enter image description here

mp4

enter image description here

The resolution of the two videos is the same, however the size dropped from 24,3MB (.webm) to 1,5MB (.mp4) after conversion.

Update

Here is the log of the conversion.

ffmpeg version 3.4.2 Copyright (c) 2000-2018 the FFmpeg developers
  built with Apple LLVM version 9.0.0 (clang-900.0.39.2)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.4.2 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --disable-jack --enable-gpl --enable-libmp3lame --enable-libx264 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libavresample   3.  7.  0 /  3.  7.  0
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Input #0, matroska,webm, from 'video.webm':
  Metadata:
    encoder         : whammy
  Duration: 00:00:05.02, start: 0.000000, bitrate: 38755 kb/s
    Stream #0:0: Video: vp8, yuv420p(progressive), 1920x1080, SAR 1:1 DAR 16:9, 60 fps, 60 tbr, 1k tbn, 1k tbc (default)
Please use -q:a or -q:v, -qscale is ambiguous
Stream mapping:
  Stream #0:0 -> #0:0 (vp8 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x7f8625800c00] -qscale is ignored, -crf is recommended.
[libx264 @ 0x7f8625800c00] using SAR=1/1
[libx264 @ 0x7f8625800c00] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x7f8625800c00] profile High, level 4.2
[libx264 @ 0x7f8625800c00] 264 - core 152 r2854 e9a5903 - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'video.mp4':
  Metadata:
    encoder         : Lavf57.83.100
    Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=-1--1, 60 fps, 15360 tbn, 60 tbc (default)
    Metadata:
      encoder         : Lavc57.107.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
frame=  301 fps= 45 q=-1.0 Lsize=    1417kB time=00:00:04.96 bitrate=2336.4kbits/s speed=0.735x    
video:1412kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.309675%
[libx264 @ 0x7f8625800c00] frame I:2     Avg QP:13.08  size:  8842
[libx264 @ 0x7f8625800c00] frame P:75    Avg QP:24.29  size:  6785
[libx264 @ 0x7f8625800c00] frame B:224   Avg QP:26.38  size:  4102
[libx264 @ 0x7f8625800c00] consecutive B-frames:  0.7%  0.0%  1.0% 98.3%
[libx264 @ 0x7f8625800c00] mb I  I16..4: 68.1% 28.7%  3.2%
[libx264 @ 0x7f8625800c00] mb P  I16..4:  0.1%  2.2%  0.4%  P16..4:  6.5%  4.0%  1.4%  0.0%  0.0%    skip:85.4%
[libx264 @ 0x7f8625800c00] mb B  I16..4:  0.0%  0.2%  0.0%  B16..8:  8.8%  3.0%  0.3%  direct: 0.3%  skip:87.3%  L0:52.1% L1:47.5% BI: 0.4%
[libx264 @ 0x7f8625800c00] 8x8 transform intra:57.7% inter:67.8%
[libx264 @ 0x7f8625800c00] coded y,uvDC,uvAC intra: 25.7% 8.7% 0.9% inter: 3.9% 0.4% 0.0%
[libx264 @ 0x7f8625800c00] i16 v,h,dc,p: 95%  2%  3%  0%
[libx264 @ 0x7f8625800c00] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 17%  5% 48%  5%  7%  6%  5%  4%  3%
[libx264 @ 0x7f8625800c00] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 20% 14% 31%  6%  7%  7%  6%  5%  4%
[libx264 @ 0x7f8625800c00] i8c dc,h,v,p: 88%  6%  6%  0%
[libx264 @ 0x7f8625800c00] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x7f8625800c00] ref P L0: 55.3%  5.5% 24.8% 14.5%
[libx264 @ 0x7f8625800c00] ref B L0: 75.6% 16.7%  7.7%
[libx264 @ 0x7f8625800c00] ref B L1: 93.9%  6.1%
[libx264 @ 0x7f8625800c00] kb/s:2304.86

Any idea on how to overcome this quality loss?

turboLoop
  • 601
  • 1
  • 4
  • 16

1 Answers1

24

Changing -qscale 1 to -crf 1 resolves the quality issue. The working command is:

ffmpeg -i video.webm -crf 1 -c:v libx264 video.mp4

As outlined in the H.264 Video Encoding Guide -crf takes in values from 0 (lossless) to 51 (worst quality).

turboLoop
  • 601
  • 1
  • 4
  • 16
  • 7
    Overkill. Try ~17. – llogan Mar 22 '18 at 17:50
  • 1
    why did you use 1 instead of 0 for the quality value? – Crashalot Jan 09 '21 at 09:40
  • @llogan thanks for the suggestion. is there some heuristic for what quality value to use? – Crashalot Jan 09 '21 at 09:41
  • 6
    @Crashalot `-crf 17` or `-crf 18` is considered "visually lossless", according to the link in the answer, which should provide an acceptable quality for the original question without the massive file size that true lossless (`-crf 0`) would provide. – llogan Jan 09 '21 at 18:38
  • thanks for the clarification and for teaching so many people on SO about ffmpeg. one more q if you don't mind: if we create a browser-based video editor with animating text, do you see any problems with creating webm in canvas then converting to mp4, mov, and other formats with ffmpeg on the server? could post separately as a question if you prefer. – Crashalot Jan 09 '21 at 19:36