AVAudioPlayer学习

AVAudioPlayer 使用方式

音频播放是很多应用程序的常见需求,AVFoundation让这一功能变得非常简单,这一点得归功于AVAudioPlayer这个类。这个类的实例提供了一种简单地从广西或内存中播放音频的方法。虽接口简单,但功能强大 并且在mac和iOS系统中经常被作为实现音频播放的最佳选择
AVAudioPlayer 构建于CoreAudio中的C-based Audio Queue Services的最顶层,所以它可以提供你在AVAudio Queue Services 中所能找到的核心功能,比如播放、循环甚至音频计量,但其也有不足之处如:需要从网络流中播入音频、需要访问原始音频样本或者更低的延时时它不能胜任些重任。

创建实例对象的方式方法

  1. 使用包含要播放音频的内存版本的NSData initWithData:error:
  2. 使用本地音频文件的NSURLinitWithContentsOfURL:error:
    在用上述方法返回一个有效实例时,建议调用prepareToPlay方法。如此一来会取得需要的音频硬件并预加载Audio Queue的缓冲区

对播放实例的控制操作

  1. 基础功能:playpausestop
  2. 修改实例的音量:volume 范围值0.0~1.0之间的浮点值
  3. 修改实例的pan值,允许使用立体声:pan值 范围:-1.0~1.0之间的浮点值
  4. 调整播放速率:rate 范围值:0.5(半速)~2.0(2倍速)
  5. 设置循环次数属性实现无缝循环:numberOfLoops设置一个大于0的数n,可以循环n次,相反若设成-1,会无限次循环
  6. 进行音频计量

配置音频会话

  1. 播放音频时切换设备侧面的“铃音/静音”按钮,可以音频在这两种状态下输出
  2. 播放音频时按下LOCK锁,进入后台,音频可以正常输出

要实现上面两个需要,我们需要做如下工作:

  • didFinishLaunchingWithOptions方法里配置AVAudioSession,
    正确设置音频会话分类为AVAudioSessionCategoryPlayback 并启动会话
AVAudioSession * session  = [AVAudioSession sharedInstance];
    NSError * error;
    if (![session setCategory:AVAudioSessionCategoryPlayback error:& error]) {
        NSLog(@"%@",error.localizedDescription);
    }
    if (![session setActive:YES error:&error]) {
        NSLog(@"%@",error.localizedDescription);
    }
  • info.plist文件中添加键值,该值表示应用程序允许在后台播放音频内容
<key>UIBackgroundModes</key>
    <array>
        <string>audio</string>
    </array>

音频会话中断通知处理

测试你的应用程序是否做了会话中断处理:

  1. 在真机上运行你的应用并播放音频
  2. 当音频处于播放状态,从另一台设备上向当前设备发起电话或FaceTime以造成音频会话中断
  3. 中断电话发起或FaceTime
    当中断时,播放的音频会慢慢消失和暂停,这一效果系统自动实现,当中断恢复后,查看我的的应用音频是否还会自动继续播放呢
    如果没有,我们需要注册AVAudioSessionInterruptionNotification通知,并处理该通知

注册监听

//        监听中断通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption: ) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];

处理中断通知:

-(void)handleInterruption:(NSNotification*)notification{

//    首先通过检索AVAudioSessionInterruptionTypeKey来确定中类型(AVAudioSessionInterruptionType),该类型用于表中断的开始或是结束
    NSDictionary * userinfo  = notification.userInfo;
    AVAudioSessionInterruptionType type = [userinfo[AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
    if (type== AVAudioSessionInterruptionTypeBegan) {
    //中断音频播放
    }else {
        AVAudioSessionInterruptionOptions options =[userinfo[AVAudioSessionInterruptionOptionKey] unsignedIntegerValue];
        if (options == AVAudioSessionInterruptionOptionShouldResume) {
      //在这里继续播放音频   
        }
    }
}

线路改变通知处理

如何确保应用程序对线路变换做出正确的响应。在iOS设备上添加或移除音频输入或输出线路时,会发现线路改变。有多重因会导致线路变化,如用户插入耳机或断开USB麦克风,这些事件的发生时,音频会根据情况改变输入输出线路,同时会广播一个描述该变化的通知给所有相关的监听器。
我们做这么一个小测试:运行你的应用,并播放音频,在播放期间插入耳机,音频输出线路变为耳机插孔并继续正常播放,这是我们希望的效果。断开耳机连接。音频线路再次回到设备的内置扬声器,我们再次听到了声音。虽然这和我们预期的效果一样,不过按苹果公司的相关文档,该音频应处理静音状态。当用插入耳机时隐含的意思是用户不希望外界听到具体的音频内容,这就意味着用户断开耳机,播放的内容需要继续保密,所有我们需要停止音频播放。

监听线路改变通知

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleRouteChange:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];

处理通知:

-(void)handleRouteChange:(NSNotification*)notification{
//    通过AVAudioSessionRouteChangeReasonKey来确认发现改变的原因
//    我们在这里需要注意的是耳机中断事件
    NSDictionary * userinfo =notification.userInfo;
    AVAudioSessionRouteChangeReason reason = [userinfo[AVAudioSessionRouteChangeReasonKey] unsignedIntegerValue];
    if (reason ==AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
//        知道有设备断开连接后,需要向userinfo字典提出请求,获取其中用于描述前一线路的AVAudioSessionRouteDescription。线路的描述信息整合在一个输入NSArray和一个输出NSArray中,数组中的实例都是AVAudioSessionPortDescription,用于描术不同的I/O接口属性。
        AVAudioSessionRouteDescription * previousRoute  = userinfo[AVAudioSessionRouteChangePreviousRouteKey];
        AVAudioSessionPortDescription * previousPort  = previousRoute.outputs[0];
        NSString * type =  previousPort.portType;
        if ([type isEqualToString:AVAudioSessionPortHeadphones]) {
      //   如果需要日更新界面,需要使用主线去更新,当前线程可以是后台线程
                dispatch_async(dispatch_get_main_queue(), ^{

                });

            }
        }

    }
}

   转载规则


《AVAudioPlayer学习》 志鹏 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
ScrollViewDelegate学习 ScrollViewDelegate学习
用户拖动界面时所触发的代理方法调用有如下: 当用户将手指放在界面中并开始拖动一定距离时会调用scrollViewWillBeginDragging: 随之会触发scrollViewDidScroll方法的调用 当用户手指离开界面时会触发s
2016-04-19 志鹏
下一篇 
CoreWlan框架学习解析 CoreWlan框架学习解析
CoreWlan 框架解析CoreWlan框基础类 CWWiFiClient CWInterface CWNetwork CWNetworkProfile与CWMutableNetworkProfile CWConfiguration与CW
2016-04-13 志鹏
  目录