
「音声が再生し終わったら処理をしたい」「エラーが起きたら通知を受けたい」
そんなときに役立つのが AVAudioPlayerDelegate プロトコル です。
AVAudioPlayerDelegateは、AVAudioPlayer(音声再生用クラス)の再生完了やエラー発生を検知できる仕組みを提供します。
音楽・効果音・音声読み上げなどを扱うアプリで、音声のライフサイクルに応じた処理を入れたい場合に非常に便利です。
AVAudioPlayerDelegateとは?
AVAudioPlayerDelegate は、AVAudioPlayerの動作イベントを受け取るためのプロトコルです。
音声の再生中や再生後、エラー発生時にコールバックを受け取って処理を行えます。
具体的には次のような場面で使えます:
- 再生が最後まで終わったとき
- 再生中にエラーが発生したとき
- デコード中にエラーが発生したとき
AVAudioPlayerは音声再生を行うクラスですが、単純に再生だけならDelegateを使わなくても動きます。
しかし「再生が終わった後に何かしたい」「途中でエラーがあったらUIを更新したい」といった場合、Delegateを使うことで簡単に実現できます。
実装に必要な必須プロパティ
AVAudioPlayerDelegateを使う場合、次のプロパティを最低限設定する必要があります。
1 2 |
var audioPlayer: AVAudioPlayer? |
- 音声を再生するための AVAudioPlayerインスタンス を保持します。
- Delegateメソッドから参照できるよう、クラスのプロパティとして定義します。
1 2 |
audioPlayer?.delegate = self |
- AVAudioPlayerの
delegate
プロパティに、自分自身(self
)を設定します。 - これにより、再生完了やエラー発生時にDelegateメソッドが呼ばれるようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class SoundManager: NSObject, AVAudioPlayerDelegate { var audioPlayer: AVAudioPlayer? func playSound() { if let url = Bundle.main.url(forResource: "sound", withExtension: "mp3") { do { audioPlayer = try AVAudioPlayer(contentsOf: url) audioPlayer?.delegate = self // Delegateの設定 audioPlayer?.play() } catch { print("音声の再生に失敗しました: \(error)") } } } } |
どういう機能を使いたい時に便利なのか?
AVAudioPlayerDelegateは、「ただ音を流すだけ」では物足りないときに力を発揮します。
特に、再生完了を合図にして別の処理を始めたい場合や、再生中のエラーに対応したい場合に有効です。
たとえば次のようなケースで役立ちます。
-
効果音の再生後に別の音声を流す
-
音楽再生が終わったら次の曲に切り替える
-
エラー発生時に再試行処理をする
-
再生終了後にボタンやUIを元の状態に戻す
-
複数の音声を順番に再生するキュー制御
つまり、単なるループ再生やBGM再生だけではなく、「再生終了をトリガーにして処理を動かす必要がある場合」に強みを発揮するのがこのプロトコルです。
類似のプロトコルとの違い・使い分け
音声や動画を扱う場合、AVAudioPlayerDelegate 以外にも似た役割を持つ仕組みがいくつかあります。
特に混同しやすいのが AVAudioRecorderDelegate と、動画・ストリーミング再生に使う AVPlayer+AVPlayerItem の組み合わせです。
それぞれ用途や特徴が異なるため、どれを使うべきかを理解しておくと、再生・録音・ストリーミングなどの処理をより適切に設計できます。
AVAudioPlayerDelegate と AVAudioRecorderDelegate
- AVAudioPlayerDelegate
- 音声再生専用のデリゲート。
- 音声の再生開始~終了の流れや、再生中のエラーなどを検知できます。
- たとえば、音楽の再生が終わったら次の曲を再生する、再生が終わったらUIを元に戻す、といった処理をここで行います。
- AVAudioRecorderDelegate
- 音声録音専用のデリゲート。
- 録音が終了したときや、録音中にエラーが発生したときに呼ばれます。
- 録音アプリや音声メモ機能などで、録音が完了したらファイル保存や解析処理を行う場合に便利です。
つまり、再生の流れを制御したい場合はAVAudioPlayerDelegate、録音を制御したい場合はAVAudioRecorderDelegate を使います。
両方を同じクラスで実装することも可能ですが、役割は明確に分かれています。
AVAudioPlayerDelegate と AVPlayer+AVPlayerItem の通知との違い
AVPlayerとは?
AVPlayer は 動画やストリーミング音声を再生するためのクラス です。
ローカルのMP4動画や、オンライン配信の音声/動画を再生できます。
基本的に非同期再生が前提で、Delegateではなく NotificationCenterやKVO(Key-Value Observing) を使って状態変化を監視します。
AVPlayerItemとは?
AVPlayerItem は、AVPlayerで再生する 1つのメディア(音声や動画)の再生情報を管理するオブジェクト です。
再生時間、バッファ状態、ステータス(再生可能・エラーなど)を持っており、通知やKVOで監視できます。
違いと使い分け
- AVAudioPlayerDelegate
- 主にローカルの音声ファイル(mp3, wavなど)や短いBGM、効果音再生に向く
- 再生終了やエラーをDelegateメソッドで受け取る
- シンプルで軽量、通知やKVOを使わずに処理できる
- AVPlayer+AVPlayerItem
- 動画やオンライン配信(ストリーミング)向け
- 再生状態はNotificationCenterやKVOで監視
- ネットワーク接続、バッファリングなどの高度な制御が可能
使い分けの目安
- 短い効果音・ローカルBGM → AVAudioPlayerDelegate
- 動画再生やオンライン配信音声 → AVPlayer+AVPlayerItem
例えば、ゲームアプリの効果音はAVAudioPlayerDelegateで十分ですが、音楽ストリーミングアプリや動画アプリはAVPlayerを使うのが定番です。
具体例① 再生完了を検知する
まずは、音声の再生が最後まで終わったタイミングを検知する方法です。
例えば効果音を流し終わったら「完了しました!」と表示したい場合に使えます。
やりたいこと
- 効果音(mp3ファイル)を再生する
- 再生終了時に処理を行う(メッセージを表示する)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import AVFoundation class SoundManager: NSObject, AVAudioPlayerDelegate { var audioPlayer: AVAudioPlayer? func playSound() { if let url = Bundle.main.url(forResource: "sound", withExtension: "mp3") { do { // AVAudioPlayerを生成し、音声ファイルを読み込み audioPlayer = try AVAudioPlayer(contentsOf: url) // 再生イベントを受け取るためのデリゲート設定 audioPlayer?.delegate = self // 再生開始 audioPlayer?.play() } catch { print("音声の再生に失敗しました: \(error)") } } } // 再生完了イベントを受け取るメソッド func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { if flag { print("再生が完了しました!") } else { print("再生中に問題が発生しました。") } } } |
audioPlayer?.delegate = self
→ AVAudioPlayerDelegateを自分自身(SoundManager)に設定し、再生イベントを受け取れるようにしています。audioPlayerDidFinishPlaying
→ 再生が終了した瞬間に自動で呼ばれるメソッド。ここに後続処理を記述します。flag
→ 再生が正常に完了したかどうかを示すブール値。true
なら成功、false
なら途中でエラーや中断。
具体例② エラー発生を検知する
次は、音声のデコード中にエラーが発生した場合に検知する方法です。
例えば、破損した音声ファイルや非対応フォーマットを再生しようとしたときに役立ちます。
やりたいこと
- 再生中にデコードエラーが起きたらログ出力する
- 必要に応じてUIや状態を更新する
1 2 3 4 5 6 7 8 |
func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) { if let error = error { print("デコードエラー発生: \(error.localizedDescription)") } else { print("原因不明のデコードエラーが発生しました") } } |
- デコード処理(音声データを再生可能な形式に変換する過程)で問題が発生すると、このメソッドが呼ばれます。
- 引数
error
から具体的なエラー内容を取得できます。 - ここでアラート表示や再試行処理を行えば、ユーザー体験を向上できます。
こうしたイベント検知を組み込むことで、AVAudioPlayerは「ただ音を再生する」だけでなく、再生完了やエラー発生をトリガーにした高度な制御が可能になります。
特にゲームや教材アプリなど、音声の終了タイミングに合わせて画面遷移やエフェクトを出すといったケースでは必須の仕組みです。
まとめ
プロトコル名 | 用途 | 主な通知イベント |
---|---|---|
AVAudioPlayerDelegate | 音声再生の完了・エラー検知 | 再生完了・デコードエラー |
AVAudioRecorderDelegate | 音声録音の完了・エラー検知 | 録音完了・デコードエラー |
AVPlayer通知 | 動画・ストリーミングの状態監視 | 再生完了・バッファ状態 |
使うべきシーン
- 再生終了後に処理を走らせたい
- 再生中にエラーが起きたら復旧処理をしたい
- 複数音声を順番に再生する制御をしたい
参考リンク