Normalize screen recording audio levels (#5244)

* Normalize screen recording audio

Screen recordings capture audio at whatever the system level is set to,
which often results in very quiet audio. Add a post-processing step that
normalizes audio to -14 LUFS using ffmpeg loudnorm after the first-frame
trim. Video is copied without re-encoding. Silently skipped for
recordings with no audio track.

* Do both trimming and normalizing in a single step so we don't have to process the video twice

* Simplify conditional

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
This commit is contained in:
Rob Zolkos
2026-04-22 13:50:05 +02:00
committed by GitHub
co-authored by David Heinemeier Hansson
parent e757ae98ea
commit 14a599ab9d
+16 -9
View File
@@ -134,7 +134,7 @@ stop_screenrecording() {
pkill -9 -f "^gpu-screen-recorder"
notify-send "Screen recording error" "Recording process had to be force-killed. Video may be corrupted." -u critical -t 5000
else
trim_first_frame
finalize_recording
local filename=$(cat "$RECORDING_FILE" 2>/dev/null)
local preview="${filename%.mp4}-preview.png"
@@ -159,17 +159,24 @@ screenrecording_active() {
pgrep -f "^gpu-screen-recorder" >/dev/null
}
trim_first_frame() {
finalize_recording() {
local latest
latest=$(cat "$RECORDING_FILE" 2>/dev/null)
[[ -f $latest ]] || return
if [[ -n $latest && -f $latest ]]; then
local trimmed="${latest%.mp4}-trimmed.mp4"
if ffmpeg -y -ss 0.1 -i "$latest" -c copy "$trimmed" -loglevel quiet 2>/dev/null; then
mv "$trimmed" "$latest"
else
rm -f "$trimmed"
fi
# Trim the first frame, and normalize audio to -14 LUFS if present, in a single pass
local args=(-y -ss 0.1 -i "$latest")
if ffprobe -v error -select_streams a -show_entries stream=codec_type -of csv=p=0 "$latest" 2>/dev/null | grep -q audio; then
args+=(-af loudnorm=I=-14:TP=-1.5:LRA=11 -c:v copy)
else
args+=(-c copy)
fi
local processed="${latest%.mp4}-processed.mp4"
if ffmpeg "${args[@]}" "$processed" -loglevel quiet 2>/dev/null; then
mv "$processed" "$latest"
else
rm -f "$processed"
fi
}