我想知道这是否可行 - 我的应用程序激活一个初始化为的音频会话:
[[[AVAudioSession alloc] init] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];
我希望能够理解何时播放来自其他应用程序或操作系统的其他音频会话.
我知道实现委托方法的能力beginInterruption:
,endInterruption
但由于AVAudioSessionCategoryOptionMixWithOthers
我正在使用的选项,这些方法不会被调用.
有没有办法在不使用私有API的情况下实现这一目标?
提前致谢.
自iOS 6.0以来,您管理应用程序的音频会话的方式发生了一些重大变化,值得一提.在iOS 6.0之前,您将使用AVAudioSession和AudioSessionServices类,分别包含委托和属性侦听.从iOS 6.0开始,使用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方法中删除observer.
// 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
的是有一个名为类型的用户信息属性对象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
您的根视图控制器中,在应用程序生命周期的开始时,就不需要轮询任何内容.通过这两个主要通知,可以了解从那里到应用程序音频会话的任何更改.NSLog
根据交换机中包含的案例,将语句替换为代码需要执行的操作.
你可以找到更多的信息AVAudioSessionInterruptionTypeKey
,并 AVAudioSessionRouteChangeReasonKey
在在AVAudioSession
类的参考文档.
我很抱歉答案很长,但我认为iOS中的音频会话管理相当繁琐,而Apple的音频会话编程指南在撰写本文时并未包含使用通知进行中断处理的代码示例.
您可以检查其他音频是否正在播放:
UInt32 otherAudioIsPlaying; UInt32 propertySize = sizeof (otherAudioIsPlaying); AudioSessionGetProperty (kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &otherAudioIsPlaying ); [self handleIfAudioIsPlaying: otherAudioIsPlaying];
然后你可以添加一个循环并检查每一个X秒是否有变化.