ShazamKit(シャザム)は音声認識フレームワークです。Apple Musicのオンラインライブラリとの照合に使用できます。また、カスタムメイドされたオーディオライブラリとの照合にも使用できます。
この記事では、まずShazamKitを使って音楽を認識する方法について説明します。次に、独自のカスタム音声カタログの構築について説明し、独自の音声を認識します。
楽曲の認識
始める前に、音声を録音するためのAVKit
フレームワークと、音声を認識するためのShazamKit
をインポートします。
また、Info.plist
ファイルのNSMicrophoneUsageDescription
には必ず値を指定してください。
エンタイトルメントの設定
オンラインのShazamKit
サービスを利用してオンラインのミュージック ライブラリとマッチさせるには、ShazamKit
のエンタイトルメントを追加する必要があります。
https://developer.apple.com/account/resources/identifiers/list に移動し、アプリをクリックします。次に、App Services
タブをクリックしたら、ShazamKit
オプションをオンにして、Save
ボタンをクリックします。
まず、ShazamKit音楽認識セッションを設定します
最初に、SHSession
セッションオブジェクトを設定する必要があります。このオブジェクトは、認識対象のサウンドピースを受け取り、その結果を指定されたデリゲートに出力します。
private var session = SHSession()
private let audioEngine = AVAudioEngine()
表示が初期化されたらデリゲートを設定してください:
session.delegate = self
デリゲートの設定
認識結果の準備ができると、デリゲートを介して報告されます。
public protocol SHSessionDelegate : NSObjectProtocol {
optional func session(_ session: SHSession, didFind match: SHMatch)
optional func session(_ session: SHSession, didNotFindMatchFor signature: SHSignature, error: Error?)
}
didFind
関数では、録音を終了してからマッチング結果を表示します:
func session(_ session: SHSession, didFind match: SHMatch) {
audioEngine.stop()
for mediaItem in match.mediaItems {
print("Title: \(mediaItem.title); Artist: \(mediaItem.artist); Genres: \(mediaItem.genres.joined(separator: ",")); Artwork URL: \(mediaItem.artworkURL?.absoluteString); Apple Music URL: \(mediaItem.appleMusicURL)")
DispatchQueue.main.async {
// TODO: - Display the result on your UI interface
}
}
}
いくつかのプロパティは空の可能性があることに留意してください。
didNotFindMatchFor
機能では、まずレコーディングを行い、その後UIにエラーメッセージを表示します。
func session(_ session: SHSession, didNotFindMatchFor signature: SHSignature, error: Error?) {
print(error?.localizedDescription ?? "")
audioEngine.stop()
DispatchQueue.main.async {
self.viewState = .noResult
}
}
レコーディングを開始し、オーディオ認識のためにオーディオサンプルをShazamKitに供給してください
セッションオブジェクトをとデリゲートを設定しました。レコーディングを開始し、音声を認識することが可能です。
let inputNode = audioEngine.inputNode
let recordingFormat = inputNode.outputFormat(forBus: .zero)
inputNode.removeTap(onBus: .zero)
inputNode.installTap(onBus: .zero, bufferSize: 1024, format: recordingFormat) { [weak self] buffer, time in
self?.session.matchStreamingBuffer(buffer, at: time)
}
audioEngine.prepare()
do {
try audioEngine.start()
} catch {
print(error.localizedDescription)
}
これで、録音を開始し、ShazamKitに音声を認識させることができるようになります。
カスタムサウンドライブラリの構築
上のセクションでは、ShazamKitがApple Musicライブラリで音楽を認識しています。独自のサウンドライブラリを構築することも可能です。
サウンドライブラリを構築するには、まず様々な音声のシグネチャとそのメタデータを収集する必要があります。
private lazy var generator = SHSignatureGenerator()
レコーディング機能では、レコーディングを開始し、それに伴って新しいシグネチャをシグネチャジェネレーターに追加してください。
let inputNode = audioEngine.inputNode
let recordingFormat = inputNode.outputFormat(forBus: .zero)
inputNode.removeTap(onBus: .zero)
inputNode.installTap(onBus: .zero, bufferSize: 1024, format: recordingFormat) { [weak self] buffer, time in
try? self?.generator.append(buffer, at: time)
}
try? AVAudioSession.sharedInstance().setCategory(.record)
audioEngine.prepare()
do {
try self.audioEngine.start()
} catch {
DispatchQueue.main.async {
self.state = .initial
print(error.localizedDescription)
}
}
レコーディングが終了するとシグネチャが作成されますので、アレイに保存してください(このアレイにはあなたの全てのサウンドシグネチャが保存されています)。
self.audioEngine.stop()
let signature = self.generator.signature()
self.generator = SHSignatureGenerator()
let metaData = SHMediaItem(properties: [.title: "", .artist: ""])
let newAudioEntry = Entry(metaData: metaData,
signature: signature)
ここでは、私は1つのオーディオ機器のメタデータとサウンドシグネチャを保存するために、カスタムストラクトを使用しています。
そうすると、この音声アイテムを楽曲リストに追加することができます。ユーザーはより多くの楽曲を録音してラベルを付けることができ、関連情報がそのリストに追加されます。
ユーザーが楽曲をすべて録音したら、それらの楽曲の署名とメタデータを含むShazamカタログファイル(.shazamcatalog
の拡張子付き)を生成することができます。
let catalog = SHCustomCatalog()
do {
try viewModel.allSignatures.forEach { entry in
let signature = entry.signature
try catalog.addReferenceSignature(signature, representing: [entry.metaData])
}
let documentURL = getDocumentsDirectory()
.appendingPathComponent(UUID().uuidString)
.appendingPathExtension("shazamcatalog")
try catalog.write(to: documentURL)
} catch {
print(error.localizedDescription)
}
カスタムサウンドライブラリから音を認識
所定のShazamカスタムサウンドカタログファイルから音を認識できます:
let catalog = SHCustomCatalog()
try catalog.add(from: Bundle.main.url(forResource: "CustomSoundLibrary", withExtension: "shazamcatalog")!)
この記事の最初の部分で説明したものと同じ実装を使用できます。ただし、SHSession
オブジェクトを初期化する時、そのカタログファイルを使用します。
let session = SHSession(catalog: catalog)
私の公開されているQiita記事をカテゴリー別にご覧いただけます。
今後ともよろしくお願い致します。