shazamio-core
Audio fingerprinting for Shazam, written in Rust and exposed to Python.
It turns an audio file, or its bytes, into the signature Shazam's endpoint accepts. It does not talk to Shazam itself: ShazamIO is the client that sends the signature and reads the answer back.
Install
pip install shazamio-core
Or with uv:
uv add shazamio-core
Python 3.10 and newer. Prebuilt wheels:
| Platform | CPython 3.10+ (abi3) |
PyPy 3.11 |
|---|---|---|
Linux x86_64, aarch64 (manylinux_2_28) |
yes | yes |
Linux x86_64, aarch64 (musllinux_1_2) |
yes | no |
macOS x86_64 (10.12+), arm64 (11.0+) |
yes | no |
Windows win_amd64, win32 |
yes | no |
Everything else builds from the source distribution, which needs a Rust toolchain 1.87 or newer, CMake and a C compiler. libopus is built from vendored sources rather than linked against a system copy, so without CMake the build stops on is 'cmake' not installed?.
Usage
Both entry points return an asyncio.Future rather than a coroutine, so they need a running event loop at the call and the work starts there rather than at the await. await, asyncio.ensure_future and asyncio.gather all accept what they return; asyncio.create_task takes a coroutine alone and rejects it. Cancelling one drops its result but not its work: the decode runs to the end on a worker thread, and later calls are unaffected.
import asyncio
from pathlib import Path
from shazamio_core import Recognizer
async def main() -> None:
recognizer = Recognizer()
from_path = await recognizer.recognize_path("track.mp3")
from_bytes = await recognizer.recognize_bytes(Path("track.mp3").read_bytes())
print(from_path.signature.uri == from_bytes.signature.uri)
asyncio.run(main())
recognize_path accepts a str or an os.PathLike[str]. A __fspath__ returning bytes is rejected.
What comes back
Both return a Signature:
| Field | Meaning |
|---|---|
signature.uri |
the fingerprint itself, base64 inside a data:audio/vnd.shazam.sig URI |
signature.samples |
duration of the analysed segment in milliseconds |
timestamp |
when the signature was produced, in epoch milliseconds |
timezone |
a fixed value the request envelope carries. It is not read from the machine and means nothing |
Every field above is read only: assigning to one raises AttributeError. Neither class can be built by hand: Signature() raises TypeError.
The URI is the part a client sends on:
data:audio/vnd.shazam.sig;base64,gCX+ypQoAnWcBQAAAJwRlAAAAAA...
How much audio is analysed
Ten seconds by default, taken from the middle of the file. A file shorter than the segment is used whole. Audio is converted to mono and downsampled to 16 kHz before analysis, whatever it started as.
Set it per recognizer, or per call:
import asyncio
from shazamio_core import Recognizer, SearchParams
async def main() -> None:
recognizer = Recognizer(segment_duration_seconds=5)
signature = await recognizer.recognize_path(
"track.mp3",
SearchParams(segment_duration_seconds=15),
)
print(signature.signature.samples)
asyncio.run(main())
SearchParams wins where both are given. The duration must be at least 1; zero
raises ValueError. A value at or above the length of the file analyses it whole,
whatever the value.
Errors
Anything the decoder cannot use raises SignatureError, and the message opens with the input that failed: the path for recognize_path, the byte payload for recognize_bytes.
| Given | Message |
|---|---|
| a path that is not there | <input>: No such file or directory (os error 2) |
| a stream nothing in this build reads, a directory included | <input>: unsupported feature: no reader in this build recognises the stream |
| a container that is read, holding a codec that is not | <input>: unsupported feature: the stream carries no track with a codec this build can decode |
| a recording cut short | <input>: unexpected end of file |
A recording cut short is refused rather than fingerprinted from what is left, with three exceptions. MP4 and Matroska fail before decoding starts and report that no reader recognises the stream. MP3 and MP2 decode up to the cut and are not refused, because a run of MPEG frames does not reliably say how long it is. A chained Ogg file cut inside a later link loses that link and is not refused either, which is a bug in symphonia.
What follows the input is symphonia's wording, or the operating system's, and differs between platforms.
An argument of the wrong type raises TypeError instead, and raises it at the call rather than on the await, so nothing is scheduled.
A panic inside the extension is a bug here rather than bad input. It raises RustPanic, an Exception subclass the package does not export, on the await, with the panic message after rust future panicked: .
import asyncio
from shazamio_core import Recognizer, SignatureError
async def main() -> None:
try:
await Recognizer().recognize_path("not-audio.txt")
except SignatureError as error:
print(error)
asyncio.run(main())
Formats
Decoding goes through symphonia with every codec and container it ships enabled, and resampling to mono 16 kHz through rubato. Opus is the one codec symphonia has no decoder for, so it goes through libopus, which is compiled into the wheel rather than loaded from the system. Nothing is shelled out to, so no external binary has to be installed.
That leaves these codecs, each one probed through the public API in the container named beside it:
| Codec | Probed in | In the test suite |
|---|---|---|
| AAC | ADTS | yes |
| ADPCM | WAV | yes |
| ALAC | MP4 | yes |
| FLAC | FLAC | yes |
| MP1 | not probed | |
| MP2 | MPEG | yes |
| MP3 | MPEG | yes |
| Opus | Ogg | yes |
| PCM | WAV, AIFF, CAF | yes |
| Vorbis | Ogg | yes |
MP1 is the one row taken from what symphonia registers rather than from a run: nothing here encodes it. The containers recognised are ADTS, AIFF, CAF, FLAC, Matroska and WebM, MP4, MPEG, Ogg and WAV, and the test suite runs on Linux, macOS and Windows.
Anything else raises SignatureError, and a container from that list is no guarantee: what has to be decodable is the codec inside it. The two refusals differ in how far the file gets:
| Refused | Fails as | Why |
|---|---|---|
| AC-3 in Matroska | no track with a codec this build can decode |
the container is read, the codec is not |
| WMA in ASF | no reader in this build recognises the stream |
there is no ASF demuxer at all |
Windows Media Audio decoded in earlier releases through an ffmpeg fallback that has since been removed.
Development
Setting up a checkout, what to run before a pull request and how commits are shaped: CONTRIBUTING.md.
License
MIT. See LICENSE.
The wheel statically links its Rust dependencies, so the terms in
THIRD-PARTY-NOTICES.md apply to it as well. That file
says how it is generated; just licenses-check fails once a dependency change
has left it behind.
Metadata
Release files for shazamio-core 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| shazamio_core-2.0.0.tar.gz | 1.5 MB | Details |
Built distributions (wheels)
Total release size: 19.0 MB
Release files / shazamio_core-2.0.0.tar.gz
| Download URL | shazamio_core-2.0.0.tar.gz |
|---|---|
| Size | 1.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9849276a3a4795683e29218cd8aac14acdcc8bae66df13304b8ce5d7b9077a12
|
|
BLAKE2b-256 checksum How to use checksums |
5e6a32ee3fd095df7bb03419657b064d50e9053b95dc05cf04ca64dcdef5e27c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl
| Download URL | shazamio_core-2.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | Linux glibc 2.28+ x86-64 PyPy 3.11 PyPy 3.11 7.3 |
|
SHA-256 checksum How to use checksums |
ee8e22b22d2e5a162cc5e5058521219865768dba819b371a235bf84899a38da6
|
|
BLAKE2b-256 checksum How to use checksums |
44e5312259213cce85c57a78423612d6c55c1b6756a5f1dda4df6d2aae65dcc6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl
| Download URL | shazamio_core-2.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | Linux glibc 2.28+ ARM64 PyPy 3.11 PyPy 3.11 7.3 |
|
SHA-256 checksum How to use checksums |
05abcc0dcf09ab6a0c2ab98a5a1533bef1fd0fe990f8a5da6a29d3c2010f6adb
|
|
BLAKE2b-256 checksum How to use checksums |
9f0dca3815a4f838bf76a24116113b7e3b2afca707b6aef41928bf7ed5584dbe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-cp310-abi3-win_amd64.whl
| Download URL | shazamio_core-2.0.0-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
bd1ace4ac7409465eb028e67160d09cf77d49de8f64b70b9aa408c0842dc9eb9
|
|
BLAKE2b-256 checksum How to use checksums |
68f28549445ad5dd1523643f9e26bccfb83408466912889e946641b9b0bce7d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-cp310-abi3-win32.whl
| Download URL | shazamio_core-2.0.0-cp310-abi3-win32.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.10 Windows x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
2ec2f5b1a00c5aac824c36a531e48f8df6bb684462c60414825eb9a06fbee9ee
|
|
BLAKE2b-256 checksum How to use checksums |
4add747e92783181bcf229f79243069466d8e3e6f4927d794aa55bdfc61d0309
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-cp310-abi3-musllinux_1_2_x86_64.whl
| Download URL | shazamio_core-2.0.0-cp310-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
da6f9780115718baa3d57ea59279237976e73fa60cd0857f0a83bab9e56cf8aa
|
|
BLAKE2b-256 checksum How to use checksums |
d2c6e75651fd454eb8b62d69801134f52d224dc40a52faf406a66b9243655c9f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-cp310-abi3-musllinux_1_2_aarch64.whl
| Download URL | shazamio_core-2.0.0-cp310-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.10 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
d622afea5231e692f1bf12ef5839791c46970222b792a617660e0505e3763fac
|
|
BLAKE2b-256 checksum How to use checksums |
af747ea1cbe7226f06cbd25f9f00c0e5b4b82705f8f6a542cf8a8eca08993321
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | shazamio_core-2.0.0-cp310-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
66b4897a58c0c82b087acc7c8117f3ce8a30a89c8e17103f8ff35c45af11bb48
|
|
BLAKE2b-256 checksum How to use checksums |
13a19b4fe5c0a7a03565b4dcc9a7659c7877786ab395010342ff89671693ed60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-cp310-abi3-manylinux_2_28_aarch64.whl
| Download URL | shazamio_core-2.0.0-cp310-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
b5fab1063d47bd13048aa316728e593ec2bb074a0ec2c05a56473556ddf9a962
|
|
BLAKE2b-256 checksum How to use checksums |
5af35f3474e9218d98bbb152aa1742de877e16dea404387a09e8bf211ec91c15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | shazamio_core-2.0.0-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
024a3d63cae76757c6d52bd9b25e6fc81a1cdbbf9cad53c2a8d7e5c3c913e93d
|
|
BLAKE2b-256 checksum How to use checksums |
92349728e3df03d7eeedd049af88244a05a9c6fc96b726ca5fb270d226c1e034
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / shazamio_core-2.0.0-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | shazamio_core-2.0.0-cp310-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.10 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
dd20b534563a12fc3f6e1f38fd91b2edc3941f583295c60f806fb0ff26ba55cb
|
|
BLAKE2b-256 checksum How to use checksums |
5967f9256e37808e6ae61fa8f037bef97464ec4188f7be888527fb6e482d3177
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|