Skip to content

Smart Transitions

manish singh edited this page Jul 25, 2026 · 1 revision

Smart Transitions

A smart transition prepares one track before playback. It can trim silence, estimate a safe outgoing fade length, and apply conservative loudness gain.

It does not inspect the next track. Pair-level decisions belong to SLM and AutoMix.

Prepare one track

from veloura.audio import (
    AudioTrack,
    prepare_smart_transition,
    transition_preset,
)

track = AudioTrack.from_source(
    "./music/song.flac",
    title="Song",
    duration=198.2,
)

config = transition_preset("streamer")
prepare_smart_transition(track, config)

print(track.trim_start)
print(track.trim_end)
print(track.gain)
print(track.crossfade_seconds)
print(track.analysis)

The same AudioTrack instance is returned after its preparation fields are updated.

What gets analyzed

Silence

Veloura runs FFmpeg's silencedetect over bounded beginning and, when enabled, ending windows. It only trims a leading section when silence begins at the start. Intro and outro trim values are capped by configuration.

Loudness

Veloura runs FFmpeg's volumedetect, reads mean_volume, and calculates a linear gain toward the configured target. The result is clamped between loudness_min_gain and loudness_max_gain.

This reduces obvious level jumps. It is not LUFS normalization, dynamic-range compression, or an equalizer.

Duration rules

The planner reduces fade length for:

  • Tracks shorter than 150, 90, or 45 seconds.
  • Titles that look like interviews, podcasts, speech, dialogue, skits, live recordings, concerts, or acoustic sessions.
  • Tracks with meaningful trailing silence.

The final fade cannot consume more than one third of the playable duration.

Failure and fallback

If FFmpeg is missing, analysis cannot decode a source, or an analysis command times out, Veloura keeps conservative defaults instead of crashing the entire queue. Inspect track.analysis and playback snapshots when you need to distinguish analyzed data from fallback behavior.

Cache preparation

from veloura.audio import FileAnalysisCache

cache = FileAnalysisCache(
    max_entries=1000,
    ttl_seconds=7 * 24 * 60 * 60,
)

cache.prepare_transition(track, config)

The cache key includes source identity, local file size and modification time when available, duration, title, schema version, and normalized configuration. A changed file or changed preset therefore receives fresh analysis.

When to prepare

Good times:

  • During queue insertion in a background task.
  • While the preceding track is still comfortably far from its ending.
  • During media import for a local library.

Bad times:

  • Inside a real-time device callback.
  • While holding your application's global queue lock.
  • Repeatedly on every 20 ms PCM read.

For untrusted online sources, combine preparation with bounded resolver timeouts and application-level concurrency limits.

Clone this wiki locally