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

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,292
  • 133
  • 301
  • 332
-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