8

Gnome has a built-in screencast tool using ctrl plus shift plus alt plus R. It's a great tool with consistent quality video output!

But, I need the output in mp4. I have tried this: ffmpeg -i screencast.webm -crf 0 screencast.mp4 as specified in other AskUbuntu posts, but it doesn't work well for me, even though it's supposed to be lossless.

My screencast in mp4 jumps around, freezes on a single frame, and the file sizes are drastically different.

I need h.264 mp4, ideally with a constant frame rate, at high definition.

What ffmpeg command can I use?

Here's an example file: ffmpeg -i input.webm

$ ffmpeg -i Screencast\ from\ 03-18-2023\ 04\:57\:59\ PM.webm 
ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
  configuration: --prefix=/usr --extra-version=0ubuntu0.22.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  WARNING: library configuration mismatch
  avcodec     configuration: --prefix=/usr --extra-version=0ubuntu0.22.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared --enable-version3 --disable-doc --disable-programs --enable-libaribb24 --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libtesseract --enable-libvo_amrwbenc --enable-libsmbclient
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, matroska,webm, from 'Screencast from 03-18-2023 04:57:59 PM.webm':
  Metadata:
    encoder         : GStreamer matroskamux version 1.20.3
    creation_time   : 2023-03-18T20:57:59.129336Z
  Duration: 00:16:48.47, start: 0.028000, bitrate: 858 kb/s
  Stream #0:0(eng): Video: vp8, yuv420p(tv, bt709, progressive), 1920x1080, SAR 1:1 DAR 16:9, 1k tbr, 1k tbn, 1k tbc (default)
    Metadata:
      title           : Video
At least one output file must be specified

  • 1
    Can you post the command itself and subsequent full terminal output for this command: ffmpeg -i screencast.webm and then it should be a simple matter to suggest the appropriate FFmpeg command... – andrew.46 Mar 20 '23 at 04:37
  • Updated! Thanks : ) – Costa Michailidis Mar 21 '23 at 05:07
  • 1
    Interestingly enough a VP8 video stream should be ok in an mp4 container so only remuxing is required: ffmpeg -i input.webm -c:v copy output.mp4 Support for VP8/9 in mp4 has been around a while but just check that your copy of FFmpeg is new enough to do this and that your playback application is also happy... – andrew.46 Mar 21 '23 at 06:17
  • And what happens to frame rates? It's variable in webm, and I'd need constant in mp4, no? – Costa Michailidis Mar 21 '23 at 18:48
  • 1
    I don't know. I would recommend a test run and see if FFmpeg will sort it out for you :). On a test encode here on my local machine there were no issues but best to test on your own setup... – andrew.46 Mar 23 '23 at 05:34
  • The frame rate is precisely one issue. There's no frame rate specified in the default [Screencast*].webm and Video Scan Type comes across as Unknown (2) on my 22.04 setup. ffmpeg works when setting frame rate explicitly:

    ffmpeg -i screencast.webm -filter:v "fps=30" screencast.mp4

    I've added more detail and options in my answer to this Q. Thank you, @andrew.46

    – smcnally Apr 08 '23 at 21:04

3 Answers3

11

This works to output your screencast as an mp4 that plays as expected in VLC and others:

ffmpeg -i screencast.webm -filter:v "fps=30" screencast.mp4

This works in more cases and avoids ffmpeg throwing 'not divisible by 2' errors:

ffmpeg -i screencast.webm -filter:v "scale=trunc(iw/2)*2:trunc(ih/2)*2,fps=30" screencast.mp4

The above sets a constant frame rate of 30 frames per second (fps). It resizes your video by one pixel at most and makes sure your input width and height (iw and ih) are even numbers.

You can also specify codec options like -codec:v libx264. Check out ffmpeg's Video Options for your particulars.

Your questions and related Q&A I've found helpful during this research include these:

smcnally
  • 470
0

Here's a script I wrote for this same issue I was facing:

It's a simple bash script that watches the screencast directory and automatically converts new entries to mp4 every time you screencast. You can add it to your startup apps and get an mp4 screencast every time you screen record. it's fully configurable!

It uses ffmpeg and inotify libraries to convert the files with options for quality, and shows native Linux notifications about progress and completion of file conversion respectively.

GitHub

Just follow the instructions.

karel
  • 122,695
  • 134
  • 305
  • 337
-1

Here is a bash file to do it for you. Based @smcanlly answer.

create a file called webm2mp4.sh

#!/bin/bash

Check if a file was provided as an argument

if [ $# -eq 0 ]; then echo "Error: No input file provided" echo "Usage: $0 <input_file.webm>" exit 1 fi

Get the input file name

input_file="$1"

Check if the input file exists

if [ ! -f "$input_file" ]; then echo "Error: File '$input_file' not found" exit 1 fi

Check if the input file has a .webm extension

if [[ "$input_file" != *.webm ]]; then echo "Error: Input file must have a .webm extension" exit 1 fi

Generate the output file name by replacing .webm with .mp4

output_file="${input_file%.webm}.mp4"

Convert the file using ffmpeg

ffmpeg -i "$input_file" -filter:v "fps=30" "$output_file"

Check if the conversion was successful

if [ $? -eq 0 ]; then echo "Conversion successful: $input_file -> $output_file" else echo "Error: Conversion failed" exit 1 fi

Make sure to chmod +x ./webm2mp4.sh Then to use just run webm2mp4.sh some-video.webm