Blog-Archiv

Samstag, 8. Juli 2023

Brighten or Darken a Video with ffmpeg

Some cameras are not good at compensating differences in brightness. Then you want to brighten or darken your video a ittle bit. You can do that with ffmpeg.

UNIX Shell Script

The basic command is

ffmpeg -v error -y -i $sourceVideo -vf eq=brightness=0.2 -c:a copy $targetVideo

but we need to care also for the time_base of the created video, else it may not be combineable with other videos of the same serie.

Here is a script that accepts a video XXX.mp4 on command line and ceates a video XXX_brighter.mp4 from it, being in the same folder as the original video. If 0.2 (20%) brighter is not sufficient for you, you can increase that by setting your chosen value as second command line argument.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
brighter=0.2   # 20% brighter
sourceVideo=$1

[ -z "$sourceVideo" ] && {
    echo "SYNTAX: $0 videofile [brightnessIncrement]" >&2
    echo "    Brighten or darken a video, default brightnessIncrement is 0.2 for 20% brighter, use -0.1 for 10% darker" >&2
    echo "    If videofile is xxx.mp4, the result file will be xxx_brighter.mp4." >&2
    exit 1
}
[ -f "$sourceVideo" ] || {
    echo "Not a file: $sourceVideo" >&2
    exit 2
}

[ -n "$2" ] && {
    brighter=$2
}

sourceDir=`dirname \$sourceVideo`
sourceFile=`basename \$sourceVideo`
filename=${sourceFile%.*}    # filename without extension
extension=${sourceFile#*.}    # extension without filename
targetVideo=$sourceDir/${filename}_brighter.$extension 

# keep time_base
getInverseTimeBase()    {    # $1 = video file path
    ffprobe -v error -select_streams v:0 -show_entries stream=time_base -of default=noprint_wrappers=1 $1 | sed 's/time_base=1\///'
}
inverseTimeBase=`getInverseTimeBase \$sourceVideo`
keepTimeBase="-vsync 0 -enc_time_base -1 -video_track_timescale $inverseTimeBase"

echo "Brightening $sourceVideo ...." >&2

ffmpeg -v error -y -i $sourceVideo -vf eq=brightness=$brighter -c:a copy $keepTimeBase $targetVideo || exit 3

echo "Created $targetVideo" >&2
  • Lines 1 sets the brightness increment default
  • Line 2 defines the source video as first command line argument
  • Line 4 checks that the argument is not empty and outputs help if so
  • Line 10 checks if that is a real file
  • Line 15 and 16 set the brightness increment optionally from second command line argument
  • Lines 19 to 23 create the target file name for the brighter video
  • Lines 25 to 30 calculate the time_base to use from the original video
  • Line 34 finally is the ffmpeg command, this takes a while to change any frame of the video.

Hope this was helpful!