song-id
One command does the whole job:
uv run scripts/identify_song.py "<url-or-file>"
It downloads the audio (yt-dlp), cuts short slices, fingerprints them
(shazamio) and prints title, artist, album, label, year, cover art and
streaming links. Add --json for machine-readable output.
Rules
- Run it with
uv run, never pip install, never bare python. The
script carries a PEP 723 header, so uv builds the environment itself and
throws it away after.
- Do not try to read the song from the post metadata. Instagram strips the
audio attribution out of what yt-dlp can see;
track and artist come back
empty. The fingerprint is the answer, not the metadata.
- Do not guess. If there is no match, say there is no match. A wrong song
name is worse than none.
- One URL per call. For several links, call the script once per link.
Workflow
- Take the URL exactly as the user pasted it. Reel, share and
?igsh=...
tracking links all work; do not clean them up.
- Run the script.
- Report the result in one or two lines:
Title - Artist, then album, label
and year, then a link the user can actually press - see below.
The link the user wants
Most people are on Spotify, so lead with Spotify. Shazam does not hand out a
Spotify track id, so the script gives two things instead:
spotify_search - a deeplink that opens Spotify (app or web) on the right
result. Always present, always works, no account needed.
isrc - the recording's global id. This is what identifies the track without
ambiguity, across every service.
If you have a Spotify tool or MCP in this session, use it. Search for
Title Artist, then pick the hit whose album equals the album field from the
script - a popular track comes back several times (single, album, regional
release) and only the album match is the right one. Report that exact
open.spotify.com/track/... link and drop the search deeplink. If you have no
Spotify tool, report spotify_search and do not apologise for it.
apple_music is an exact link and comes for free; include it as a second line
only if the user has ever shown they use Apple Music. The Shazam link is for
when someone wants the source of the answer.
If the user says which service they use, follow that instead of the default.
That preference belongs in the app's own persistent instructions, not in this
skill - the skill only decides what to do when nobody said anything.
When there is no match
Exit code 1 means the fingerprint found nothing. In order:
- Retry deeper into the clip:
--offsets 5,20,35,50 --window 25. The first
seconds are often speech, a logo sting or silence.
- Long video with the music late: pick offsets by hand from the duration.
- Still nothing - report it plainly. Common real causes: original or
AI-generated audio, a live or cover version, the track is not in Shazam's
catalog, or a voice-over drowns the music. Say which one you suspect.
Do not fall back to a web search for lyrics unless the user asks. Guessed
titles from a search look like answers and are usually wrong.
Options
| Flag |
Meaning |
--offsets 0,10,25,45 |
Seconds to fingerprint, tried in order (default) |
--window 20 |
Length of each fingerprinted slice, in seconds |
--json |
Raw JSON (adds isrc, cover, shazam_id), for chaining |
--keep |
Keep the downloaded audio and print its path |
Failure modes worth knowing
ffmpeg is not on PATH - the decoder is missing. Install ffmpeg; nothing
works without it.
download failed: ... login required - the post is private or the account
is age-gated. yt-dlp cannot reach it; ask the user for the file instead.
- HTTP 429 from Shazam - too many lookups from this IP in a short window.
Wait and retry; do not loop.
- Every lookup suddenly failing - Shazam moved its endpoint. Bump
shazamio
in the script header.
1---2name: song-id3description: Identify the music playing in a video or audio clip by acoustic fingerprint. Use when the user pastes an Instagram Reel, TikTok, YouTube, X or any media URL and asks what the song is - "what song is this", "find the song", "song name", "welches Lied", "welcher Song", "was läuft da für Musik", "Musik aus dem Reel", "find the track", "name that tune" - or when they hand over a local video/audio file with the same question. Pulls the audio track, fingerprints it against Shazam, and reports title, artist, album, label, release year and streaming links.4license: MIT5---67# song-id89One command does the whole job:1011```12uv run scripts/identify_song.py "<url-or-file>"13```1415It downloads the audio (yt-dlp), cuts short slices, fingerprints them16(shazamio) and prints title, artist, album, label, year, cover art and17streaming links. Add `--json` for machine-readable output.1819## Rules2021- **Run it with `uv run`, never `pip install`, never bare `python`.** The22 script carries a PEP 723 header, so `uv` builds the environment itself and23 throws it away after.24- **Do not try to read the song from the post metadata.** Instagram strips the25 audio attribution out of what yt-dlp can see; `track` and `artist` come back26 empty. The fingerprint is the answer, not the metadata.27- **Do not guess.** If there is no match, say there is no match. A wrong song28 name is worse than none.29- One URL per call. For several links, call the script once per link.3031## Workflow32331. Take the URL exactly as the user pasted it. Reel, share and `?igsh=...`34 tracking links all work; do not clean them up.352. Run the script.363. Report the result in one or two lines: `Title - Artist`, then album, label37 and year, then a link the user can actually press - see below.3839## The link the user wants4041Most people are on Spotify, so lead with Spotify. Shazam does not hand out a42Spotify track id, so the script gives two things instead:4344- `spotify_search` - a deeplink that opens Spotify (app or web) on the right45 result. Always present, always works, no account needed.46- `isrc` - the recording's global id. This is what identifies the track without47 ambiguity, across every service.4849**If you have a Spotify tool or MCP in this session, use it.** Search for50`Title Artist`, then pick the hit whose album equals the `album` field from the51script - a popular track comes back several times (single, album, regional52release) and only the album match is the right one. Report that exact53`open.spotify.com/track/...` link and drop the search deeplink. If you have no54Spotify tool, report `spotify_search` and do not apologise for it.5556`apple_music` is an exact link and comes for free; include it as a second line57only if the user has ever shown they use Apple Music. The Shazam link is for58when someone wants the source of the answer.5960If the user says which service they use, follow that instead of the default.61That preference belongs in the app's own persistent instructions, not in this62skill - the skill only decides what to do when nobody said anything.6364## When there is no match6566Exit code 1 means the fingerprint found nothing. In order:67681. Retry deeper into the clip: `--offsets 5,20,35,50 --window 25`. The first69 seconds are often speech, a logo sting or silence.702. Long video with the music late: pick offsets by hand from the duration.713. Still nothing - report it plainly. Common real causes: original or72 AI-generated audio, a live or cover version, the track is not in Shazam's73 catalog, or a voice-over drowns the music. Say which one you suspect.7475Do not fall back to a web search for lyrics unless the user asks. Guessed76titles from a search look like answers and are usually wrong.7778## Options7980| Flag | Meaning |81| --- | --- |82| `--offsets 0,10,25,45` | Seconds to fingerprint, tried in order (default) |83| `--window 20` | Length of each fingerprinted slice, in seconds |84| `--json` | Raw JSON (adds `isrc`, `cover`, `shazam_id`), for chaining |85| `--keep` | Keep the downloaded audio and print its path |8687## Failure modes worth knowing8889- `ffmpeg is not on PATH` - the decoder is missing. Install ffmpeg; nothing90 works without it.91- `download failed: ... login required` - the post is private or the account92 is age-gated. yt-dlp cannot reach it; ask the user for the file instead.93- HTTP 429 from Shazam - too many lookups from this IP in a short window.94 Wait and retry; do not loop.95- Every lookup suddenly failing - Shazam moved its endpoint. Bump `shazamio`96 in the script header.