私はこれが可能かどうかを把握しようとしています-私のアプリは次のように初期化されたオーディオセッションをアクティブにします:
[[[AVAudioSession alloc] init] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];
別のアプリまたはOSから発生した追加のオーディオセッションがいつ再生されるかを理解したいと思います。
デリゲートメソッドを実装する機能について知っていますbeginInterruption:
とendInterruption
が、使用しているAVAudioSessionCategoryOptionMixWithOthers
オプションのため、これらは呼び出されません。
プライベートAPIを使用せずにこれを達成する方法はありますか?
前もって感謝します。
iOS 6.以降、アプリケーションのオーディオセッションを管理する方法にいくつかの重要な変更が加えられ、最初に簡単に言及する価値があります。 iOS 6.の前に、AVAudioSessionおよびAudioSessionServicesクラスを使用し、それぞれ委任とプロパティリスニングを組み込みます。 iOS 6.以降はAVAudioSessionクラスを使用し、通知を組み込みます。
以下はiOS 6.0以降のものです。
アプリケーションサンドボックスの外部の他のオーディオが使用されているかどうかを確認するには-
// query if other audio is playing
BOOL isPlayingWithOthers = [[AVAudioSession sharedInstance] isOtherAudioPlaying];
// test it with...
(isPlayingWithOthers) ? NSLog(@"other audio is playing") : NSLog(@"no other audio is playing");
割り込み処理については、AVAudioSessionInterruptionNotification
およびAVAudioSessionRouteChangeNotification
を監視する必要があります。そのため、オーディオセッションを管理するクラスでは、次のようなものを配置できます。これは、アプリケーションライフサイクルの開始時に一度呼び出し、同じクラスのdeallocメソッドでオブザーバーを削除することを忘れないでください。
// ensure we already have a singleton object
[AVAudioSession sharedInstance];
// register for notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(interruption:)
name:AVAudioSessionInterruptionNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(routeChange:)
name:AVAudioSessionRouteChangeNotification
object:nil];
最後に、次のセレクターを追加しますinterruption:
およびrouteChange:
-これらはNSNotification
型のuserInfoと呼ばれるプロパティを持つNSDictionary
オブジェクトを受け取ります。このオブジェクトは、アプリケーションの条件を支援するために読み取ります。
- (void)interruption:(NSNotification*)notification {
// get the user info dictionary
NSDictionary *interuptionDict = notification.userInfo;
// get the AVAudioSessionInterruptionTypeKey enum from the dictionary
NSInteger interuptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
// decide what to do based on interruption type here...
switch (interuptionType) {
case AVAudioSessionInterruptionTypeBegan:
NSLog(@"Audio Session Interruption case started.");
// fork to handling method here...
// EG:[self handleInterruptionStarted];
break;
case AVAudioSessionInterruptionTypeEnded:
NSLog(@"Audio Session Interruption case ended.");
// fork to handling method here...
// EG:[self handleInterruptionEnded];
break;
default:
NSLog(@"Audio Session Interruption Notification case default.");
break;
} }
そして同様に...
- (void)routeChange:(NSNotification*)notification {
NSDictionary *interuptionDict = notification.userInfo;
NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
switch (routeChangeReason) {
case AVAudioSessionRouteChangeReasonUnknown:
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonUnknown");
break;
case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
// a headset was added or removed
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonNewDeviceAvailable");
break;
case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
// a headset was added or removed
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
break;
case AVAudioSessionRouteChangeReasonCategoryChange:
// called at start - also when other audio wants to play
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonCategoryChange");//AVAudioSessionRouteChangeReasonCategoryChange
break;
case AVAudioSessionRouteChangeReasonOverride:
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonOverride");
break;
case AVAudioSessionRouteChangeReasonWakeFromSleep:
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonWakeFromSleep");
break;
case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory:
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory");
break;
default:
break;
} }
アプリのライフサイクルの開始時に、たとえばルートビューコントローラーのviewDidLoad
でアプリケーションのオーディオセッションの状態を確認する限り、何もポーリングする必要はありません。アプリケーションのオーディオセッションに対する以降の変更は、これら2つの主要な通知によって通知されます。 NSLog
ステートメントを、スイッチに含まれるケースに基づいてコードが実行する必要があるものに置き換えます。
AVAudioSessionInterruptionTypeKey
およびAVAudioSessionRouteChangeReasonKey
の詳細については、AVAudioSession
クラスリファレンスドキュメントを参照してください。
長い答えをおaびしますが、iOSでのオーディオセッション管理はかなり面倒だと思います。これを書いている時点で、Appleのオーディオセッションプログラミングガイドには、割り込み処理の通知を使用したコード例は含まれていません。
他のオーディオが次のように再生されているかどうかを確認できます。
UInt32 otherAudioIsPlaying;
UInt32 propertySize = sizeof (otherAudioIsPlaying);
AudioSessionGetProperty (kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &otherAudioIsPlaying );
[self handleIfAudioIsPlaying: otherAudioIsPlaying];
その後、ループを追加して、何か変更があった場合はX秒ごとに確認できます。