webm to mp4 conversion using ffmpeg
Asked Answered
S

6

160

When I try to convert a webm file to mp4 the output is very very choppy and it appears as if many frames have been dropped by ffmpeg

I used the following commands to convert

ffmpeg -i movie.webm movie.mp4
ffmpeg -i movie.webm -vcodec libx264 movie.mp4
ffmpeg -i movie.webm -vcodec libx264 -qscale 0 movie.mp4

All of them have the same problem. When I use ffprobe it seems to show the frames more or less properly.

UPDATE:

 built on Jun 14 2013 14:31:50 with gcc 4.7 (Ubuntu/Linaro 4.7.2-2ubuntu1)
  configuration: --prefix=/home/user2/ffmpeg_build --extra-cflags=-I/home/user2/ffmpeg_build/include --extra-ldflags=-L/home/pavan4/ffmpeg_build/lib --bindir=/home/pavan4/bin --extra-libs=-ldl --enable-gpl --enable-libass --enable-libfdk-aac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-x11grab
  libavutil      52. 35.101 / 52. 35.101
  libavcodec     55. 16.100 / 55. 16.100
  libavformat    55.  8.102 / 55.  8.102
  libavdevice    55.  2.100 / 55.  2.100
  libavfilter     3. 77.101 /  3. 77.101
  libswscale      2.  3.100 /  2.  3.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  3.100 / 52.  3.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

Use -h to get full help or, even better, run 'man ffmpeg'

Input #0, matroska,webm, from '1.webm':
  Duration: 00:00:10.64, start: 0.000000, bitrate: 5024 kb/s
    Stream #0:0(eng): Video: vp8, yuv420p, 1280x720, SAR 1:1 DAR 16:9, 1k fps, 1k tbr, 1k tbn, 1k tbc (default)
[libx264 @ 0x1d966a0] using SAR=1/1
[libx264 @ 0x1d966a0] MB rate (3600000) > level limit (2073600)
[libx264 @ 0x1d966a0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
[libx264 @ 0x1d966a0] profile High, level 5.2
[libx264 @ 0x1d966a0] 264 - core 133 r2 a3ac64b - H.264/MPEG-4 AVC codec - Copyleft 2003-2013 - 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=12 lookahead_threads=2 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 '1_conv4.mp4':
  Metadata:
    encoder         : Lavf55.8.102
    Stream #0:0(eng): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=-1--1, 16k tbn, 1k tbc (default)
Stream mapping:
Stream #0:0 -> #0:0 (vp8 -> libx264)
Press [q] to stop, [?] for help
frame=  168 fps=0.0 q=33.0 size=      62kB time=00:00:00.11 bitrate=4606.0kbits/frame=  293 fps=230 q=33.0 size=     138kB time=00:00:00.23 bitrate=4809.7kbits/

video:5620kB audio:0kB subtitle:0 global headers:0kB muxing overhead 2.212461%
[libx264 @ 0x1d966a0] frame I:46    Avg QP:18.50  size: 39849
[libx264 @ 0x1d966a0] frame P:2940  Avg QP:18.27  size:  1222
[libx264 @ 0x1d966a0] frame B:7651  Avg QP:17.68  size:    43
[libx264 @ 0x1d966a0] consecutive B-frames:  4.0%  0.2%  0.3% 95.5%
[libx264 @ 0x1d966a0] mb I  I16..4: 19.9% 63.2% 16.9%
[libx264 @ 0x1d966a0] mb P  I16..4:  0.2%  0.5%  0.1%  P16..4:  3.9%  1.1%  0.6%  0.0%  0.0%    skip:93.6%
[libx264 @ 0x1d966a0] mb B  I16..4:  0.0%  0.0%  0.0%  B16..8:  0.2%  0.0%  0.0%  direct: 0.0%  skip:99.8%  L0:25.1% L1:74.9% BI: 0.0%
[libx264 @ 0x1d966a0] 8x8 transform intra:63.6% inter:75.9%
[libx264 @ 0x1d966a0] coded y,uvDC,uvAC intra: 61.5% 53.4% 24.4% inter: 0.5% 0.5% 0.0%
[libx264 @ 0x1d966a0] i16 v,h,dc,p: 52% 19% 19% 11%
[libx264 @ 0x1d966a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 32% 17% 13%  4%  6%  9%  5%  8%  6%
[libx264 @ 0x1d966a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 30% 18% 14%  5%  8% 10%  6%  6%  3%
[libx264 @ 0x1d966a0] i8c dc,h,v,p: 55% 17% 24%  4%
[libx264 @ 0x1d966a0] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x1d966a0] ref P L0: 82.5% 13.2%  4.0%  0.3%
[libx264 @ 0x1d966a0] ref B L0: 60.2% 39.2%  0.6%
[libx264 @ 0x1d966a0] ref B L1: 98.5%  1.5%
[libx264 @ 0x1d966a0] kb/s:4327.77
Syreetasyria answered 8/8, 2013 at 10:14 Comment(7)
A general comment about "how to ask", please add at least one of your ffmpeg command line output to see ffmpeg version and all remaining information about your input file stream to your output file stream mapping.Light
@Light I updated the post :) I thought I was doing something trivial so didnt add the output.Syreetasyria
it shouldn't be so trivial, I just ran the same kind of conversion with ffmpeg ` built on Jun 4 2013 01:41:53 with gcc 4.7.3 (GCC)` without issue, mp4 on the output have a correct quality. Don't know how to help :(Light
@Light can you maybe try it on the file I have and let me know if it converts alright! link is here filetea.me/t1sAnxNr3xNQl22bPYc7nB59QSyreetasyria
sorry but that link doesn't work! Just got an empty web page.Light
@Light sorry I had to restart and i thought the link is persistent.. here you go again filedropper.com/1_25Syreetasyria
let us continue this discussion in chatLight
L
179

As your input file report a strange frame rate value 1k fps coming from the tbs and tbr value (look here for their definition)

the encoder generate a different result, 16k tbn, 1k tbc (default)

So by calling :

ffmpeg -fflags +genpts -i 1.webm -r 24 1.mp4

You configure ffmpeg to generate new pts (a.k.a Presentation TimeStamp) for each frame and you set the target frame-rate to 24.

So your output mp4 file info (ffmpeg -i ....) change from

Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 4327 kb/s, 1000.09 fps, 1k tbr, 16k tbn, 2k tbc

to

Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1670 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc
Light answered 9/8, 2013 at 14:13 Comment(4)
I just noticed this that for the mp4 ffmpeg automatically changes the bitrate to 2M while the source is at 5M. Can I set automatically the bitrate to be chosen from the source?Syreetasyria
no idea, it's a recurrent question on SOF and SuperUser, but ask again someone may have a solution, on my side i would put every line in a script, to first run a ffmpeg -i on the input, catching&parsing the command line output to find the bitrate, and after reuse that value the set the -b:v value to transcode...Light
this mp4 file is not playable on browser, why?Ferrol
Something isnt right with this file and can't be played even with Quicktime. I wish it did work.Dulcinea
E
73

Re-mux WebM to MP4

If you want to stream copy (re-mux) and avoid re-encoding:

ffmpeg -i input.webm -c copy output.mp4

This will copy the VP9/VP8 video and Opus/Vorbis audio from WebM to MP4. This is like a "copy and paste". No re-encoding occurs, so no quality is lost and the process is very fast.

(Note that if you were copying only the video and not the audio, you would use -c:v copy instead of -c copy. Point being, the -c part is the same meaning in both cases.)

If you get error: "opus in MP4 support is experimental"

If you get this error:

opus in MP4 support is experimental, add '-strict -2' if you want to use it.
Could not write header for output file #0 (incorrect codec parameters ?): Experimental feature

Then either:

  • Use a newer ffmpeg as Opus in MP4 is no longer experimental in newer ffmpeg versions.
  • Or add -strict experimental (or the alias -strict -2) if you are stuck with outdated ffmpeg.
Evident answered 27/2, 2020 at 23:20 Comment(4)
This should be the accepted answer, IMHO. Re-encoding must be avoided unless otherwise absolutely necessary.Susurrous
Doesn't work, I keep getting this error: [mp4 @ 0x5608e2b2ca00] Could not find tag for codec vp8 in stream #0, codec not currently supported in container. Could not write header for output file #0 (incorrect codec parameters ?): Invalid argumentEnarthrosis
The -strict -2 is sensitive to placement within the ffmpeg command line. Neither leading (ffmpeg -strict -2 ...) nor trailing (ffmpeg ... -strict -2) worked. Adding it after the first argument, did: ffmpeg -i input.webm -strict -2 -c copy output.mp4.Emmerie
Be aware that, using the "Re-Mux" method, you may end up with undesirable codecs...Meghan
B
36

I summarize here the results of converting from webm to mp4 using the many command line options suggested.

We assume here that if you're asking this question, then you're forced to use webm because the Android device emulator within Android Studio generated it for you, and you're on a Mac so you'd really like to use iMovie to edit the video.

1 ffmpeg -i vid.webm vid-1.mp4 Ref Takes 17.8 sec. Output file is 1.5 MB.

2 ffmpeg -i vid.webm -crf 1 -c:v libx264 vid-2.mp4 Takes 18 sec. Output file is 7.6 MB.

3 ffmpeg -i vid.webm -crf 0 -c:v libx264 vid-3.mp4 Ref Takes 21 sec. Output file is 11.9 MB.

4 ffmpeg -fflags +genpts -i vid.webm -r 24 vid-4.mp4 Ref Takes 0.16 sec. Output file is 1.5 MB.

5 ffmpeg -i vid.webm -c copy vid-5.mp4 Ref Takes 2.8 sec. Output file is 64.6 MB.

6 ffmpeg -i vid.webm -strict experimental vid-6.mp4 Ref Takes 18 sec. Output file is 1.5 MB.

7 ffmpeg -i vid.webm -c copy -strict experimental vid-7.mp4 Ref Takes 0.16 sec. Output file is 64.6 MB.

8 ffmpeg -i vid.webm -c:v copy -strict experimental vid-8.mp4 Also Ref Takes 0.69 sec. Output file is 64.5 MB.

Only numbers 1, 2, 3, 4, and 6 can be imported to iMovie (10.2).

The version of ffmpeg used is 4.3.

This is a first step. I am leaving out the more complicated quality comparison.

Perhaps the worst trap waiting for you is that iMovie really wants to produce a 1920x1080 movie, and so you may well get two large black bars on the side. If you're editing a demo of your app in portrait mode, you'll be wasting a lot of space. If you can, ideally you'll want to produce a video in that resolution.

The most immediate sequel question is: Assuming you truly have no need for the heavily pushed Final Cut Pro (because you're a programmer, not a video editor), will FCP allow you to set your own resolution?

Bullpen answered 1/2, 2021 at 16:38 Comment(5)
I dont see how this comparison is useful without specifying what was the size of the INPUT file.Accurate
My favorite option number 4 - quick and small result: ffmpeg -fflags +genpts -i vid.webm -strict experimental -r 24 vid-4.mp4Moonmoonbeam
what is the " -crf 1" part? I did a "man ffmpeg" and that option wasn't listed. My ffmpeg is on debian - "ffmpeg version 4.3.3-0+deb11u1 Copyright (c) 2000-2021 the FFmpeg developers "Iphigenia
Option 4 runs slow for me. Anyone know why?Dulcinea
ffmpeg -i A211.webm -vcodec libx265 -crf 30 -c:a copy -strict experimental A211.mp4; did it in 1.09s for me but with a black screen, also did all commands aboveLecialecithin
B
16

I was able to convert byffmpeg -i video.webm -strict experimental video.mp4.

Busload answered 27/2, 2020 at 5:37 Comment(5)
-strict experimental is not needed when re-encoding to MP4 as in your example. However, it is needed if you want to re-mux VP8/VP9 into MP4 by adding -c copy.Evident
@Ilogn, I tried yesterday without strict option, but I wasn't able to convert. Please, try the video at Electric Car...it's a webm format video.Busload
Works fine for me without -strict. I'm assuming you are getting the error The encoder 'aac' is experimental but experimental codecs are not enabled. This indicates that your ffmpeg is very old: recent versions do not need -strict to encode with the native FFmpeg AAC encoder.Evident
@Evident I'm using the lastest version of FFmpeg(4.2) but still facing that errorUnnumbered
@AminShojaei Because you are adding -c copy or -c:a copy or -c:a libopus to put Opus audio into MP4. This combination was consider experimental, but not anymore if you update to FFmpeg 4.3.Evident
E
3

After some hours of testing i was able to convert a matroska/webm (Input #0, matroska,webm, from 'testit1.webm') input to a mp4 output (Output #0, mp4, to 'testit1.mp4'). The video was recorded with the mediarecorder in chrome.

ffmpeg -i testit1.webm -c copy -strict experimental testit1.mp4

However by doing this we kept the small size of the webm video. But we did't have any audio. To get the audio working we used:

ffmpeg -i testit1.webm -c:v copy -strict experimental testit1.mp4

Hope this helps if you are in the same boat.

E answered 30/6, 2020 at 13:57 Comment(0)
I
2

You can place the file paths in a text file and then do this loop:

while read line; do ffmpeg -i "$line" -c:v libx264 -y "${line%.webm}.mp4" ;done < convert_us.txt

Note that the -c:v part is optional and ensures the video code is h.264.

Iphigenia answered 15/5, 2022 at 20:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.