Generate a Shazam signature with only one line instead of 120

Mobile@Exxeta
6 min readDec 21, 2022

--

Recently, we worked on an app that would allow applicants and teams to get a first impression of each other. Looking for a way to make the experience more exciting for the user, we came across ShazamKit.

At WWDC 2021, Apple introduced it as a Software Development Kit for integrating audio recognition into apps.
You are probably familiar with the Shazam service, which has been providing information about a variety of different music tracks since 2002. With ShazamKit, the service is extended with the ability to make any audio recognizable.

We used this functionality of the CustomCatalog to sync the interface of our app with the audio of a video we made.

In this post, we would like to talk about our experience in generating the Shazam signatures needed for the synchronization.

What are Shazam signatures?

A Shazam signature can be understood as a kind of fingerprint for recognizing audio.
With the help of this fingerprint, we want to get certain properties of the audio.

For this purpose, any metadata can be assigned to a signature in so-called media items. Depending on the use case, an app should be able to react to one or more audios.

For each audio, a signature should be created and referenced with a MediaItembefore it is added to a catalog.

A short audio excerpt is matched against the custom catalog to obtain the corresponding metadata in case of a match with one of the included signatures.

Structure of a Custom Catalog (Adapted from Apple Inc., 2022, https://developer.apple.com/videos/play/wwdc2022/10028/)
Structure of a Custom Catalog (Adapted from Apple Inc., 2022, https://developer.apple.com/videos/play/wwdc2022/10028/)

Generating a Signature

Apple’s sample project includes a CatalogProvider that creates a custom catalog and adds a signature along with metadata.
The code-along to create custom audio experiences, which we followed for the implementation, did not go into further detail about the origin of the signature file used in this process.

We first wondered how to get the Shazam signature for our video and finally found what we were looking for in the ShazamKit documentation.
There you can find an article about “Generating a signature from an audio buffer” in the section SHSignatureGenerator.

With the given instructions, one could now build a tool — like Yuma Soerianto did — that generates signatures and even bundles them into catalogs.

Generating a Signature with SHSignatureGenerator

In our case, a simple Playground, in which we implemented the described instructions from the documentation and then saved the generated file on our device, was quite sufficient. The following three steps describe how we went about this.

1. Generating Signature

First, we inserted the code given in the documentation into our Playground; it defines the two functions generateSignature(from:) and convert(audioFile:, outputFile:, processConvertedBlock).

The function generateSignature(from:)expects the URL of the audio file to generate the signature from it and returns it.

For generating a signature, the file first needs to be converted into a specific format. This occurs within the function convert(audioFile:, outputFormat:, processConvertedlock:).

If you are following our approach, you have probably noticed that just copying the code generates errors. To solve this problem, you could put the two functions inside a class called CustomCatalog and later call its functions via an instance of it.
We decided against this and fixed the errors with the following two small adjustments:

  • We removed the call of the class CustomCatalog from the function generateSignature(from:) before convert(audioFile:, outputFormat:, processConvertedBlock:)
  • We also removed the static keyword prepended to the definition of the convert-function.
func generateSignature(from audioURL: URL) -> SHSignature? {
/* … */
convert(audioFile: audioFile, outputFormat: audioFormat) { buffer in
/* … */
}
/* … */
}

func convert(audioFile: AVAudioFile, outputFormat: AVAudioFormat, processConvertedBlock: (AVAudioPCMBuffer) -> Void) {
/* … */
}

2. Defining URLs

In the next step, we place the audio file for which we want to create a signature in the Resources folder of our Playground.
In our case, it is a video file named My_Video in mp4 format.

Since the URL of this file is needed to generate the Shazam signature, we have defined it in the variable audioURL.

At this point, we are able to generate a Signature file, but we also want to transfer it to our app project.

To later save the generated signature in our file system, we also defined the variable signatureURL to hold the path where it should be saved and additionally appended it with the filename My_Signature and its file extension shazamsignature.

let audioURL = Bundle.main.url(forResource: “My_Video”, withExtension: “mp4”)
let signatureURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(“My_Signature”).appendingPathExtension(“shazamsignature”)

3. Saving signature file

Now we are only a few lines of code away from reaching our signature.
To save the signature in the file system, we defined a function called saveSignature(signature:), which attempts to write the data representation of a generated signature to the signature URL we defined earlier.

To find the location where the file is stored, we print the signatureURL in the debug area of Xcode.

All we need to do now is generate the signature with generateSignature(from:) and the audioURL and then save it to the system with saveSignature(signature:) and the file can finally be found in the Finder at the location printed in the debug area.

func saveSignature(signature: SHSignature) {
do {
try signature.dataRepresentation.write(to: signatureURL, options: .atomic)
print(signatureURL)
} catch {
fatalError(“Signature could not be saved”)
}
}

if let signature = generateSignature(from: audioURL!) {
saveSignature(signature: signature)
}

Generating Signatures with the ShazamKit CLI

We found the given approach to generating Shazam signatures with the SHSignatureGenerator a little unsatisfying.
Especially when it comes to generating multiple signatures or when audio files change.

A year after the ShazamKit was introduced, Apple reported at WWDC 2022 the ShazamKit CLI as a solution that would simplify generating signatures.
We were even happier when, after a few months, with the release of the new MacOS Ventura, we were finally able to try out this tool.

To generate the signature of an audio all you must do is open the terminal in the folder where your file is located and run the following command, where My_Video.mp4 is the name of the input file and My_Signature.shazamsignature the name of the output.
As the result of this command you will find the Shazam signature file in the folder next to your audio file.

shazam signature -i My_Video.mp4 -o My_Signature.shazamsignature

To simplify the process of generating signatures for multiple audio files, we wrote a short shell script, which looks like this:

#!/bin/bash
for f in ./Videos/*;
do
audioFileName=$(basename — “$f”);
signatureFileName=”${audioFileName%.*}.shazamsignature”;

#generating signature
shazam signature -i “$f” -o “$signatureFileName”;

# moving signature to /Signature/ folder
mv “$signatureFileName” “./Signatures/”;
done

In the shell script, we are looping through all the files in a subfolder of the current directory, which is called /Videos/.
For every file in this folder, we are extracting its name from the directory path and also replacing its file extension with .shazamsignature.

After that, we are running the command to generate a signature, like already shown above.
This time we are using the file we are currently looping over as the input and the name we’ve created two lines above as the file name for the output.

For the magic to work, we first had to prepare our working directory.
We’ve created a folder named /Videos/ which contains all the videos we want to generate signatures for.
Furthermore, we added a second folder /Signatures/ where the signatures are moved after they are generated.
And last but not least we added the shell script file generateSignatures.sh to the current working directory.

Folder structure for generating multiple Shazam signatures with the ShazamKit CLI
Folder structure for generating multiple Shazam signatures with the ShazamKit CLI

To give the current user the permission to execute the shell script, we had to do one last thing; Open the terminal in the folder we just prepared and run the following command:

chmod u+x generateSignatures.sh

And finally, to execute the shell script run:

./generateSignatures.sh

Conclusion

The ability to make custom audio recognizable with ShazamKit offers exciting possibilities for the mobile user experience.

Generating the Shazam signature initially raised questions for us, and since ShazamKit was relatively new, there wasn’t as much input from other developers.
So we hope we were able to help you with our experience.

With the ShazamKit CLI, Apple provides a tool that simplifies the process enormously. Be sure to check out the WWDC 2022 video to see many more features of the CLI.

We wish you a lot of fun trying it out! (by Luisa Fröhlich)

--

--

Mobile@Exxeta

Passionate people @ Exxeta. Various topics around building great solutions for mobile devices. We enjoy: creating | sharing | exchanging. mobile@exxeta.com