Sta*_*ash 26 cocoa-touch objective-c ios avaudiosession
我想知道这是否可行 - 我的应用程序激活一个初始化为的音频会话:
[[[AVAudioSession alloc] init] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];
Run Code Online (Sandbox Code Playgroud)
我希望能够理解何时播放来自其他应用程序或操作系统的其他音频会话.
我知道实现委托方法的能力beginInterruption:,endInterruption但由于AVAudioSessionCategoryOptionMixWithOthers我正在使用的选项,这些方法不会被调用.
有没有办法在不使用私有API的情况下实现这一目标?
提前致谢.
Bam*_*rld 68
自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");
Run Code Online (Sandbox Code Playgroud)
至于中断处理,你需要观察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];
Run Code Online (Sandbox Code Playgroud)
最后添加下面的选择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;
} }
Run Code Online (Sandbox Code Playgroud)
同样......
- (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;
} }
Run Code Online (Sandbox Code Playgroud)
只要您检查应用程序音频会话的状态,例如在viewDidLoad您的根视图控制器中,在应用程序生命周期的开始时,就不需要轮询任何内容.通过这两个主要通知,可以了解从那里到应用程序音频会话的任何更改.NSLog根据交换机中包含的案例,将语句替换为代码需要执行的操作.
你可以找到更多的信息AVAudioSessionInterruptionTypeKey,并 AVAudioSessionRouteChangeReasonKey在在AVAudioSession类的参考文档.
我很抱歉答案很长,但我认为iOS中的音频会话管理相当繁琐,而Apple的音频会话编程指南在撰写本文时并未包含使用通知进行中断处理的代码示例.
您可以检查其他音频是否正在播放:
UInt32 otherAudioIsPlaying;
UInt32 propertySize = sizeof (otherAudioIsPlaying);
AudioSessionGetProperty (kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &otherAudioIsPlaying );
[self handleIfAudioIsPlaying: otherAudioIsPlaying];
Run Code Online (Sandbox Code Playgroud)
然后你可以添加一个循环并检查每一个X秒是否有变化.