Skip to content

Instantly share code, notes, and snippets.

@maximebories
Last active May 6, 2025 15:49
Show Gist options
  • Save maximebories/91d79c0ec25fd3f990615dcf355de8eb to your computer and use it in GitHub Desktop.
Save maximebories/91d79c0ec25fd3f990615dcf355de8eb to your computer and use it in GitHub Desktop.
FFmpeg command to convert webm to mp4 video files

WebM to MP4 using FFmpeg

This FFmpeg command converts a .webm video file to a standard .mp4 file using the libx264 codec for video, aac codec for audio, and a CRF value of 22. The preset is set to 'slow' for higher quality encoding, and the audio bitrate is set to 128 kbps.

If the input and output filenames don't contain spaces, quotation marks or other special characters:

ffmpeg -i input.webm -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k output.mp4

Or escape spaces using backslashes

ffmpeg -i input\ with\ spaces.webm -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k output\ with\ spaces.mp4

Or use quotation marks in any other cases:

ffmpeg -i "input with spaces.webm" -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k "output with spaces.mp4"

Explanation:

-i input.webm: Specifies the input WebM file (use quotes or backslashes for spaces). -c:v libx264: Uses the libx264 encoder for video (widely compatible). -preset slow: Prioritizes quality over speed (consider 'medium' for faster encodes). -crf 22: Sets Constant Rate Factor (lower values mean higher quality, typically 18-28 is good). -c:a aac: Encodes audio with AAC (common and efficient). -b:a 128k: Sets audio bitrate to 128 kbps (adjust based on needs). output.mp4: Names the output MP4 file (use quotes or backslashes for spaces).

Alternatives & common values:

Video codec alternative to libx264:

  • libx265 (for even better compression, but may require more processing power)

Audio codec alternative to AAC and common bitrates:

  • libopus (modern, efficient codec) at 64k, 96k, 128k (for music), or even lower for speech-only content
  • mp3 (widely supported, but less efficient than AAC or Opus) at 128k, 192k, 256k

Potential enhancements:

1. Copying metadata:

ffmpeg -i "input with spaces.webm" -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k -map_metadata 0 "output with spaces.mp4"

2. Scaling video (if needed):

# ffmpeg -i "input with spaces.webm" -vf scale=1280:-2 -c:v libx264 ... 

3. Hardware acceleration (if available):

# ffmpeg -hwaccel auto -i "input with spaces.webm" ... 

4. Two-pass encoding (for even better quality, but slower):

# ffmpeg -i "input with spaces.webm" -c:v libx264 -preset slow -crf 22 -pass 1 -f mp4 /dev/null
# ffmpeg -i "input with spaces.webm" -c:v libx264 -preset slow -crf 22 -pass 2 "output with spaces.mp4"

Remember:

  • Experiment with CRF and audio bitrate for your specific needs.
  • Consider hardware acceleration for faster encodes on supported systems.
  • Two-pass encoding offers the best quality but takes longer.
@Nour-MK
Copy link

Nour-MK commented Apr 15, 2024

note that there must not be spaces in the name of the .webm file to be converted. it causes the command to fail.

@StipJey
Copy link

StipJey commented Apr 25, 2024

Respect, bro!

@bdhowell
Copy link

bdhowell commented Sep 7, 2024

You can always enclose Unix filenames in quotes. That should solve Nour-MK's problem.

@kasir-barati
Copy link

kasir-barati commented Sep 21, 2024

Convert webm to mp4

This worked really well for me: ffmpeg -i screen-capture.webm -c:v copy -c:a aac -b:a 128k output.mp4.

Merge 2+ mp4 files together with ffmpeg

BTW if you also wanted to concat two or more mp4 files you can do the following:

  1. Create a text file called inputs.txt.

  2. Use file command + each mp4 file path. E.g.

    file '/home/userName/first.mp4'
    file '/home/userName/second.mp4'
    

    Remember that the order here matters. In this example it will append the second.mp4 to first.mp4.

  3. cd to where this inputs.txt is located and execute this command:

    ffmpeg -f concat -safe 0 -i inputs.txt -c copy output.mp4
    

@toLog
Copy link

toLog commented Apr 3, 2025

Convert webm to mp4

This worked really well for me: ffmpeg -i screen-capture.webm -c:v copy -c:a aac -b:a 128k output.mp4.

Merge 2+ mp4 files together with ffmpeg

BTW if you also wanted to concat two or more mp4 files you can do the following:

  1. Create a text file called inputs.txt.

  2. Use file command + each mp4 file path. E.g.

    file '/home/userName/first.mp4'
    file '/home/userName/second.mp4'
    

    Remember that the order here matters. In this example it will append the second.mp4 to first.mp4.

  3. cd to where this inputs.txt is located and execute this command:

    ffmpeg -f concat -safe 0 -i inputs.txt -c copy output.mp4
    

The resulting file will have low compatibility, unfortunately. Most systems want MP4 video tracks to be one out of of a certain set of formats despite the MIME MPEG-4 standards not prescribing any particular video codecs for the MIME type.

@0xRake
Copy link

0xRake commented Apr 25, 2025

Thought it'd be more effective to optimize this into a shell function.

Description

Basically what code snippet does is:

  • By calling the webm2mp4 function your .webm file will be converted and outputted toas a high quality h.264 + 320kbps aac mp4 file. (I've got a preference towards higher quality files therefore the modifications...)
webm2mp4(){
  (( $# < 1 )) && { echo "Usage: webm2mp4 input.webm [output.mp4]"; return 1; }
  local in="$1"; shift
  local out="${1:-${in%.webm}.mp4}"
  ffmpeg -i "$in" \
    -c:v libx264 -preset slow -crf 18 \
    -c:a aac -b:a 320k \
    -movflags +faststart \
    "$out"
}

Usage example in a nutshell is as follows (after having included the function with you shellrc file and having sourced the rc file):

webm2mp4 input.webm               # clip.mp4
webm2mp4 input.webm renamed.mp4   # renamed.mp4

@dassimanuel000
Copy link

New error

ffmpeg -i "Screencast2025-05-01-19-16-13.webm" -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k -map_metadata 0 "output with spaces.mp4"
ffmpeg version N-119207-g93ae305ce1 Copyright (c) 2000-2025 the FFmpeg developers
built with gcc 13 (Ubuntu 13.3.0-6ubuntu2~24.04)
configuration: --enable-gpl --enable-libx264 --enable-libx265 --enable-libvpx --enable-libfdk-aac --enable-libmp3lame --enable-libopus --enable-libass --enable-libfreetype --enable-libvorbis --enable-nonfree
libavutil 60. 1.100 / 60. 1.100
libavcodec 62. 0.101 / 62. 0.101
libavformat 62. 0.100 / 62. 0.100
libavdevice 62. 0.100 / 62. 0.100
libavfilter 11. 0.100 / 11. 0.100
libswscale 9. 0.100 / 9. 0.100
libswresample 6. 0.100 / 6. 0.100
libpostproc 59. 0.100 / 59. 0.100
Input #0, matroska,webm, from 'Screencast2025-05-01-19-16-13.webm':
Metadata:
encoder : GStreamer matroskamux version 1.24.2
creation_time : 2025-05-01T17:16:14.191804Z
Duration: 00:00:42.86, start: 0.018000, bitrate: 2410 kb/s
Stream #0:0(eng): Video: vp8, yuv420p(tv, bt709, progressive), 1349x914, SAR 1:1 DAR 1349:914, 1k tbr, 1k tbn (default)
Metadata:
title : Video
[out#0/mp4 @ 0x62923fd11d40] Codec AVOption b:a (set bitrate (in bits/s)) has not been used for any stream. The most likely reason is either wrong type (e.g. a video option with no video streams) or that it is a private option of some decoder which was not actually used for any stream.
Stream mapping:
Stream #0:0 -> #0:0 (vp8 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x62923fd12780] width not divisible by 2 (1349x914)
[vost#0:0/libx264 @ 0x62923fd12200] [enc:libx264 @ 0x62923fd12700] Error while opening encoder - maybe incorrect parameters such as bit_rate, rate, width or height.
[vf#0:0 @ 0x62923fd12d00] Error sending frames to consumers: Generic error in an external library
[vf#0:0 @ 0x62923fd12d00] Task finished with error code: -542398533 (Generic error in an external library)
[vf#0:0 @ 0x62923fd12d00] Terminating thread with return code -542398533 (Generic error in an external library)
[vost#0:0/libx264 @ 0x62923fd12200] [enc:libx264 @ 0x62923fd12700] Could not open encoder before EOF
[vost#0:0/libx264 @ 0x62923fd12200] Task finished with error code: -22 (Invalid argument)
[vost#0:0/libx264 @ 0x62923fd12200] Terminating thread with return code -22 (Invalid argument)
[out#0/mp4 @ 0x62923fd11d40] Nothing was written into output file, because at least one of its streams received no packets.
frame= 0 fps=0.0 q=0.0 Lsize= 0KiB time=N/A bitrate=N/A speed=N/A
Conversion failed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment