Audio Session細かいことまとめ

SessionActive化のタイミング
電話がかかってきて電話に出た時は、End Interruptionが呼ばれないそうなので、どこでSessionをActiveにするか、検討する必要がある。


割り込みのタイミング
アプリをバックグラウンドにしたときに音楽を再生していない場合は割り込みが入る(イニシャライズ時に指定した関数が走る)。再生している時は入らない。「何もしていないなら切りますよ」的なニュアンスで何かの処理が走る模様。割り込み関数が実際に走るのはフォアグラウンドにしたとき。begin分とend分の2回走る。

バックグラウンド機能のON OFFやmixWithOthersのON OFFも関係あります。

AVPlayerの割り込みメソッド呼び出しについて
AudioSessionのイニシャライズ時に指定する割り込みメソッドは再生中で無くても呼ばれるが、AVPlayerの割り込みメソッドはplay中でないと呼ばれない。(検証不十分)


AVPlayerの自動SessionActive機能について
AVPlayerには割り込み完了時にSessionActiveをYESにする機能があるのだが、この機能が少し癖があるので気を付けたい。
まずはいろいろなパターンを調べた。割り込みはiOSに付属しているアラームを使った。ちなみにタイマーだと1つしか登録できないが、アラームだと複数登録できる。

パターン1:初めにアラーム設定し、アプリを起動する
アラーム設定する
アプリ起動
AVPlayerインスタンス作成
セッション初期化
セッションアクティブ化
アラーム発生
アラーム処理(OKをタップ)
次のアラーム発生で割り込みメソッドが呼ばれない
自動でアクティブ化されない


パターン2:アプリを起動してから一旦バックグラウンドにして、アラーム設定し、再びアプリを起動する
アプリ起動
AVPlayerインスタンス作成
セッション初期化
セッションアクティブ化
アラーム設定する
アプリ起動
AVPlayerインスタンス作成(viewDidLoadに入れていたので再び処理が走った)
セッション初期化(viewDidLoadに入れていたので再び処理が走った)
セッションアクティブ化(viewDidLoadに入れていたので再び処理が走った)
アラーム発生
アラーム処理(OKをタップ)
次のアラーム発生で割り込みメソッドが呼ばれる
自動でアクティブ化される

パターン2は、パターン1と同じ事をやろうとしたけどアプリ起動前にアラーム設定をするのを忘れてしまいアプリ起動後に行ったもの。


パターン3:パターン1にプレイ操作を入れた
アラーム設定する
アプリ起動
AVPlayerインスタンス作成
セッション初期化
セッションアクティブ化
プレイ操作
アラーム発生
アラーム処理(OKをタップ)
次のアラーム発生で割り込みメソッドが呼ばれる
自動でアクティブ化される


パターン4:プレイ操作自体にアクティブ化と自動アクティブ機能ON化が含まれているのでは?という読みで次のパターンもやってみた。
アラーム設定する
アプリ起動
AVPlayerインスタンス作成
セッション初期化
セッションアクティブ化(やりません)
プレイ操作
アラーム発生
アラーム処理(OKをタップ)
次のアラーム発生で割り込みメソッドが呼ばれる
自動でアクティブ化される
初めのアラーム発生のところで割り込み関数が呼ばれましたのでプレイ操作の時点でアクティブ化されたようです。まあアクティブ化は一応明記したほうがいいでしょう。また、プレイ操作直後にストップ操作を入れても結果は変わらず。


パターン1とパターン2の違いが謎でしたが、AVPlayerインスタンス作成時にセッション初期化が一度でも走っているかどうかの違いがあります。パターン5をやってみました。

パターン5:パターン1でAVPlayerインスタンス作成のタイミングをセッション初期化後に変更
アラーム設定する
アプリ起動
セッション初期化
セッションアクティブ化
AVPlayerインスタンス作成
アラーム発生
アラーム処理(OKをタップ)
次のアラーム発生で割り込みメソッドが呼ばれる
自動でアクティブ化される
やはりAVPlayerインスタンス作成時にAudioSessionが初期化されているかどうかがポイントのようです。インスタンス作成をアクティブ化の前にしても結果は変わらず。念の為、アクティブ化を省いてやってみたら、初めのアラーム発生でも割り込み関数は呼ばれません。また、2つめのアラーム発生時にも呼ばれません。最初のアクティブ化は、明記するか、プレイする必要があるようです(今のところの結果より)。


今のところのまとめ
割り込み解除時のAudioPlayerによる自動SessionActive化機能は次の条件でONされる
・曲プレイされたとき
・セッション初期化後にAVPlayerのインスタンスが作られた時。

次のパターンではONされず、自動SessionActive化はされない。
・アプリ起動後の一度目のセッション初期化の前にインスタンスを作っただけで再生させていない場合


mixWithOthersについて
iPodの音を再生させながらゲームが出来るアプリなどはこのmixWithOthersの値を1にする。
このmixWithOthers、自分のアプリ内で自分のアプリの音と他の音を同時再生させるためのパラメータかと思ったらそれだけでは無かった。
その説明の前にバックグラウンドの説明をします。
AVAudioPlayer
AVPlayer
AVQueuePlayer
これらのような音楽を再生させるクラスを使う時、アプリがバックグラウンドになっても音の再生を続けるために、info.plist内でRequired background modesの値にApp plays audioを追加します(詳しく説明したサイトは多くあります)。
で、このバックグラウンドでも再生可能の設定にして、mixWithOthersの値を1にした場合、当然バックグランドでも音は鳴ります。
で、他のアプリを起動したときにどうなるかというと、そのアプリのセッションカテゴリーの設定がSoloAmbientであっても鳴り続けます。SoloAmbientは他のアプリの音は再生しないというカテゴリーですので、説明と違う状況になります。
今後iOSのバージョンアップで修正されるかもしれません。

mixWithOthers
バックグラウンドで再生を行う際、音声ファイルが圧縮の場合許可されないことがあります。
mixWithOthersが1の場合は許可されないことがあります。

PDFファイルより抜粋
Appleが出しているPDFファイルAudioSessionProgrammingGuideより。
セッションの状態がアクティブか非アクティブかに関係なくカテゴリを変更 できます。
デバイスのハードウェアコーデックは、アプリケーションのオーディオセッションカテゴリを、ほか のオーディオ(iPodオーディオなど)を消音するように設定する場合に限り、アプリケーションで利 用できます。
割り込み時などにオーディオセッション カテゴリが変わると、mixWithOthersプロパティの値はfalseに戻ります。ミックス動作ができるようにするに は、このプロパティを再度設定する必要があります。
カテゴリーの変化でもルートチェンジが呼ばれる。

コメント

このブログの人気の投稿

Swiftのコンパイルエラー寄せ集め

コンパイルエラー覚え書き(Objective-C)

AVAudioSession細かいことまとめ(late 2014)