ニート・アンド・カンパニー

WEBサービスやプログラミングについて勉強中。

Objective-C AudioSessionまとめ

Appleの公式ドキュメントが読みづらかったので、
自分なりにまとめながら読んでみた。

2つのAudioSession

AVAudioSessionクラス (Objective-c、ハイレベル)

基本的にはこのクラスを使う。こちらの方が簡単。

// 使い方
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];

Audio Session Services (C、ローレベル)

もっと複雑な設定にしたかったらこっち。 オーディオセッションの基本機能と高度な機能のすべてにアクセスできる、完全機能を備えたCのAPI

// 使い方
// オーディオセッションに適用しようとするカテゴリの識別子を渡して初期化。
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound; // 1

AudioSessionSetProperty (
    // オーディオセッションプロパティのキー。設定するプロパティ値のデータサイズ(バイト単位)
    kAudioSessionProperty_AudioCategory,  
    // オーディオセッションのカテゴリに適用したいオーディオ経路オーバーライドの値
    sizeof (sessionCategory), // 3
    // オーディオセッションに設定したいカテゴリ
    &sessionCategory // 4
);

アプリケーション起動時に自動で初期化されるが、、、

アプリケーションの起動時にオーディオセッションは
自動的にアクティブ(カテゴリ名 : AVAudioSessionCategorySoloAmbient)になる。
しかし、AppleはviewDidLoadメソッドの中で
明示的にアクティブにすることを推奨している。

他のアプリケーションからの割り込みを処理する

割り込まれたとき

別のアプリケーション(時計、カレンダーのアラーム、電話の着信など)を受けると、
自アプリのオーディオセッションを非アクティブになる。
その時の処理は

- (void)beginInterruption

内に実装する。

割り込みが終わったとき

ユーザがアラームを消したり電話に出なかった場合、 アプリケーションのオーディオセッションは再びアクティブになる。
割り込みが終了したら、

- (void)endInterruption

が呼ばれるので、ここに処理を書く。

AVAudioRecorderクラスとAVAudioPlaybackクラスは、独自の割込み処理デリゲートメソッドを持っている

// 再生中にオーディオセッションに対して割り込みが発生したとき
-(void)audioPlayerBeginInterruption:

// 再生に対する割り込みが終了したとき
-(void)audioPlayerEndInterruption:

// 録音中にオーディオセッションに対する割り込みが発生
-(void)audioRecorderBeginInterruption:

// 録音に対する割り込みが終了したとき
-(void)audioRecorderEndInterruption:

AudioSessionカテゴリ

AVAudioSessionCategorySoloAmbient

  • 再生 : 有効 / 録音 : 無効
  • ユーザがサイレントスイッチを「サイレント」位置に切り替えると、アプリケーションのオーディオは鳴らなくなる
  • 画面をロックされると、アプリケーションのオーディオは鳴らなくなる
  • アプリケーションのオーディオが鳴り始めると、そのデバイスで出力されているほかのオーディオ(すでに再生中のiPodオーディオなど)は鳴らなくなる

AVAudioSessionCategoryPlayback

  • 画面がロックされても再生を続行する場合に使う

TIPS

他のアプリケーションがオーディオを再生中かチェックする

UInt32 otherAudioIsPlaying;
UInt32 propertySize = sizeof (otherAudioIsPlaying);

AudioSessionGetProperty ( // 2
    kAudioSessionProperty_OtherAudioIsPlaying,
    &propertySize,
    &otherAudioIsPlaying
);

// * 使用例 *
// ほかのオーディオが再生中の場合は、AVAudioSessionCategoryAmbient カテゴリを割り当て。
// そうでなければAVAudioSessionCategorySoloAmbient カテゴリを割り当てる。

if (otherAudioIsPlaying) {
    [[AVAudioSession sharedInstance]
    setCategory: AVAudioSessionCategoryAmbient
    error: nil];
} else {
    [[AVAudioSession sharedInstance]
    setCategory: AVAudioSessionCategorySoloAmbient
    error: nil];
}

再生のミックスをサポートする

OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty (
     kAudioSessionProperty_OverrideCategoryMixWithOthers, // 1
     sizeof (allowMixing), // 2
     &allowMixing // 3
);

ヘッドフォンが接続中かどうか調べる (iOS6以降)

AVAudioSession *session = [AVAudioSession sharedInstance];
NSArray *out = session.currentRoute.outputs;
AVAudioSessionPortDescription *portDescription = [out lastObject];
if ([portDescription.portType isEqualToString:@"Headphones"])
{
    return YES;
}else{
    return NO;
}

実機検証がオススメ

シミュレータではオーディオセッション動 作はシミュレートできず、デバイスのハードウェア機能にアクセスできない