在iOS设备上检测活动的AVAudioSessions

 手机用户2502879747 发布于 2023-02-12 23:18

我想知道这是否可行 - 我的应用程序激活一个初始化为的音频会话:

[[[AVAudioSession alloc] init] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];

我希望能够理解何时播放来自其他应用程序或操作系统的其他音频会话.

我知道实现委托方法的能力beginInterruption:,endInterruption但由于AVAudioSessionCategoryOptionMixWithOthers我正在使用的选项,这些方法不会被调用.

有没有办法在不使用私有API的情况下实现这一目标?

提前致谢.

2 个回答
  • iOS 6.0以来,您管理应用程序的音频会话的方式发生了一些重大变化,值得一提.在iOS 6.0之前,您将使用AVAudioSessionAudioSessionServices类,分别包含委托和属性侦听.从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");
    

    至于中断处理,你需要观察AVAudioSessionInterruptionNotificationAVAudioSessionRouteChangeNotification.因此,在管理音频会话的类中,您可以添加如下内容 - 这应该在应用程序生命周期的开始时调用一次,并且不要忘记在同一个类的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的音频会话编程指南在撰写本文时并未包含使用通知进行中断处理的代码示例.

    2023-02-12 23:31 回答
  • 您可以检查其他音频是否正在播放:

    UInt32 otherAudioIsPlaying;
    UInt32 propertySize = sizeof (otherAudioIsPlaying);
    AudioSessionGetProperty (kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &otherAudioIsPlaying );
    
    [self handleIfAudioIsPlaying: otherAudioIsPlaying];
    

    然后你可以添加一个循环并检查每一个X秒是否有变化.

    2023-02-12 23:31 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有