Skip to content
Packages Examples Agents Blog Get started

Audio tempo/beat analysis for the Oridecon Framework — analyzes an audio MediaAsset and returns tempo (BPM) and beat timestamps for driving beat-synced cut timing.


oridecon-multimedia-beat analyzes an audio clip and returns a BeatAnalysisResult (tempo_bpm + beat_timestamps). Two backends are available: librosa (default, runs in-process, no reference server) and madmom (optional, deep-learning-based, reference-server pattern — better on syncopated or tempo-changing material).

Full documentation: oridecon.dev

Terminal window
uv add oridecon-multimedia-beat
# Optional extras
uv add "oridecon-multimedia-beat[librosa]" # librosa in-process backend
uv add "oridecon-multimedia-beat[madmom-server]" # madmom reference server
from oridecon import Application
from oridecon.di.module import Module, module
from oridecon.multimedia.beat import BeatAnalysisModule
from oridecon.contracts.multimedia.protocols import BeatAnalysisProvider
from oridecon.contracts.multimedia.types import BeatAnalysisRequest, MediaAsset
@module(imports=[BeatAnalysisModule.configure()])
class AppModule(Module):
pass
async def main() -> None:
async with Application.boot(modules=[AppModule]) as app:
beat = await app.container.resolve(BeatAnalysisProvider)
asset = MediaAsset(mime_type="audio/mp3", provider="local", bytes_data=b"<mp3>")
result = await beat.analyze(BeatAnalysisRequest(asset=asset))
if result.is_ok():
analysis = (
result.unwrap()
) # BeatAnalysisResult — tempo_bpm + beat_timestamps
print(analysis.tempo_bpm)
if __name__ == "__main__":
import asyncio
asyncio.run(main())

Zero-config usage: Call BeatAnalysisModule.configure() with no arguments to use the in-process librosa backend.

application.yaml
multimedia_beat:
backend: "librosa"
librosa_sample_rate: 44100

Option 2 — Profiles + Environment Variables

Section titled “Option 2 — Profiles + Environment Variables”
Terminal window
export ORI_PROFILE=production
export ORI_MULTIMEDIA_BEAT__BACKEND=madmom
export ORI_MULTIMEDIA_BEAT__LIBROSA_SAMPLE_RATE=44100
from oridecon.multimedia.beat import BeatAnalysisModule
from oridecon.multimedia.beat.config import BeatAnalysisConfig
BeatAnalysisModule.configure(
config=BeatAnalysisConfig(backend="librosa", librosa_sample_rate=44100)
)
FieldDefaultEnv varDescription
backend"librosa"ORI_MULTIMEDIA_BEAT__BACKENDlibrosa (in-process), madmom (reference server)
librosa_sample_rate22050ORI_MULTIMEDIA_BEAT__LIBROSA_SAMPLE_RATESample rate for the librosa backend
madmom_base_url"http://localhost:5600"ORI_MULTIMEDIA_BEAT__MADMOM_BASE_URLMadmom server URL
timeout30.0ORI_MULTIMEDIA_BEAT__TIMEOUTRequest timeout in seconds
MethodDescription
BeatAnalysisModule.configure(config)Configure with explicit beat-analysis config
BeatAnalysisModule.stub()No-op module for unit testing (uses librosa)
  • Two backendslibrosa (in-process, default, no reference server) and madmom (deep-learning, reference-server pattern)
  • No blob persistence — returns a BeatAnalysisResult (tempo + beat timestamps), not a MediaAsset; no queued task handler
  • Beat-synced editing — drive cut timing in the calling application
  • Reference serveroridecon-beat-madmom-serve console script runs the madmom model server
  • Result-basedanalyze() -> Result[BeatAnalysisResult, MultimediaError]; errors are domain values, not exceptions
from oridecon import Application
from oridecon.multimedia.beat import BeatAnalysisModule
async def test_boot():
async with Application.boot(modules=[BeatAnalysisModule.stub()]) as app:
assert app.container is not None
FileWhat it contains
src/oridecon/multimedia/beat/module.pyBeatAnalysisModule.configure() and .stub()
src/oridecon/multimedia/beat/config.pyBeatAnalysisConfig
src/oridecon/multimedia/beat/di/provider.pyBeatAnalysisGenerationProvider — registers BeatAnalysisProvider
src/oridecon/multimedia/beat/providers/Backend implementations (librosa, madmom)
src/oridecon/multimedia/beat/servers/Reference-server entry point (oridecon-beat-madmom-serve)
src/oridecon/multimedia/beat/exceptions.pyBeatAnalysisError hierarchy