10

さて、AVAudioSession を次のように定義しました (はい、c 呼び出しと obj-c 呼び出しの組み合わせです) また、アプリにはバックグラウンド モードのオーディオがあることに注意してください。

[(AVAudioSession *)[AVAudioSession sharedInstance] setDelegate: self];
// Allow the app sound to continue to play when the screen is locked.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
//Turn off automatic gain on the microphone
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeMeasurement error:nil];
//Turn on the ability to mix with others
UInt32 doSetProperty = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty);

//Activate the audio session
[[AVAudioSession sharedInstance] setActive:YES error:nil];

アプリには、オーディオ用にいくつかの異なるオプションがあります (最初の 2 つだけがプログラムされています)。

  • 通常: アプリからの音声がないため、外部の音声をいじらないでください
  • ヘッドセット マイクの録音のみ: ゲイン調整を行ってはならず、外部オーディオ (ヘッドセットを介して再生される) を台無しにしないでください。
  • 録音せずにアプリから音楽を再生する: 外部オーディオを停止し、現在の出力 (スピーカーまたはヘッドセット) から再生します。
  • アプリから音楽を再生し、ヘッドセット マイクを録音する: 外部オーディオを停止し、ヘッドセット経由でのみ録音および再生します。

録音はフォアグラウンドとバックグラウンドでうまく機能しており、後で再生を追加します. しかし、今夜、ラウド スピーカーでオーディオが既に再生されている (Pandora) 場合に、アプリに移動して録音モードを有効にすると、Pandora が電話のスピーカーから再生されるように切り替わり、オーディオ セッションが無効になっていて、アプリはバックグラウンド化されています (ただし、強制的に閉じられるわけではありません)。アプリを強制的に閉じるまで、オーディオは電話のスピーカーから再生され続けます。

//Deactivate the audio session
[[AVAudioSession sharedInstance] setActive:NO error:nil];

反対に、ヘッドセットが装着されていて、アプリが録音モードで開始されたときにヘッドセットから音楽が再生されている場合、短い一時停止だけがあり、音楽は同じ音量で再生され続けます (正確には、ダッキングはありません)。 .

ヘッドセットを使用せずにオーディオ セッションをアクティブにしたときにルートが変更される理由と、セッションが非アクティブになったときに元に戻らない理由がわかりません。特にフォーンスピーカーに変更!私が間違っていることがありますか、それともユーザーが何をしたいのかに応じて AVAudioSession を別の方法で定義する必要がありますか? また、ユースケースごとに個別に定義する必要がある場合でも。たとえば、アプリが録音している場合、オーディオは常にヘッドセットを通過し、アプリが録音していない場合、オーディオはヘッドセットまたはラウドスピーカーのいずれかを出力します (ユーザーがヘッドセットを接続しているかどうかに応じて) - つまり、正常な動作)。

追加の詳細

さて、すべてのコード c を切り替えてみたところ、ドキュメント内に kAudioSessionProperty_OverrideAudioRoute に関するメモが埋め込まれていることに気付きました

kAudioSessionOverrideAudioRoute_None
kAudioSessionCategory_PlayAndRecord カテゴリに対して、出力オーディオがレシーバーに送信されるように指定します。これは、このカテゴリのデフォルトの出力オーディオ ルートです。

そこで、このプロパティ (これらのプロパティ) を 3 つの異なる方法で設定してみました。

  • kAudioSessionOverrideAudioRoute_Speaker を使用した kAudioSessionProperty_OverrideAudioRoute はオーディオの再生を続けますが、レシーバーを介して切り替え、ルートを ReceiverAndMicrophone として表示します。
  • kAudioSessionProperty_OverrideCategoryDe​​faultToSpeaker と kAudioSessionOverrideAudioRoute_Speaker は、現在再生中のオーディオを停止し、ルートを SpeakerAndMicrophone として表示します
  • 値が 1 の kAudioSessionProperty_OverrideCategoryDe​​faultToSpeaker は、kAudioSessionOverrideAudioRoute_Speaker と同じことを行います

したがって、基本的にドキュメントには、デフォルトはレシーバーに切り替えることであると書かれています。しかし、私が何をしても、スピーカー出力を維持して外部オーディオを再生し続けることはできないようです。

4

1 に答える 1

9

ドキュメントにはこれについての言及はありませんが、プロパティを設定する順序は明らかに重要です。最終的にこれを見つけた人のために、これが機能します:

//Init and set the interrupt listener.  last parameter is passed to interruptlistener
AudioSessionInitialize(NULL, NULL, interruptlistener, NULL);

//Allow the app sound to continue to play when the screen is locked.
UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);

//Force current audio out through speaker
UInt32 routeSpeaker = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(routeSpeaker), &routeSpeaker);

//Turn on the ability to mix with others
UInt32 doSetProperty = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty);
于 2013-03-13T18:56:14.073 に答える