Generate a music cue sheet from a video, broadcast, or class recording

Source: AudD•

Generate a music cue sheet from a video, broadcast, or class recording

Scan a finished video, broadcast, or class recording with the AudD enterprise endpoint and turn the matches into a cue list CSV: title, artist, album, label, ISRC/UPC, in and out times, and duration, ready for your licensing and reporting workflow.

A cue sheet lists every piece of music in a production with where it starts, where it ends, and how long it runs. Post-production teams deliver one with a TV episode or a film; broadcasters keep as-aired logs; fitness studios and event producers need to know which tracks a recorded class or event used. If nobody logged the music while editing, you can rebuild the list from the finished file. This recipe scans the file with AudD’s enterprise endpoint and writes a cue list CSV.

What you get is a starting point. AudD identifies the recording: title, artist, album, label, and (on a Startup plan or higher) ISRC and UPC. It does not return composers, publishers, ISWCs, or PRO shares, and it doesn’t file anything with a PRO or broadcaster. Cue sheet formats differ by PRO and by broadcaster, so the CSV leaves those columns for you to fill in from your licensing records.

What you’ll build

A script that takes one file and writes cue-sheet.csv:

One row per continuous use of a track. If the same song plays in the cold open and again over the end credits, that is two cues, as cue sheets expect.

If you need show notes for a podcast, see Generate music credits for a podcast episode; for a DJ mix with blended transitions, see Turn a DJ set or mix into a tracklist. This page is about the cue list: in and out times, durations, identifiers, and the columns a rights workflow needs.

Prerequisites

  • An API token. Get your own token at dashboard.audd.io. ISRC, UPC, and score require a Startup plan or higher.
  • Python 3.10+ with pip install audd, and ffprobe (part of ffmpeg) to read the file’s duration.
  • The finished file: a video, an audio export, or a URL. Use the final mix; a music-only stem matches more cues if you have one (see Step 5).

Step 1: Scan the whole file

A cue sheet needs every cue, so scan every 12-second chunk. Don’t sample with skip: a 15-second sting between probes would never be found. Set limit to the number of chunks in the file, so the call covers the whole file and nothing more.

The enterprise endpoint is billed one request per 12 seconds of audio processed, so the cost is set by the running time:

Each match has start_seconds and end_seconds: where the match sits in your file, in seconds. The SDK computes them from the chunk’s position plus the offset inside the chunk. If you call the HTTP API yourself, the enterprise fields reference has the formula.

Step 2: Collapse matches into cues

A song that plays for two minutes comes back as about ten matches, one per chunk. Merge consecutive matches of the same recording into one cue. Allow a gap of one chunk, because a quiet passage or a line of dialogue over the music can make a single chunk miss. A different recording starting ends nothing by itself: two songs can overlap in a crossfade, and each keeps its own cue.

The key prefers the ISRC, so two matches with slightly different title strings for the same recording still merge. When there’s no ISRC (on plans below Startup, or for a custom match) it falls back to artist and title, or to the custom catalog’s audio_id.

Step 3: Format times and write the CSV

usage, composer, publisher, and pro stay empty. Usage (background, visual vocal, theme, and so on) depends on how the music sits in the picture, which audio recognition can’t see. Composer, publisher, and PRO affiliation come from your licence paperwork or the music supervisor.

A cue sheet in seconds is fine for most workflows. If yours needs frames, convert from seconds at your project frame rate after the fact.

Step 4: How precise the times are

Times are approximate, and how approximate depends on one setting.

Without accurate offsets, a match only tells you which 12-second chunk it came from. In and out times snap to chunk boundaries, so each edge can be off by up to 12 seconds, and a duration by up to about 24.

With accurate offsets (accurate_offsets=true on the HTTP API), each match also carries start_offset and end_offset: where inside the chunk, in milliseconds, the matched audio starts and ends. In and out times then land inside the chunk instead of on its boundary. The Python SDK turns this on by default, and so does the CLI; if you call the HTTP API directly, send the parameter yourself.

Even with accurate offsets, check the result against the edit before you deliver it:

  • A fade-in, a fade-out, or a tail buried under dialogue may not match, so the cue can look a few seconds shorter than it plays.
  • A cue cut into pieces in the edit shows up as separate cues if a gap is longer than GAP. That is often correct for a cue sheet, which counts each use separately.
  • Round durations the way your PRO or broadcaster asks; some want whole seconds, some want rounding up.

If you have the edit decision list, use it for the final in and out points and use AudD’s list to find and identify the cues.

Step 5: Library music and unreleased tracks

AudD’s public database covers about 160 million commercially released songs. Production library music, a score written for the show, and tracks not yet released may not be in it, and those cues come back as no match.

If you have the audio files for that music (the library tracks you licensed, the composer’s stems), you can add them to a custom catalog: a private fingerprint database for your account. A later scan then returns those cues with an audio_id you assigned, which your own table maps to the library, composer, and publisher. Custom catalog access is not enabled by default; email [email protected] to request it. Uploads are metered and must not be retried automatically, since a retry after an upload that landed is charged again.

In write_cue_sheet, look up rows whose source is custom:<id> in LIBRARY and fill in title, composer, and publisher. A custom match can have empty artist and title fields, so your table is the source of truth for those cues.

A music-only stem, if the mix has one, gives cleaner matches than the full mix, where dialogue and effects sit on top of the music. Times carry over as long as the stem starts at the same point as the program.

The CLI way

For a one-off cue list, the AudD CLI does the scan and the merge:

--limit is the number of 12-second chunks (110 for 22 minutes); --dry-run shows the cost without sending anything. --tracklist merges consecutive matches into tracks, and the CSV has artist, title, album, label, isrc, upc, start, end, start_seconds, and end_seconds per track. Compute duration as end_seconds - start_seconds in your spreadsheet. Accurate offsets are on by default.

By use

Handling errors

  • AudDAuthenticationError: bad token. Stop and fix it.
  • AudDQuotaError, AudDSubscriptionError: out of requests, or a feature your plan doesn’t include. Fix the account; retrying won’t help.
  • AudDCustomCatalogAccessError: custom catalog access isn’t enabled yet.
  • AudDInvalidAudioError: the file couldn’t be decoded. Export the audio to WAV or MP3 and try again.
  • AudDConnectionError on a scan: safe to retry. Cancelling a request mid-flight might still consume requests, and a retried scan is billed again, so save the matches as soon as they arrive.
  • Generate music credits for a podcast episode
  • Turn a DJ set or mix into a tracklist
  • Enterprise response and match fields
  • Public database vs your custom catalog
  • AudD for PROs and rights organizations
  • Controlling enterprise endpoint cost

What this article says