Skip to content
streamneo.
Streaming Settings11 min read

How to Normalise Audio Volume Across Videos in an FFmpeg YouTube Loop

Measure each video separately, use consistent loudnorm targets and check where FFmpeg switches to dynamic mode.

sn.
StreamNeoPublished 5 October 2026
Worth sharing?

To make videos in an FFmpeg YouTube loop sound more even, use loudnorm with the same target settings for every file, but measure each file separately. For a prepared playlist, a two-pass workflow lets you use each file’s own measurements when linear normalisation is suitable.

This does not make different recordings sound identical, and YouTube does not specify a mandatory LUFS target in the cited upload guidance. Treat the target as a production choice: measure, process, then listen to the results in context.

Why playlist files can sound uneven

Two videos can have similar sample peaks and still sound very different in perceived volume. One might be a quiet devotional recording with long pauses; another may be a densely mastered bhajan with strong percussion. Peak matching alone does not account for how loudness is distributed over time, so the transition can feel abrupt even if neither file clips.

The loudnorm filter analyses integrated loudness, loudness range and true peak. Those measures help you bring files towards a shared target while observing a peak ceiling. They do not correct every difference in arrangement, recording quality, microphone distance, noise, or dynamics. A close-miked voice over a quiet tanpura may still feel more present than a busier track at a similar integrated loudness.

The key for a playlist is consistency of method, not reusing one file’s measurements. Set the same target parameters for the batch, then measure each source independently. If you copy the first track’s measured values into every later command, FFmpeg is applying the first track’s analysis to material it has not measured; the result can miss the intended level or make the processing unsuitable.

There is also a practical distinction between the file and the broadcast. If you create a normalised output before streaming, you can inspect it and use the same prepared asset in a loop. If you are building the stream directly with FFmpeg, the command structure and timing may differ. For the playlist side of that setup, see how to create a YouTube live playlist loop with VLC and OBS; the audio preparation described here is a separate step.

Measure loudness for each file

Start with one source file and run a measurement pass. The example below uses illustrative targets of -16 LUFS integrated loudness, 11 LU loudness range and -1.5 dBTP true peak. These are example production choices, not YouTube requirements. The FFmpeg documentation lists the filter options and their valid ranges; choose values for the material and listening context rather than treating an example as a platform rule.

ffmpeg -i input.mp4 -map 0:a:0 \\
  -af "loudnorm=I=-16:LRA=11:TP=-1.5:print_format=json" \\
  -f null -

The command sends the selected first audio stream through loudnorm and discards the output. At the end, the filter prints JSON measurement fields, including input_i, input_lra, input_tp and input_thresh. Keep those values with the matching filename. Repeat the measurement for every item you intend to process. The targets remain common across the batch, while these source measurements vary from file to file.

If an MP4 contains more than one audio stream, -map 0:a:0 selects the first one. Check the file before assuming that the first stream is the commentary, language or mix you want. If some playlist items have no audio, a command that explicitly maps an audio stream will fail for those files; handle them as a separate case rather than silently treating them as measured audio.

A small spreadsheet or a text file alongside the media is enough to prevent mix-ups. Record the filename, the four measurement fields, and the chosen targets. This is especially useful if you process a devotional playlist with alternate language mixes or a news loop containing separate interviews and stings. Measurements belong to a particular audio stream, not just a video’s title.

For a long batch, automate the repetition only after verifying the command against a few files. Keep the measurement output available for diagnosis. If the result is unexpectedly quiet or dynamic mode is reported, you can compare the output with the correct source measurements rather than rerunning a batch with uncertain substitutions. FFmpeg documents loudnorm and its measurement fields in its filter reference.

Choose consistent loudnorm targets

The three target controls serve different purposes. I is the integrated loudness target in LUFS. LRA is the target loudness range in LU. TP is the true-peak ceiling in dBTP. A shared set makes outputs more comparable, but the values involve trade-offs: aiming for a higher perceived loudness can leave less peak headroom, while a more restrained target may preserve more of the recording’s original feel.

Setting What it controls Practical question
I Integrated loudness target How prominent should this material feel beside the rest of the playlist?
LRA Loudness-range target How much variation between quieter and louder passages should remain?
TP True-peak ceiling How much headroom should be retained for reconstructed peaks?

The example settings are within the ranges documented by FFmpeg: I from -70 to -5 LUFS, LRA from 1 to 50 LU, and TP from -9 to 0 dBTP. FFmpeg’s documented defaults are I=-24, LRA=7 and TP=-2; those defaults are filter defaults, not a YouTube recommendation. You do not need to adopt either the example or defaults without listening and considering the programme.

For quiet ambience, devotional music and spoken local news, the same number may not be the best editorial choice for every format. A voice-led update may benefit from clear speech, while an ambience loop can be intended to sit gently in the background. If one channel mixes formats, decide what consistency means for your listeners: similar overall prominence, preserved musical dynamics, or a compromise between them. Use one target set as a repeatable starting point, then review whether the quieter material remains audible and whether the louder material still sounds natural.

Do not infer an upload target from YouTube’s technical encoding guidance. YouTube’s recommended upload encoding settings cover matters such as audio formats and sample rate, not a mandatory LUFS mastering number. Select a target because it suits your programme and workflow, not because you expect a platform setting to guarantee a particular loudness after playback processing.

Apply the second pass where linear mode fits

For a prepared file, the second pass supplies the measurements collected for that same source and the common target values. Replace every INPUT_* placeholder with the values printed during that file’s first pass; the placeholders are explanatory, not literal filter values.

ffmpeg -i input.mp4 -map 0:v? -map 0:a:0 \\
  -af "loudnorm=I=-16:LRA=11:TP=-1.5:measured_I=INPUT_I:measured_LRA=INPUT_LRA:measured_TP=INPUT_TP:measured_thresh=INPUT_THRESH:linear=true" \\
  -c:v copy -c:a aac output.mp4

This example maps the video stream if present and the first audio stream. -c:v copy leaves the selected video stream encoded as it was; it does not copy the audio unchanged. The audio has been filtered and therefore must be encoded for the output. AAC is shown as an example codec, not a universal container choice. Check that your chosen output container supports the streams you map, and inspect the output mapping before running a batch.

Linear mode is conditional rather than guaranteed by writing linear=true. FFmpeg needs the measured values, the requested loudness range cannot be lower than the source’s measured range, and the gain must not push true peak above the chosen ceiling. If those conditions do not fit, the filter can revert to dynamic mode. The result may therefore not behave like simple linear gain for every file, even though the same target settings were requested.

When it fits, the advantage of a two-pass approach is controlled, file-specific processing: you have measured the complete programme, then apply those measurements with the shared target. Its cost is an additional read of each source and a little bookkeeping. For files that take a long time to scan, factor that into your batch schedule; do not remove the measurement stage by reusing values from another track.

Understand dynamic-mode fallback

FFmpeg supports single-pass and double-pass operation. Single-pass processing can be useful when you cannot analyse a complete file first, including a live input. For a folder of finished videos, the two-pass method is usually easier to audit because it gives you each file’s measurements before processing. Neither approach makes every input meet a target in exactly the same way.

If the filter reports that it is using dynamic mode, read that as a signal about the constraints, not automatically as a failed command. The source’s loudness range, desired target range and peak ceiling may not permit the requested linear adjustment. Dynamic processing changes gain over time to work towards the target while respecting constraints; listen for changes that are distracting in material where a steady natural level matters.

In dynamic mode, FFmpeg upsamples audio to 192 kHz to detect true peaks, according to the filter documentation. If you need a specific output sample rate, set it explicitly with an output option such as -ar or use aresample; do not assume that the internal true-peak detection rate sets the delivery sample rate. YouTube’s upload guidance recommends 48 kHz, but choose and verify the output format against the current official guidance and your full encode command.

A mono source also deserves attention. The dual_mono option can compensate for perceptual measurement differences when mono audio is intended for stereo playback. It is not a fix for every channel-layout problem. Check whether the source should remain mono, be delivered as stereo, or be mapped with other channels, and listen to the actual result. YouTube’s audio troubleshooting guidance discusses problems that can arise when stereo audio is converted to mono, including poor compatibility.

Check peaks, transitions, and listening results

After encoding, inspect the second-pass JSON report and compare it with the intended targets. Confirm the output loudness and true-peak figures, and note whether the filter used linear or dynamic mode. A report is useful evidence about the file, but it cannot tell you whether a spoken introduction feels too quiet after a loud music bed or whether a cymbal transient is unpleasant on the speakers your viewers use.

Listen to at least the beginning, a representative loud section and the end of each processed file. Also audition playlist joins: the last few seconds of one item and the first few seconds of the next. This catches differences that isolated playback misses, including a sudden jump from a quiet chant to a percussion-heavy track, an abrupt fade, or silence at the boundary. If you use a slate or countdown between files, listen to that transition as well; this guide on adding a countdown or slate between videos covers the visual and playlist side.

Use the same playback volume and compare sources in sequence. A pair of headphones can be useful for finding clicks, distortion or a sudden level change, but specialised equipment is not a requirement for this workflow. Do not judge only by looking at waveform height: the purpose of loudness measurement is to account for perceived programme level and peak constraints, which waveform appearance alone does not express.

Keep the original files until you have checked the outputs. If one item sounds wrong, compare its source measurements, output report and channel mapping. You may find a wrong stream was selected, or that the source has an unusually wide dynamic range. Re-run only that item after correcting the cause, then check it again beside its neighbours. If audio disappears in the actual broadcast despite a good local output, troubleshoot the playback and stream mapping separately; this guide to prerecorded video with no audio in Streamlabs Desktop addresses a different failure point in the chain.

Keep YouTube playback enhancements distinct

Normalising a file before upload or broadcast changes the audio in that file. YouTube playback features are separate: what a viewer hears can also depend on their device and the controls available to them. YouTube says Stable volume is on by default when watching videos where the feature is available, and its help page notes exceptions. That viewer-side processing is not a substitute for measuring your sources or checking your own loop.

Avoid diagnosing a file solely from what one viewer hears with one playback setting. Compare the prepared output locally, then review the broadcast on a normal viewing device. If you need to explain why playback differs between devices, distinguish your encoded file from YouTube’s playback-side behaviour. See YouTube’s current pages for Stable volume and audio enhancements; availability and controls can change, so check the official guidance rather than assuming every viewer has identical processing.

For an always-on channel, a repeatable preparation step is often more useful than trying to correct the sound during the night. StreamNeo can remove the need to leave your own computer running for a prepared-file broadcast; it does not replace per-file audio measurement, listening checks or your decision about the channel’s sound.

Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.

FAQ

What loudnorm settings should I use for YouTube?

YouTube’s cited upload recommendations do not mandate a LUFS target. Choose an integrated loudness, range and true-peak ceiling that suit your programme, label them as your own production settings, and apply the same targets consistently across files. Measure each source separately and listen to the output.

Can I use one measurement for every video?

No. Use the same target settings, but use the measurements from each individual source in its second pass. A recording’s loudness, range, peak and threshold are not measurements of the next recording, even if both files belong to the same playlist.

Why did FFmpeg use dynamic mode?

Linear mode has constraints: the filter needs all measured values, the requested loudness range must not be below the source range, and the gain must respect the true-peak ceiling. When those conditions are not met, FFmpeg can fall back to dynamic mode. Check the report and listen for whether the result suits the material.

Does normalisation make the whole playlist sound identical?

No. It can bring integrated loudness towards a shared target while controlling true peaks, but it cannot erase differences in performance, arrangement, recording or dynamics. Check transitions in sequence and make editorial adjustments where a particular file still feels out of place.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Streaming Settings guides ↗ · All topics ↗