11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[WWDC 2021] iOS 15: ShazamKitを使用してオンライン音楽認識を行い、カスタムサウンドカタログを構築し、独自のiOSアプリでカスタムサウンドを認識します。

Last updated at Posted at 2021-09-19

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)

:relaxed: Twitter ツイッター @MszPro

私の公開されているQiita記事をカテゴリー別にご覧いただけます。

:sunny: 今後ともよろしくお願い致します。

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?