-- Leo's gemini proxy

-- Connecting to gmi.noulin.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

Encoding videos in AV1, h264 and mpeg2 with FFmpeg


Feed


date: 2024-01-04 19:25:21


categories: linux


firstPublishDate: 2022-05-25 07:54:25


I don't encode many videos but I want to try the newest video and audio codecs:


AV1 Wikipedia


Opus Wikipedia


AV1 is implemented in libaom and svt-av1. Libaom is the reference codec, it produces smaller files than svt-av1 but it is slow. The svt-av1 encoder is optimized for speed and produces bigger files than libaom.


I usually encode videos in 2 passes, libaom uses my 16 cores at 33% in pass 1 while svt-av1 uses the 16 cores at 100%. In pass 2, libaom uses 2 cores at 100% and svt1-av1 uses the 16 cores at 100%.


The CPU is an Intel i7 (2021)


I encode my videos with libaom to get smaller files for a given quality because it takes a finite time to encode and I will store the videos forever.


I film with my iPhone in 4k 60 fps hevc and I don't have a computer that can play these videos so I also scale down the resolution.


Encoding the iPhone videos in h264 (using the parameters below) make them 20 times smaller, I transfer back to the videos to iPhone to save space and avoid having to use iCloud.


Install


I installed FFmpeg and libaom from apt but I don't recommend doing this because it is better to use the latest AV1 encoders.


apt-get install ffmpeg libaom0 libaom-dev nasm yasm libx264-dev libx265-dev libnuma-dev libfdk-aac-dev libopus-dev libass-dev libdav1d-dev libmp3lame-dev libvorbis-dev libvpx-dev

Instead, I compile FFmpeg from source:


git clone --depth 1 https://aomedia.googlesource.com/aom
commit ef14518388c0a41c1d3b992f75d5886c9da33832
mk build
cmake -G "Unix Makefiles" -DENABLE_TESTS=OFF -DENABLE_NASM=on ../
make -j30
sudo make install

git clone --depth=1 https://gitlab.com/AOMediaCodec/SVT-AV1.git
commit 8c2621f75a5d6bc4b719b46fb6b17701a6f3fe1d
cd SVT-AV1
cd Build
cmake .. -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
make -j 30
sudo make install

git clone https://git.ffmpeg.org/ffmpeg.git
commit f1c19867d72a14699277175101b2bcf1e333af88
./configure \
  --pkg-config-flags="--static" \
  --extra-libs="-lpthread -lm" \
  --ld="g++" \
  --bindir="$HOME/bin" \
  --enable-gpl \
  --enable-libaom \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libfreetype \
  --enable-libmp3lame \
  --enable-libopus \
  --enable-libdav1d \
  --enable-libvorbis \
  --enable-libvpx \
  --enable-libx264 \
  --enable-libx265 \
  --enable-nonfree
make -j30

Video Information


To show the information about a video file, use `ffprobe`:


ffprobe filename
# ffprobe prints stderr, redirect to be able to grep
ffprobe filename 2>&1 | grep displaymatrix

# result
ffprobe version N-106826-gf1c19867d7 Copyright (c) 2007-2022 the FFmpeg developers
  built with gcc 10 (Debian 10.2.1-6)
  configuration: --pkg-config-flags=--static --extra-libs='-lpthread -lm' --ld=g++ --bindir=/home/user/bin --enable-gpl --enable-libaom --enable-libsvtav1 --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libdav1d --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree
  libavutil      57. 24.101 / 57. 24.101
  libavcodec     59. 27.100 / 59. 27.100
  libavformat    59. 23.100 / 59. 23.100
  libavdevice    59.  6.100 / 59.  6.100
  libavfilter     8. 38.100 /  8. 38.100
  libswscale      6.  6.100 /  6.  6.100
  libswresample   4.  6.100 /  4.  6.100
  libpostproc    56.  5.100 / 56.  5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/user/AIphoneUpload/IMG_1819.MOV':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    creation_time   : 2022-11-18T17:37:37.000000Z
    com.apple.quicktime.location.accuracy.horizontal: 35.000000
    com.apple.quicktime.location.ISO6709: +55.7093+013.2177+065.187/
    com.apple.quicktime.make: Apple
    com.apple.quicktime.model: iPhone 12 Pro Max
    com.apple.quicktime.software: 15.7.1
    com.apple.quicktime.creationdate: 2022-11-18T18:37:36+0100
  Duration: 00:00:24.59, start: 0.000000, bitrate: 67647 kb/s
  Stream #0:0[0x1](und): Video: hevc (Main 10) (hvc1 / 0x31637668), yuv420p10le(tv, bt2020nc/bt2020/arib-std-b67), 3840x2160, 67375 kb/s, 59.99 fps, 60 tbr, 600 tbn (default)
    Metadata:
      creation_time   : 2022-11-18T17:37:37.000000Z
      handler_name    : Core Media Video
      vendor_id       : [0][0][0][0]
      encoder         : HEVC
    Side data:
      DOVI configuration record: version: 1.0, profile: 8, level: 10, rpu flag: 1, el flag: 0, bl flag: 1, compatibility id: 4
      displaymatrix: rotation of -90.00 degrees
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 159 kb/s (default)
    Metadata:
      creation_time   : 2022-11-18T17:37:37.000000Z
      handler_name    : Core Media Audio
      vendor_id       : [0][0][0][0]
  Stream #0:2[0x3](und): Data: none (mebx / 0x7862656D), 0 kb/s (default)
    Metadata:
      creation_time   : 2022-11-18T17:37:37.000000Z
      handler_name    : Core Media Metadata
  Stream #0:3[0x4](und): Data: none (mebx / 0x7862656D), 11 kb/s (default)
    Metadata:
      creation_time   : 2022-11-18T17:37:37.000000Z
      handler_name    : Core Media Metadata
  Stream #0:4[0x5](und): Data: none (mebx / 0x7862656D), 72 kb/s (default)
    Metadata:
      creation_time   : 2022-11-18T17:37:37.000000Z
      handler_name    : Core Media Metadata

The important line in the ffprobe output is:


      displaymatrix: rotation of -90.00 degrees

It tells me if I should rotate the video.


Encoding


For DVD resolution (720x576), I use a bitrate of 650kb/s

For 4k fps 60 resolution, I use a bitrate of 2mb/s, the quality seems correct but I can't really check because it takes 15s to decode a frame.


It is quite slow to encode with libaom:


for 1s of UHD 60fps video, it takes about 1 hour.

for 1s of HD video, it takes 10 minutes

for 1s of DVD video, it takes 2 minutes


The SVT-AV1 encoder is 300 times faster than libaom-av1.


For more information about the encoding option for AV1 in FFmpeg, check out:

AV1 FFmpeg Video Encoding Guide


The setup of svt-av1 is not perfect, I get this error:


ffmpeg: error while loading shared libraries: libSvtAv1Enc.so.1: cannot open shared object file: No such file or directory

In order to find libsvtav1, update LD_LIBRARY_PATH:


export LD_LIBRARY_PATH+=":/usr/local/lib"
# run ffmpeg

I encode videos with 2 pass in order to improve the image quality.


DVD


I created a test video file by cutting 10s of a DVD with FFmpeg:


ffmpeg -i example.VOB -ss 00:10:00 -to 00:10:30 -c copy y.VOB

To encode with libaom:


ffmpeg -i y.VOB -c:v libaom-av1 -b:v 650k -pass 1 -an -f null /dev/null && \
ffmpeg -i y.VOB -c:v libaom-av1 -b:v 650k -pass 2 -ac 2 -c:a libopus y.mkv

To encode with svt1av1:


ffmpeg -i y.VOB -c:v libsvtav1 -b:v 650k -pass 1 -an -f null /dev/null && \
ffmpeg -i y.VOB -c:v libsvtav1 -b:v 650k -pass 2 -ac 2 -c:a libopus y.mkv

I encountered an error encoding a DVD with audio in AC3 5.1 and libopus:


[libopus @ 0x55896ce87c80] Invalid channel layout 5.1(side) for specified mapping family -1.
Error initializing output stream 0:1 -- Error while opening encoder for output stream #0:1 - maybe incorrect parameters such as bit_rate, rate, width or height

To solve this, I add the `-ac 2` option to have the output in 2 streams (stereo).


4k 60 fps


To encode with libaom:


ffmpeg -i IMG_1454.MOV -c:v libaom-av1 -b:v 2000k -pass 1 -an -f null /dev/null && \
ffmpeg -i IMG_1454.MOV -c:v libaom-av1 -b:v 2000k -pass 2 -ac 2 -c:a libopus y.mkv

To encode with svtav1:


ffmpeg -i IMG_1454.MOV -c:v libsvtav1 -b:v 2000k -pass 1 -an -f null /dev/null && \
ffmpeg -i IMG_1454.MOV -c:v libsvtav1 -b:v 2000k -pass 2 -ac 2 -c:a libopus y.mkv

The option for scaling the video is `-vf scale=`:


ffmpeg -i IMG_1454.MOV -vf scale=720:576 -c:v libsvtav1 -b:v 2000k -pass 1 -an -f null /dev/null && \
ffmpeg -i IMG_1454.MOV -vf scale=720:576 -c:v libsvtav1 -b:v 2000k -pass 2 -ac 2 -c:a libopus y.mkv

When the video is vertical as indicated by `displaymatrix: rotation of -90.00 degrees`, I encode video with these parameters (540:960 instead of 960:540 for horizontal videos):


ffmpeg -i IMG_1819.MOV -vf scale=540:960 -c:v libsvtav1 -b:v 1000k -pass 1 -an -f null /dev/null && \
ffmpeg -i IMG_1819.MOV -vf scale=540:960 -c:v libsvtav1 -b:v 1000k -pass 2 -ac 2 -c:a libopus IMG_1819.mkv

Encoding in h264 for low performance computer


ffmpeg -i IMG_1819.MOV -vf scale=540:960 -c:v libx264 -b:v 2000k -pass 1 -an -f null /dev/null && \
ffmpeg -i IMG_1819.MOV -vf scale=540:960 -c:v libx264 -b:v 2000k -pass 2 -ac 2 -c:a libopus IMG_1819.mkv

To be able to play video directly in all web browsers additional parameters are needed `-profile:v main -pix_fmt yuv420p` and for audio `-c:a aac -ac 2 -strict experimental -b:a 128k`, the commands become:


ffmpeg -i IMG_1819.MOV -vf scale=540:960 -c:v libx264 -profile:v main -pix_fmt yuv420p -b:v 2000k -pass 1 -an -f null /dev/null && \
ffmpeg -i IMG_1819.MOV -vf scale=540:960 -c:v libx264 -profile:v main -pix_fmt yuv420p -b:v 2000k -pass 2 -c:a aac -ac 2 -strict experimental -b:a 128k IMG_1819.mkv

Encoding for the web (h264)


The parameters in previous section don't allow playing the video in all operating systems. With the configuration below, the video files are playable directly from the web page on Linux, MacOS and Windows and in all major browsers: firefox, safari, chrome, edge.


ffmpeg -i IMG_1819.MOV -vf "fps=30,scale=960x540" -c:v libx264 -profile:v main -pix_fmt yuv420p -b:v 2000k -pass 1 -an -f null /dev/null && \
ffmpeg -i IMG_1819.MOV -vf "fps=30,scale=960x540" -c:v libx264 -profile:v main -pix_fmt yuv420p -b:v 2000k -pass 2 -c:a aac -ac 2 -strict experimental -b:a 128k IMG_1819.mp4

Encoding in mpeg2 for Intel Pentium M processor 1600MHz


I have a

Pentium M

in a thinkpad from 2003. To be able to watch videos on this computer, I need to:


scale to 480x270

encode in mpeg2

change framerate from 60fps to 30fps

encode audio in mp3


ffmpeg -i IMG_1819.MOV -vf "fps=30,scale=270x480" -c:v mpeg2video -b:v 3000k -c:a libmp3lame IMG_1819.mkv

The resulting file is 1GB for 1h30 of video with reasonable quality.


Cutting a video


With ffmpeg, it is possible to cut a long video and make shorter clip, with this command:


ffmpeg -i "video.mp4" -ss 00:03:00 -c copy -to 00:03:03 clip.mp4

Merging audio file with video file


ffmpeg -i video_file -i audio_file -c:v copy -c:a copy out_file.mp4

hashtags: #ffmpeg #video #encoding


Feed

-- Response ended

-- Page fetched on Tue May 21 22:26:47 2024