Skip to content

01_ffmpeg

Davood Dorostkar edited this page Feb 12, 2025 · 31 revisions

Example code

Typical video conversion command:

ffmpeg -hide_banner -loglevel warning -i input.webm \
-c:a aac -b:a 128k \
-c:v libx264 -b:v 1000k \
-s 1920x1080 -r 25 output.mp4

remove audio from file:

ffmpeg -i 1.mp4 -c copy  -an out.mp4

Video to audio

ffmpeg -i 1.mp4 -vn out.mp3

speed up/down:

speed up video only:

ffmpeg -i 1.mp4 -vf "setpts=PTS/10" output.mp4

speed up audio only:

ffmpeg -i input.mp4 -af "atempo=1.1" out.mp4

you can use both flags together

concat file from file list:

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

content of list .txt:

file '/home/davood/Desktop/video/out.mp4'
file '/home/davood/Desktop/video/out2.mp4'

remove extra text:

ffmpeg -hide_banner ...

just copy audio:

ffmpeg -c:a copy ...

just copy video:

ffmpeg -c:v copy ...

set audio container to AAC and bitrate to 128k:

ffmpeg -i input.mp4 -c:v copy -c:a libfdk_aac -b:a 128k output.mp4

it might not work in windows, so use built-in AAC:

... -c:a aac ...

set video container to H.264 and bitrate to 1MB/s:

ffmpeg -i input -c:v libx264 -c:a copy output.mp4

two pass encoding:

Windows users should use NUL instead of /dev/null and ^ (in command prompt) or ` (in PowerShell) instead of .

ffmpeg -y -i input -c:v libx264 -b:v 2600k -pass 1 -an -f null /dev/null && \
ffmpeg -i input -c:v libx264 -b:v 2600k -pass 2 -c:a aac -b:a 128k output.mp4

change dimension:

ffmpeg -i input.mp4 -s 1920x1080 output.mp4

change frame rate:

ffmpeg -i input.mp4 -r 25 output.mp4

rotation:

ffmpeg -i in.mov -vf "transpose=1" out.mov
0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

cut a part of file:

//// with start and stop time:
ffmpeg -i input.mp4 -ss 00:01:00 -to 00:02:05 output.mp4
//// with start and duration(in seconds):
ffmpeg -i input.mp4 -ss 00:01:00 -t 100 output.mp4
//// from second 3 to end:
ffmpeg -i input.mp4 -ss 3 -c copy output.mp4

set encoding preset:

... -preset ultrafast ...
... -preset veryslow ...

set quality

greater numbers lead to less quality and size (constant rate factor):

... -crf 23 ...

set lossless H.264:

... -qp 0 ...

restict CPU usage

to use 2 cores:

- threads 2

Log levels

ffmpeg -loglevel <LEVEL>

defaul level is warning. available log levels, from less info to more info:

quiet
panic
fatal 
error 
warning 
info 
verbose 
debug

Make a video form a list of images

ffmpeg -framerate 10 -pattern_type glob -i '*.png' -c:v libx264 -pix_fmt yuv420p output.mp4

Convert images

ffmpeg -i input.png output.jpg

changing quality:

-q:v 2: sets the quality of the output JPEG. The value can range from 2 to 31, where 2 is the highest quality and 31 is the lowest.

ffmpeg -i input.png -q:v 2 output.jpg

Using percentage based compression

ffmpeg -i input.png -compression_level 100 output.jpg

changing size:

ffmpeg -i input.png -vf "scale=iw*0.5:ih*0.5" output.jpg

Hardware Acceleration

when using cuda, setting the framerate (and a little, the bitrates) has critical effect on convert speed

without -hwaccel cuda it totally uses CPU. with -hwaccel cuda, it uses both GPU and CPU. if you use -hwaccel_output_format cuda -c:v h264_nvenc as well, it totally uses GPU.

use cuda:

ffmpeg -hwaccel cuda ...

if it doesn't use 100% GPU, you need to compile ffmpeg yourself:

mkdir ~/nvidia/ && cd ~/nvidia/
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
cd nv-codec-headers && sudo make install
cd ~/nvidia/
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg/
sudo apt install build-essential yasm cmake libtool libc6 libc6-dev unzip wget libnuma1 libnuma-dev
cd ~/nvidia/ffmpeg/
./configure --enable-nonfree --enable-cuda-nvcc --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64 --disable-static --enable-shared
make -j $(nproc)
sudo make install

verify installation:

ls -l /usr/local/bin/ffmpeg
type -a ffmpeg

Now Use CUDA:

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -c:v h264_nvenc -r 25 output1.mp4

possible issues:

if cannot find some shared objects, first find them and then make a symlink for them(in this case the lib is in /usr/lib/libavdevice.so.61 but the system cannot find it):

sudo ln -s /usr/lib/libavdevice.so.61 /usr/lib/x86_64-linux-gnu/libavdevice.so.61

compile ffmpeg from source

compile ffmpeg from source

reference

reference on presets and encoding

Watermark Videos

Script for Text Watermarking (Bash)

#!/bin/bash

# Define input folder, output folder, and watermark text
input_folder="input_videos"
output_folder="output_videos"
watermark_text="Your Watermark Text"

### Create the output folder if it doesn't exist
mkdir -p "$output_folder"

### Loop through all video files in the input folder
for video in "$input_folder"/*; do
  # Get the filename without extension
  filename=$(basename "$video")
  output="$output_folder/$filename"

  # Add text watermark using FFmpeg
  ffmpeg -i "$video" -vf "drawtext=text='$watermark_text':fontcolor=white:fontsize=24:x=10:y=10" -c:v libx264 -crf 23 -preset medium -c:a copy "$output"
  
  echo "Processed: $filename -> $output"
done

Explanation of FFmpeg Command

  • -vf "drawtext=...:

    • text='Your Watermark Text': The text to display.
    • fontcolor=white: The color of the text. You can use other colors like black, red, or hex values (#FFFFFF).
    • fontsize=24: The size of the text.
    • x=10:y=10: The position of the text.
      • Top-left: x=10:y=10
      • Top-right: x=w-tw-10:y=10
      • Bottom-left: x=10:y=h-th-10
      • Bottom-right: x=w-tw-10:y=h-th-10
        • w: Video width.
        • h: Video height.
        • tw: Text width.
        • th: Text height.
  • -c:v libx264: Specifies the H.264 video codec.

  • -crf 23: Sets video quality (lower is better).

  • -preset medium: Balances encoding speed and compression.

  • -c:a copy: Copies the audio without re-encoding.

Install Font for Customization

If you want to use a specific font:

  1. Install the font:
    sudo apt-get install fonts-dejavu-core
    Replace fonts-dejavu-core with the desired font package.
  2. Modify the command to specify the font:
    -vf "drawtext=text='Your Watermark Text':fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:fontcolor=white:fontsize=24:x=10:y=10"