Skip to content

Instantly share code, notes, and snippets.

@drlinux
Created June 2, 2024 07:53
Show Gist options
  • Save drlinux/aa4a2e15f37f84b9d8b15c4458bec48d to your computer and use it in GitHub Desktop.
Save drlinux/aa4a2e15f37f84b9d8b15c4458bec48d to your computer and use it in GitHub Desktop.
#!/bin/sh
# This script needs ffmpeg v3.2 (--enable-libebur128) + jq
# Check if source and target files are provided
if [ $# -ne 2 ]; then
echo "Usage: $0 <source> <target>"
exit 1
fi
SOURCE="$1"
TARGET="$2"
EXTENSION="${SOURCE##*.}"
JSON_ANALYST_FILE="${SOURCE%.*}.json"
DEST_I="-14"
DEST_LRA="11"
DEST_TRUE_PEAK="-1.0"
# Run ffmpeg to analyze the audio
RAW_FFMPEG_ANALYST=$(ffmpeg -hide_banner -nostats -i "$SOURCE" -af loudnorm=print_format=json -f null - 2>&1)
if [ $? -ne 0 ]; then
echo "ffmpeg analysis failed."
exit 1
fi
# Extract the JSON data from the analysis output
JSON_START=$(echo "$RAW_FFMPEG_ANALYST" | grep -n '{' | head -n 1 | cut -d: -f1)
JSON_END=$(echo "$RAW_FFMPEG_ANALYST" | grep -n '}' | tail -n 1 | cut -d: -f1)
JSON_DATA=$(echo "$RAW_FFMPEG_ANALYST" | sed -n "${JSON_START},${JSON_END}p")
# Save the JSON data to a file
echo "$JSON_DATA" > "$JSON_ANALYST_FILE"
# Parse the JSON file using jq
LOUDNESS_input_i=$(jq -r '.input_i' "$JSON_ANALYST_FILE")
LOUDNESS_input_tp=$(jq -r '.input_tp' "$JSON_ANALYST_FILE")
LOUDNESS_input_lra=$(jq -r '.input_lra' "$JSON_ANALYST_FILE")
LOUDNESS_input_thresh=$(jq -r '.input_thresh' "$JSON_ANALYST_FILE")
LOUDNESS_input_offset=$(jq -r '.target_offset' "$JSON_ANALYST_FILE")
# Check if jq commands succeeded
if [ -z "$LOUDNESS_input_i" ] || [ -z "$LOUDNESS_input_tp" ] || [ -z "$LOUDNESS_input_lra" ] || [ -z "$LOUDNESS_input_thresh" ] || [ -z "$LOUDNESS_input_offset" ]; then
echo "jq parsing failed."
exit 1
fi
# Construct the audio filter string
AF_FILTER="loudnorm=I=$DEST_I:TP=$DEST_TRUE_PEAK:LRA=$DEST_LRA:measured_I=$LOUDNESS_input_i:measured_LRA=$LOUDNESS_input_lra:measured_TP=$LOUDNESS_input_tp:measured_thresh=$LOUDNESS_input_thresh:offset=$LOUDNESS_input_offset:linear=true:print_format=summary"
# Apply the normalization filter with ffmpeg
ffmpeg -y -i "$SOURCE" -codec:v copy -codec:a aac -b:a 320k -af "$AF_FILTER" "$TARGET"
if [ $? -ne 0 ]; then
echo "ffmpeg normalization failed."
exit 1
fi
echo "Normalization completed successfully."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment