下の記事を参考にShazamKitを動かしてみました。
ShazamKitは音楽認識ライブラリで、マイク経由で曲を渡すと曲名を出してくれたりします。
ShazamKitのiOS15から登場したライブラリで、SDKはAndroidでも使えるようです。
初期設定
まずは使いたいアプリのBundleIDのShazamKitを有効化します。
AppleのMemberCenterにアクセスしてShazamKitを使いたいBundleIDを登録してから「App Services」にあるShazamKitにチェックを入れて保存します。
実装
新規にプロジェクトを作成します。
BundleIDは先程登録したIDを使います。
音声認識の際にマイクを使うので、Info.plistにNSMicrophoneUsageDescriptionを追加してマイクを使う理由を記述します。
まずはマイクの音を取り込む実装をします。
ViewControllerを下のように修正します。
class ViewController: UIViewController { let engine = AVAudioEngine() override func viewDidLoad() { super.viewDidLoad() let audioSession = AVAudioSession.sharedInstance() try? audioSession.setCategory(.record) try? audioSession.setActive(true, options: .notifyOthersOnDeactivation) let inputNode = engine.inputNode try? engine.start() } }
起動するとマイクの音声を読み取る事ができるようになります。
次は読み取った音声を元に曲名を調べる実装をします。
ViewControllerを下のように変更します。
import UIKit import ShazamKit class ViewController: UIViewController { let session = SHSession() // 追加 let engine = AVAudioEngine() override func viewDidLoad() { super.viewDidLoad() let audioSession = AVAudioSession.sharedInstance() try? audioSession.setCategory(.record) try? audioSession.setActive(true, options: .notifyOthersOnDeactivation) let inputNode = engine.inputNode try? engine.start() // ここから追加 session.delegate = self let format = inputNode.outputFormat(forBus: .zero) inputNode.installTap(onBus: .zero, bufferSize: 1024, format: format) { buffer, _ in self.session.matchStreamingBuffer(buffer, at: nil) } } } extension ViewController: SHSessionDelegate { func session(_ session: SHSession, didFind match: SHMatch) { print(#function) print(match.mediaItems) } func session(_ session: SHSession, didNotFindMatchFor signature: SHSignature, error: Error?) { print(#function) print(error) } }
音声をShazamKitにわたす処理は下の箇所で行っています。
inputNode.installTap(onBus: .zero, bufferSize: 1024, format: format) { buffer, _ in self.session.matchStreamingBuffer(buffer, at: nil) }
読み取り成功時や失敗時はSHSessionDelegateのメソッドが呼ばれます。
extension ViewController: SHSessionDelegate { func session(_ session: SHSession, didFind match: SHMatch) { print(#function) print(match.mediaItems) } func session(_ session: SHSession, didNotFindMatchFor signature: SHSignature, error: Error?) { print(#function) print(error) } }
曲を流すと下のように正しく曲が認識されました。
日本の曲も試した所、正しく認識する事ができました。