npx claudepluginhub charleswiltgen/axiom --plugin axiomThis skill uses the workspace's default tool permissions.
ShazamKit provides audio recognition against Shazam's music catalog and custom audio catalogs. The framework covers matching, signature generation, catalog management, and library integration.
Provides Ktor server patterns for routing DSL, plugins (auth, CORS, serialization), Koin DI, WebSockets, services, and testApplication testing.
Conducts multi-source web research with firecrawl and exa MCPs: searches, scrapes pages, synthesizes cited reports. For deep dives, competitive analysis, tech evaluations, or due diligence.
Provides demand forecasting, safety stock optimization, replenishment planning, and promotional lift estimation for multi-location retailers managing 300-800 SKUs.
ShazamKit provides audio recognition against Shazam's music catalog and custom audio catalogs. The framework covers matching, signature generation, catalog management, and library integration.
For decision trees, setup checklist, and best practices, see the shazamkit discipline skill.
Platform: iOS 15+, iPadOS 15+, macOS 12+, tvOS 15+, watchOS 8+, visionOS 1+
A managed session that handles recording and matching captured sound automatically. This is the modern, recommended path for microphone-based recognition.
init() // Matches against Shazam catalog
init(catalog: SHCatalog) // Matches against custom catalog
func result() async -> SHSession.Result // Single match attempt
var results: SHManagedSession.Results // AsyncSequence for continuous matching
func prepare() async // Preallocate resources + start prerecording
func cancel() // Stop recording + cancel current match
var state: SHManagedSession.State // Current session state
SHManagedSession conforms to Observable (iOS 17+). SwiftUI views refresh automatically on state changes.
Conforms to Sendable as of iOS 18.
@frozen enum State
| Case | Meaning |
|---|---|
.idle | Not recording or matching |
.prerecording | Prepared, recording in anticipation of match |
.matching | Actively making match attempts |
Lower-level session for matching audio buffers or signatures against catalogs.
init() // Matches against Shazam catalog
init(catalog: SHCatalog) // Matches against custom catalog
func match(_ signature: SHSignature) // Match a complete signature
func matchStreamingBuffer(_ buffer: AVAudioPCMBuffer, at time: AVAudioTime?) // Match streaming audio
When using matchStreamingBuffer, include the time parameter when available — the session validates contiguous audio.
var delegate: (any SHSessionDelegate)?
var results: SHSession.Results // AsyncSequence of SHSession.Result
When a query matches multiple reference signatures in a custom catalog, all matches are returned sorted by quality. Use metadata annotation to distinguish between them.
@frozen enum Result: Sendable
| Case | Associated Value |
|---|---|
.match(SHMatch) | Matched media items found |
.noMatch(SHSignature) | No match for this signature |
.error(any Error, SHSignature) | Error during matching |
protocol SHSessionDelegate: NSObjectProtocol
optional func session(_ session: SHSession, didFind match: SHMatch)
optional func session(_ session: SHSession, didNotFindMatchFor signature: SHSignature, error: (any Error)?)
Contains the results of a successful match.
var mediaItems: [SHMatchedMediaItem] // Matched items (multiple possible)
var querySignature: SHSignature // The query that produced this match
Metadata associated with a reference signature.
init(properties: [SHMediaItemProperty : any NSSecureCoding & NSObjectProtocol])
| Property | Type | Description |
|---|---|---|
.title | String | Song/content title |
.subtitle | String | Subtitle |
.artist | String | Artist name |
.artworkURL | URL | Album art URL |
.videoURL | URL | Video URL |
.genres | [String] | Genre list |
.explicitContent | Bool | Explicit content flag |
.isrc | String | International Standard Recording Code |
.appleMusicID | String | Apple Music identifier |
.appleMusicURL | URL | Apple Music URL |
.webURL | URL | Web URL for sharing |
.shazamID | String | Shazam catalog identifier |
.creationDate | Date | When item was created |
| Property | Type | Description |
|---|---|---|
.timeRanges | [Range<TimeInterval>] | When this item is active in the reference |
.frequencySkewRanges | [Range<Float>] | Frequency skew ranges for differentiation |
Add custom metadata using SHMediaItemProperty extensions:
extension SHMediaItemProperty {
static let episodeNumber = SHMediaItemProperty("episodeNumber")
static let teacher = SHMediaItemProperty("teacher")
}
let item = SHMediaItem(properties: [
.title: "Episode 3",
.episodeNumber: 3,
.teacher: "Neil"
])
Custom property values must be valid property list types.
class func fetch(shazamID: String, completionHandler: @escaping (SHMediaItem?, (any Error)?) -> Void)
Requests a media item from the Shazam catalog by its Shazam ID.
subscript(key: SHMediaItemProperty) -> Any { get }
NSSecureCoding, NSCopying, NSObjectProtocol, Identifiable (iOS 17+), Sendable
Subclass of SHMediaItem with match-specific information. Only created by the framework from successful matches.
| Property | Type | Description |
|---|---|---|
.matchOffset | TimeInterval | Where in the reference the match occurred |
.predictedCurrentMatchOffset | TimeInterval | Auto-updating position in reference (seconds) |
.frequencySkew | Float | Frequency difference between matched and reference |
.confidence | Float | Match confidence (0.0 to 1.0, where 1.0 is highest) |
predictedCurrentMatchOffset updates continuously during streaming matches — use it to sync UI to audio position.
struct SHMediaItemProperty: RawRepresentable, Hashable, Sendable
Predefined property keys for SHMediaItem. Extend with custom keys using init(rawValue:).
.title, .subtitle, .artist, .artworkURL, .videoURL, .genres, .explicitContent, .isrc, .appleMusicID, .appleMusicURL, .webURL, .shazamID, .creationDate, .matchOffset, .frequencySkew, .confidence, .timeRanges, .frequencySkewRanges
Contains opaque audio fingerprint data.
var duration: TimeInterval // Duration of audio represented
var dataRepresentation: Data // Serializable data for storage/transmission
init(dataRepresentation: Data) throws
func slices(from start: TimeInterval, duration: TimeInterval, stride: TimeInterval) -> SHSignature.Slices
Returns a sequence of signature segments of the specified duration, stepping by stride from the start offset.
NSSecureCoding, NSCopying, NSObjectProtocol, Sendable
Converts audio into signatures.
func append(_ buffer: AVAudioPCMBuffer, at time: AVAudioTime?) throws
func signature() -> SHSignature
static func signature(from asset: AVAsset) async throws -> SHSignature
Accepts any AVAsset with an audio track. Multiple tracks are mixed automatically.
Abstract base class for catalogs.
var minimumQuerySignatureDuration: TimeInterval // Minimum query length needed
var maximumQuerySignatureDuration: TimeInterval // Maximum useful query length
Mutable catalog for custom audio matching.
func addReferenceSignature(_ signature: SHSignature, representing mediaItems: [SHMediaItem]) throws
func write(to url: URL) throws // Save .shazamcatalog file
func add(from url: URL) throws // Load/merge from file
File extension: .shazamcatalog
Sendable
User's synced Shazam library. Each app can only read and delete items it has added.
static var `default`: SHLibrary
func addItems(_ items: [SHMediaItem]) async throws
func removeItems(_ items: [SHMediaItem]) async throws
var items: [SHMediaItem] { get } // Observable
let currentItems = await SHLibrary.default.items
Conforms to Observable. SwiftUI views using SHLibrary.default.items update automatically when items change.
Items sync across devices via iCloud. Attributed to the app that added them. Visible in Shazam app and Control Center Music Recognition module.
Legacy write-only access to the user's Shazam library.
static var `default`: SHMediaLibrary
func add(_ mediaItems: [SHMediaItem], completionHandler: @escaping (Error?) -> Void)
struct SHError: Error
| Code | Description |
|---|---|
.matchAttemptFailed | Match attempt failed |
.signatureInvalid | Invalid signature data |
| Code | Description |
|---|---|
.customCatalogInvalid | Catalog data is corrupt or invalid |
.customCatalogInvalidURL | URL for catalog is invalid |
| Code | Description |
|---|---|
.signatureDurationInvalid | Signature duration too short or long |
.audioDiscontinuity | Gap detected in streaming audio |
| Code | Description |
|---|---|
.mediaLibrarySyncFailed | Failed to sync with library |
.internalError | Internal framework error |
| Code | Description |
|---|---|
.invalidAudioFormat | Audio format not supported |
.mediaItemFetchFailed | Failed to fetch media item details |
Command-line tool for building custom catalogs at scale.
# Create signature from media file
shazam signature --input <media-file> --output <signature-file>
# Create custom catalog
shazam custom-catalog create \
--input <signature-file> \
--media-items <csv-file> \
--output <catalog-file>
# Update existing catalog
shazam custom-catalog update \
--input <signature-file> \
--media-items <csv-file> \
--catalog <catalog-file>
# Display catalog contents
shazam custom-catalog display --catalog <catalog-file>
# Add/remove/export signatures and media items
shazam custom-catalog add ...
shazam custom-catalog remove ...
shazam custom-catalog export ...
Run shazam custom-catalog create --help for CSV header-to-property mapping.
FoodMath educational app demonstrating custom catalog matching with synced UI content. Uses SHSession with delegate pattern.
Key patterns: Custom SHMediaItemProperty extensions, predictedCurrentMatchOffset for time-sync, SHCustomCatalog from .shazamsignature files.
Dance discovery app using SHManagedSession for simplified matching. Demonstrates SHLibrary read/write/delete and Observable SwiftUI integration.
Key patterns: SHManagedSession result/results, session state in SwiftUI, SHLibrary.default.items in List, swipe-to-delete with removeItems.
SHCatalog (abstract)
├── SHCustomCatalog (mutable, user-created)
└── (internal Shazam catalog)
SHMediaItem
└── SHMatchedMediaItem (match-specific subclass)
SHSession → delegate or AsyncSequence
SHManagedSession → AsyncSequence, Observable, handles recording
| Task | API |
|---|---|
| Identify song (iOS 17+) | SHManagedSession().result() |
| Continuous recognition | for await result in session.results |
| Match custom audio | SHManagedSession(catalog: custom) |
| Match signature file | SHSession().match(signature) |
| Generate from file | SHSignatureGenerator.signature(from: asset) |
| Generate from mic | generator.append(buffer, at: time) |
| Add to library | SHLibrary.default.addItems([item]) |
| Read library | SHLibrary.default.items |
| Remove from library | SHLibrary.default.removeItems([item]) |
| Extension | Purpose |
|---|---|
.shazamsignature | Audio signature file |
.shazamcatalog | Custom catalog file |
WWDC: 2021-10044, 2021-10045, 2022-10028, 2023-10051
Docs: /shazamkit, /shazamkit/shmanagedsession, /shazamkit/shsession, /shazamkit/shcustomcatalog, /shazamkit/shmediaitem, /shazamkit/shlibrary
Skills: shazamkit, avfoundation-ref, swift-concurrency