AVAudioSession

官方API文档是这样对AVAudioSession描述的:

audiosession负责调节你的app和iOS系统里的音频行为.一旦加载了audiosession你可以获得一个audiosession的单例.你可以配置这个audiosession来控制你的app的音频行为.例如:

当你的app播放声音的时候,你是希望其他正在播放声音的app静音还是混合两个app的声音?
你的app如何回应突发的打断,例如这时候闹铃突然响了?
你的app又该如何回应耳机口的拔插呢?

AuioSession的配置会影响你的app在运行中所有的音频活动,除了利用System Sounds Services API控制的音频.
你还可以利用AudioSession来检测你所用硬件的参数,例如声道和采样率.
你还可以随时激活或者停止你的audioSession,当你的app播放声音或者正在录音的时候,你必须确保AudioSession处于激活状态.
系统也有权利随时中断你的audioSession,例如,当你来电话的时候.当然,AudioSession提供了api来让你的app从这种中断中恢复.
一、

AVAudioSessionCategoryAmbient,//用于播放。随静音键和屏幕关闭而静音。不终止其它应用播放声音

AVAudioSessionCategorySoloAmbient,//用于播放。随静音键和屏幕关闭而静音。终止其它应用播放声音

AVAudioSessionCategoryPlayback,//用于播放。不随静音键和屏幕关闭而静音。终止其它应用播放声音,需要在工程里设置targets->capabilities->选择backgrounds modes->勾选audio,airplay,and picture in picture

AVAudioSessionCategoryPlayAndRecord,//用于播放和录音。不随着静音键和屏幕关闭而静音。终止其他应用播放声音

AVAudioSessionCategoryMultiRoute//用于播放和录音。不随着静音键和屏幕关闭而静音。可多设备输出

 

 

AVAudioSession类由AVFoundation框架引入。每个IOS应用都有一个音频会话。这个会话可以被AVAudioSession类的sharedInstance类方法访问,如下:
AVAudioSession*audioSession = [AVAudioSession sharedInstance];

在获得一个AVAudioSession类的实例后,你就能通过调用音频会话对象的setCategory:error:实例方法,来从IOS应用可用的不同类别中作出选择。下面列出了可供使用的音频会话类别:


AVAudioSessionCategoryAmbient:
用于非以语音为主的应用,随着静音键和屏幕关闭而静音。不中止其它应用播放声音,可以和其它自带应用如iPod,safari等同时播放声音。锁屏时,应用将停止所有正在回放的音频。如果正当iPod播放一手歌时,你开始播放音频,将设备设为静音模式并不能停止你的音频回放。

AVAudioSessionCategorySoloAmbient(默认类别)
这个类别非常像AVAudioSessionCategoryAmbient类别,除了会停止其他程序的音频回放,比如iPod程序。当设备被设置为静音模式,你的音频回放将会停止。

AVAudioSessionCategoryPlayback
会静止其他应用的音频回放(比如iPod应用的音频回放)。你可以使用AVAudioPlayer的prepareToPlay和play方法,在你的应用中播放声音。屏幕被锁定或者设备为静音模式,音频会放都会继续。

AVAudioSessionCategoryRecord
这会停止其他应用的声音(比如iPod)并让你的应用也不能初始化音频回放(比如AVAudioPlayer)。在这种模式下,你只能进行录音。使用这个类别,调用AVAudioPlayer的prepareToPlay会返回YES,但是调用play方法将返回NO。主UI界面会照常工作。这时,即使你的设备屏幕被用户锁定了,应用的录音仍会继续。

AVAudioSessionCategoryPlayAndRecord
这个类别允许你的应用中同时进行声音的播放和录制。当你的声音录制或播放开始后,其他应用的声音播放将会停止。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放和录制都会继续。

AVAudioSessionCategoryAudioProcessing
这个类别用于应用中进行音频处理的情形,而不是音频回放或录制。设置了这种模式,你在应用中就不能播放和录制任何声音。调用AVAPlayer的prepareToPlay和play方法都将返回NO。其他应用的音频回放,比如iPod,也会在此模式下停止。

//判断如果其他应用有正在播放的音频 恢复播放。
[[AVAudioSession sharedInstance] setActive:NO
                                 withFlags:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation

                                     error:nil];

 

 

 

情况一:用户按home键主动退到后台,一般的音乐类播放软件都会有后台播放的设置,不用进行额外的操作,但是如果是正在播放视频的话,退到后台后视频应该是暂停状态,这时我们只需要在AppDelegate的相关方法中进行主动的设置就可以

//程序即将进入后台
- (void)applicationWillResignActive:(UIApplication *)application {
    //这里可以用通知中心的方式,通知视频播放的界面将UI更新为暂停的状态(视频会自动暂停)
    [[NSNotificationCenter defaultCenter] postNotificationName:BackgroundOperation object:@"willResignActive"];
}

//程序即将进入活跃状态
- (void)applicationDidBecomeActive:(UIApplication *)application {
    //此时程序已经回到前台,如果需要的话可以让视频继续播放,让UI切换到播放的状态,如果不需要可以什么都不做
    [[NSNotificationCenter defaultCenter] postNotificationName:BackgroundOperation object:@"didBecomeActive"];

}

情况二:被电话或者其他App播放的声音打断,此时就需要我们在程序中去监听这些事件,当事件被触发时进行相应的操作

 //监测被中断的事件
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(isPlayerPlaying:) name:AVAudioSessionInterruptionNotification object:nil];

其中AVAudioSessionInterruptionNotification就是系统提供的被中断的通知

然后在被打断时进行相应的操作

//检测歌曲被打断事件(别的软件播放音乐,来电话)
- (void)isPlayerPlaying:(NSNotification *)notification {
    NSInteger type = [[notification.userInfo valueForKey:@"AVAudioSessionInterruptionTypeKey"] integerValue];
    if (type == 1) {
       //在这里进行你想要的操作
    }
}

音乐类软件为了提高用户体验一般都会添加耳机线控音乐的功能(单机暂停/播放,双击下一曲,点击三下上一曲),还可以对耳机的插拔进行监听

监听耳机的插拔:

//监听耳机的插拔
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(routeChange:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];

//相应的事件
- (void)routeChange:(NSNotification *)notification {
    NSDictionary *interuptionDict = notification.userInfo;
    NSInteger roteChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];

    switch (roteChangeReason) {
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
            //插入耳机
            break;

        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            //拔出耳机
            NSLog(@"拔出耳机");
            [self pausePlay];

            break;

    }

}

//上面的roteChangeReason还有其他的集中类型,代表了其他的状态,可以对应的进行不同的操作

点击耳机中键的事件:

首先要在程序入口处让app接收远程控制事件

//让app支持接收远程控制事件
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];

然后在远程事件通知中进行相应的操作(这个通知还会接收系统上拉菜单中的控制中心的播放和暂停按钮)

//app接受远程控制(控制中心 耳机等)
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {

    if (event.type == UIEventTypeRemoteControl) {
        switch (event.subtype) {
            case 100:
                //控制中心的播放按钮
                [[PlayingManager defaultManager] musicPlay];
                break;
            case 101:
                //控制中心的暂停按钮
                [[PlayingManager defaultManager] pausePlay];
                break;
            case 103:{
                //耳机的单击事件 根据音乐的播放状态选择暂停或播放
                if ([[PlayingManager defaultManager] getStateOfPlayer]) {
                    [[PlayingManager defaultManager] pausePlay];
                } else {
                    [[PlayingManager defaultManager] musicPlay];
                }

            }
                break;
            case 104:
                //耳机的双击中键事件 
                [[PlayingManager defaultManager] nextMusic];
                break;
             case 105:
                //耳机的中键盘点击三下触发的时间
                [[PlayingManager defaultManager] beforeMusic];
                break;

            default:
                break;
        }
    }

}


 

 

 

 

-- NORMAL --

你可能感兴趣的:(iOS)