美文网首页iOS DevelopmentAVaudioSessioniOS 开发
iOS基础篇-AVPLayer和AVAudioSession

iOS基础篇-AVPLayer和AVAudioSession

作者: 麦子_KB | 来源:发表于2018-02-27 16:17 被阅读116次
    • 作用
      AVPLayer:可以用来播放在线及本地音视频
      AVAudioSession:音频会话,主要用来管理音频设置与硬件交互
      使用时需要导入
    #import <AVFoundation/AVFoundation.h>
    
    • AVAudioSession中配置选项:
    AVAudioSessionCategory
    注意:除了 AVAudioSessionCategoryMultiRoute 外,其他的 Category 都遵循 last in wins 原则,即最后接入的音频设备作为输入或输出的主设备。
    1.AVAudioSessionCategoryAmbient
    当前App的播放声音可以和其他app播放的声音共存,当锁屏或按静音时停止。
    
    2.AVAudioSessionCategorySoloAmbient
    只能播放当前App的声音,其他app的声音会停止,当锁屏或按静音时停止。
    
    3.AVAudioSessionCategoryPlayback
    只能播放当前App的声音,其他app的声音会停止,当锁屏或按静音时不会停止。
    
    4.AVAudioSessionCategoryRecord
    只能用于录音,其他app的声音会停止,当锁屏或按静音时不会停止
    
    5.AVAudioSessionCategoryPlayAndRecord
    在录音的同时播放其他声音,当锁屏或按静音时不会停止
    可用于听筒播放,比如微信语音消息听筒播放
    
    6.AVAudioSessionCategoryAudioProcessing
    使用硬件解码器处理音频,该音频会话使用期间,不能播放或录音
    
    7.AVAudioSessionCategoryMultiRoute
    多种音频输入输出,例如可以耳机、USB设备同时播放等
    
    AVAudioSessionCategoryOptions
    1.AVAudioSessionModeDefault
    默认的模式,适用于所有的场景,可用于场景还原
    
    2.AVAudioSessionModeVoiceChat
    适用类别 :
    AVAudioSessionCategoryPlayAndRecord 
    应用场景VoIP
    
    3.AVAudioSessionModeGameChat
    适用类别:
    AVAudioSessionCategoryPlayAndRecord 
    应用场景游戏录制,由GKVoiceChat自动设置,无需手动调用
    
    4.AVAudioSessionModeVideoRecording
    适用类别:
    AVAudioSessionCategoryPlayAndRecord
    AVAudioSessionCategoryRecord 
    应用场景视频录制
    
    5.AVAudioSessionModeMoviePlayback
    适用类别:
    AVAudioSessionCategoryPlayBack
    应用场景视频播放
    
    6.AVAudioSessionModeVideoChat
    适用类别:
    AVAudioSessionCategoryPlayAndRecord
    应用场景视频通话
    
    7.AVAudioSessionModeMeasurement
    适用类别:
    AVAudioSessionCategoryPlayAndRecord
    AVAudioSessionCategoryRecord
    AVAudioSessionCategoryPlayback
    AVAudioSessionModeSpokenAudio
    
    AVAudioSessionMode
    
    1.AVAudioSessionCategoryOptionMixWithOthers
    适用于:
    AVAudioSessionCategoryPlayAndRecord
    AVAudioSessionCategoryPlayback
    AVAudioSessionCategoryMultiRoute 
    用于可以和其他app进行混音
    
    2.AVAudioSessionCategoryOptionDuckOthers
    适用于:
    AVAudioSessionCategoryAmbient
    AVAudioSessionCategoryPlayAndRecord
    AVAudioSessionCategoryPlayback
    AVAudioSessionCategoryMultiRoute
    用于压低其他声音播放的音量,使期音量变小
    
    3.AVAudioSessionCategoryOptionAllowBluetooth
    适用于:
    AVAudioSessionCategoryRecord and AVAudioSessionCategoryPlayAndRecord
    用于是否支持蓝牙设备耳机等
    
    4.AVAudioSessionCategoryOptionDefaultToSpeaker
    适用于:
    AVAudioSessionCategoryPlayAndRecord
    用于将声音从Speaker播放,外放,即免提
    
    5.AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
    适用于:
    AVAudioSessionCategoryPlayAndRecord
    AVAudioSessionCategoryPlayback
    AVAudioSessionCategoryMultiRoute
    
    6.AVAudioSessionCategoryOptionAllowBluetoothA2DP
    适用于:
    AVAudioSessionCategoryPlayAndRecord
    蓝牙和a2dp
    
    7.AVAudioSessionCategoryOptionAllowAirPlay
    适用于:
    AVAudioSessionCategoryPlayAndRecord
    airplay
    

    使用AVAudioSession对上下文app进行音频控制

    /**
     *  SetAVAudioSessionCategory
     */
    - (void)setAVAudioSessionCategory:(NSString *)category
                              options:(AVAudioSessionCategoryOptions)options {
        NSError *error = nil;
        BOOL success = [[AVAudioSession sharedInstance] setCategory:category withOptions:options error:&error];
        
        if (!success) {
            NSLog(@"SetCategory error:%@ ",error.description);
        }
        
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        BOOL ret = [audioSession setActive:YES error:&error];
        
        if (!ret) {
            NSLog(@"%s - activate audio session failed with error %@", __func__,[error description]);
        }
    }
    
    • 结合AVPlayer使用
    @property (strong, nonatomic) AVPlayer *avPlayer;
    
    AVPlayerItem *playerItem  = [self creatAVPlayerItemWithUrlStr:AudioUrlStr];
    self.playState = VoicePlayStateLoding;
        
    if (self.avPlayer != nil && self.avPlayer.status == AVPlayerStatusReadyToPlay) {
       [self.avPlayer replaceCurrentItemWithPlayerItem:playerItem];
    } else {
       self.avPlayer = [AVPlayer playerWithPlayerItem:playerItem];
    }
        
    [self setSessionLabType:@"SoloAmbient"];
    
    • 监听音频受其他事件(电话,闹铃,其他app占用通道)影响
    - (void)customAddNotification {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(audioRouteChangeListenerCallback:)
                                                     name:AVAudioSessionRouteChangeNotification object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(otherAppAudioSessionCallBack:)
                                                     name:AVAudioSessionSilenceSecondaryAudioHintNotification object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(systermAudioSessionCallBack:)
                                                     name:AVAudioSessionInterruptionNotification object:nil];
    }
    
    // 监听外部设备改变
    - (void)audioRouteChangeListenerCallback:(NSNotification*)notification {
        NSDictionary *interuptionDict = notification.userInfo;
        NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
        switch (routeChangeReason) {
            case AVAudioSessionRouteChangeReasonNewDeviceAvailable:{
                NSLog(@"headset input");
                break;
            }
            case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:{
                NSLog(@"pause play when headset output");
                [self.avPlayer pause];
                break;
            }
            case AVAudioSessionRouteChangeReasonCategoryChange:
                NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange");
                break;
        }
    }
    
    // 其他app占用音频通道
    - (void)otherAppAudioSessionCallBack:(NSNotification *)notification {
        NSDictionary *interuptionDict = notification.userInfo;
        NSInteger interuptType = [[interuptionDict valueForKey:AVAudioSessionSilenceSecondaryAudioHintTypeKey] integerValue];
        switch (interuptType) {
            case AVAudioSessionSilenceSecondaryAudioHintTypeBegin:{
                [self.avPlayer pause];
                NSLog(@"pause play when other app occupied session");
                break;
            }
            case AVAudioSessionSilenceSecondaryAudioHintTypeEnd:{
                NSLog(@"occupied session");
                break;
            }
            default:
                break;
        }
    }
    
    // 电话、闹铃等一般性中断通知
    - (void)systermAudioSessionCallBack:(NSNotification *)notification {
        NSDictionary *interuptionDict = notification.userInfo;
        NSInteger interuptType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
    
        switch (interuptType) { 
            case AVAudioSessionInterruptionTypeBegan:{
                [self.avPlayer pause];
                NSLog(@"pause play when phone call or alarm ");
                break;
            }
            case AVAudioSessionInterruptionTypeEnded:{
                break;
            }
            default:
                break;
        }
    }
    
    • 总结
      使用AVPAVAudioSession和AVPlayer结合可灵活实现音视频播放,可控制听筒、前后台、音频混播等多种播放控制。在使用中我们可以结合场景来切换不同的session.
      Demo地址:https://github.com/MrWilsonXu/AudioSession.git

    相关文章

      网友评论

        本文标题:iOS基础篇-AVPLayer和AVAudioSession

        本文链接:https://www.haomeiwen.com/subject/rfmpxftx.html