How Two-Pass Loudnorm Measurement Works in video-use
The two-pass loudnorm measurement in video-use analyzes audio using ffmpeg's loudnorm filter with print_format=json to capture precise loudness statistics, then feeds those measured values into a second pass to guarantee the output meets the target -14 LUFS integrated standard while preserving the original video stream.
The browser-use/video-use repository implements broadcast-standard audio normalization for social media content through a precise two-step process. This mechanism ensures uploaded videos meet consistent loudness targets without re-encoding video streams, making it essential for creating platform-ready content efficiently.
First Pass: Measurement and Analysis
The measurement phase occurs in helpers/render.py within the measure_loudness function (lines 97-112). This function executes ffmpeg with the loudnorm filter configured to output diagnostic data rather than processed audio.
def measure_loudness(video_path: Path) -> dict[str, str] | None:
"""
Run ffmpeg loudnorm first pass and parse the JSON measurement.
"""
filter_str = (
f"loudnorm=I={LOUDNORM_I}:TP={LOUDNORM_TP}:LRA={LOUDNORM_LRA}:print_format=json"
)
cmd = [
"ffmpeg", "-y", "-hide_banner", "-nostats",
"-i", str(video_path),
"-af", filter_str,
"-vn", "-f", "null", "-",
]
proc = subprocess.run(cmd, capture_output=True, text=True)
stderr = proc.stderr
# Extract the JSON block that loudnorm prints to stderr
start = stderr.rfind("{")
end = stderr.rfind("}")
data = json.loads(stderr[start : end + 1])
return data
Key technical details: The filter analyzes the entire audio stream and writes a JSON object containing input_i (integrated loudness), input_tp (true peak), input_lra (loudness range), input_thresh, and target_offset to stderr. The code isolates this JSON block (lines 116-123) by finding the last occurrence of curly braces in the stderr output, ensuring reliable extraction even when ffmpeg logs additional information.
Second Pass: Normalization with Measured Values
The apply_loudnorm_two_pass function (lines 131-190) orchestrates the full workflow by feeding the measured values back into ffmpeg. This second pass applies the calculated gain or attenuation needed to reach the target specification.
def apply_loudnorm_two_pass(
input_path: Path,
output_path: Path,
preview: bool = False,
) -> bool:
# Full two-pass
print(f" loudnorm pass 1: measuring {input_path.name}")
measurement = measure_loudness(input_path)
if measurement is None:
# Fallback to one-pass approximation if measurement fails
return apply_loudnorm_two_pass(input_path, output_path, preview=True)
filter_str = (
f"loudnorm=I={LOUDNORM_I}:TP={LOUDNORM_TP}:LRA={LOUDNORM_LRA}"
f":measured_I={measurement['input_i']}"
f":measured_TP={measurement['input_tp']}"
f":measured_LRA={measurement['input_lra']}"
f":measured_thresh={measurement['input_thresh']}"
f":offset={measurement['target_offset']}"
f":linear=true"
)
cmd = [
"ffmpeg", "-y", "-hide_banner", "-nostats",
"-i", str(input_path),
"-c:v", "copy",
"-af", filter_str,
"-c:a", "aac", "-b:a", "192k", "-ar", "48000",
"-movflags", "+faststart",
str(output_path),
]
subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
return True
Critical implementation detail: The second pass populates the measured_I, measured_TP, measured_LRA, measured_thresh, and offset parameters with values from the first pass. This tells the loudnorm filter exactly how much adjustment is required to hit the target loudness while preserving dynamic range. The video stream is copied directly (-c:v copy) to avoid quality loss and reduce processing time.
Preview Mode and Single-Pass Fallback
When the preview parameter is True or when the first pass measurement fails, the system falls back to a single-pass approximation. This mode skips the measurement phase and runs loudnorm without the measured value parameters:
if preview:
filter_str = f"loudnorm=I={LOUDNORM_I}:TP={LOUDNORM_TP}:LRA={LOUDNORM_LRA}"
This approach is significantly faster but less accurate because the filter cannot adapt to the specific loudness characteristics of the source material. The fallback mechanism ensures robustness: if measure_loudness returns None due to parsing errors or ffmpeg failures, the code automatically retries with preview=True.
Target Loudness Constants
The normalization targets are defined as constants at lines 90-94 in helpers/render.py:
LOUDNORM_I = -14.0 # target integrated LUFS
LOUDNORM_TP = -1.0 # target true-peak dB
LOUDNORM_LRA = 11.0 # target loudness range
These values represent the social media loudness standard (-14 LUFS integrated, -1 dBTP peak, 11 LU loudness range) used by major platforms to ensure consistent audio levels across user-generated content.
Summary
- Two-pass workflow: First pass measures, second pass normalizes using measured values to guarantee target compliance.
- JSON extraction: The
measure_loudnessfunction parses loudnorm's JSON output from stderr by locating the last curly-brace block in the output. - Video preservation: The second pass uses
-c:v copyto maintain original video quality while only re-encoding the normalized audio stream. - Fallback strategy: If measurement fails, the system automatically falls back to single-pass mode for reliability.
- Social media standards: Targets -14 LUFS integrated loudness with -1 dBTP true peak and 11 LU loudness range.
Frequently Asked Questions
Why does video-use use a two-pass loudnorm measurement instead of single-pass?
The two-pass approach guarantees precise loudness compliance by first measuring the actual integrated loudness, true peak, and loudness range of the source material, then calculating the exact gain correction needed. Single-pass mode must estimate these values on the fly, which can result in slight deviations from the target -14 LUFS standard, making the two-pass method essential for final delivery quality.
What specific loudness values does video-use target?
According to the constants defined in helpers/render.py, video-use targets -14.0 LUFS for integrated loudness (LOUDNORM_I), -1.0 dBTP for true peak (LOUDNORM_TP), and 11.0 LU for loudness range (LOUDNORM_LRA). These values align with the social media loudness standard used by major platforms to ensure consistent audio levels.
How does the measurement data transfer between the two passes?
The first pass captures a JSON object containing keys like input_i, input_tp, input_lra, input_thresh, and target_offset from ffmpeg's stderr output. The measure_loudness function returns this data as a dictionary, which apply_loudnorm_two_pass then injects into the second pass's filter string using the measured_I, measured_TP, measured_LRA, measured_thresh, and offset parameters.
What happens if the first pass measurement fails?
If measure_loudness returns None due to parsing errors or ffmpeg execution issues, the code automatically triggers a fallback scenario. The apply_loudnorm_two_pass function recursively calls itself with preview=True, which skips the measurement phase and uses a single-pass loudnorm filter approximation instead, ensuring the pipeline completes even when precise measurement is unavailable.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →