目前公司主要做Voip方面的应用,作为iOS开发者,当然需要对AVFoundation有个全面的了解。接下来将开启一个系列,记录学习AVFoundation的过程。

这篇主要说一下AVFoundation中经常用到的音频播放类AVAudioPlayer,官方对它的介绍是这样的:

可以在任意的时间播放音频
可以播放文件系统中或内存中的音频
可循环播放
可使用多个实例同时播放
支持快进、快退、定点播放、加速播放、减速播放等

可以看到,AVAudioPlayer主要用在播放本地音频。如果想播放网络音频,则需要使用其他类了。另外协议类AVAudioPlayerDelegate主要用作AVAudioPlayer的各种事件回调。

AVAudioPlayer支持常用的音频编码,如AACPCMAPCMU等。音频类型如下:

AVAudioPlayer


API


Init

初始化一个AVAudioPlayer的方式有如下四种:

- (instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError * _Nullable *)outError;
- (instancetype)initWithData:(NSData *)data error:(NSError * _Nullable *)outError;
- (instancetype)initWithContentsOfURL:(NSURL *)url fileTypeHint:(NSString *)utiString error:(NSError * _Nullable *)outError;
- (instancetype)initWithData:(NSData *)data fileTypeHint:(NSString *)utiString error:(NSError * _Nullable *)outError;

AVAudioPlayer有4种初始化方式,即可以通过文件路径(NSURL)来初始化也可以通过音视频数据(NSData)来初始化。另外也可以指定音频文件的UTI类型。通常可以指定为public.audio,关于UTI请点这里

prepareToPlay

- (BOOL)prepareToPlay

调用此方法可将音频数据提前加载到缓冲区。

play

- (BOOL)play

调用此方法即可异步开始播放音频

playAtTime

- (BOOL)playAtTime:(NSTimeInterval)time

在某一时刻开始播放音频,可设置成当前时间之后的多少秒。例如设置5秒之后开始播放:

NSTimeInterval delay = 5;
[self.audioPlayer playAtTime:self.audioPlayer.deviceCurrentTime+delay];

pause

- (void)pause

暂停播放

stop

- (void)stop

stoppause最大的区别是stop会撤销prepareToPlay所做的准备。

setVolume:fadeDuration:

- (void)setVolume:(float)volume fadeDuration:(NSTimeInterval)duration

设置音频在duration时间之后的播放声音大小,volume的范围为0-1

averagePowerForChannel

- (float)averagePowerForChannel:(NSUInteger)channelNumber

获取通道内的平均分贝值,取值范围为0Db(最大分贝)到-160Db(最小分贝),调用此方法之前,需先调用updateMeters方法更新分贝。

peakPowerForChannel

- (float)peakPowerForChannel:(NSUInteger)channelNumber

获取通道内的最大分贝值,取值范围为0Db(最大分贝)到-160Db(最小分贝),调用此方法之前,需先调用updateMeters方法更新分贝。

updateMeters

- (void)updateMeters

更新所有通道内的分贝值。


Property


playing

获取当前播放状态

volume

获取当前播放的音量大小,范围为0-1,建议使用MPVolumeView来自定义音量界面。

pan

设置哪个扬声器播放。例如:-1。0表示只使用左扬声器播放,1.0表示只使用右扬声器播放,0.0表示同时使用左右两个扬声器播放。

rate

设置播放速度,取值范围是0.5-2.0。默认为1.0,表示正常的播放速度。0.5表示半速。2表示两倍。但在使用此属性之前,必须先调用enableRate启用播放速度功能。

enableRate

开启播放速度,最好在prepareToPlay方法之后设置。

numberOfLoops

设置循环播放的次数。确切的来说,此变量表示在播放结束之后,还需要再播放几次。例如设置为1,表示在播放结束之后,在播放一次,所有,你能听到两次播放。 如果设置为负数,表示一直循环播放。直到调用stop方法停掉。

delegate

AVAudioPlayer代理

settings

获取音频参数。例如比特率、通道数等。settings的类型为NSDictionary<NSString *,id>keys如下:

  • 通道:AVChannelLayoutKey
  • 比特率:AVEncoderBitRateKey
  • 编码类型:AVFormatIDKey
  • 通道数:AVNumberOfChannelsKey
  • 采样率:AVSampleRateKey

numberOfChannels

通道数,效果和AVNumberOfChannelsKey一样。

channelAssignments

一般情况下为nil,如果不是空的话,那么此数组的长度和numberOfChannels的值一样,每个AVAudioSessionChannelDescription代表每个通道的详细参数。

duration

音频的长度

currentTime

当前音频播放到哪里,时间点。通过设置currentTime可实现快退,快进等功能。例如:

//快进
- (IBAction)fastForward:(id)sender {
NSTimeInterval shortTime = 1;
NSTimeInterval now = self.audioPlayer.currentTime + shortTime;
[self.audioPlayer setCurrentTime:now];
}

deviceCurrentTime

输出设备的当前时间,主要搭配playAtTime使用。

url

音频文件URL

data

音频文件数据

format

获取当前缓存的音频格式

meteringEnabled

如果想获取音频的分贝值,要开启此设置。例如我们想实时获取当前播放的分贝值。来绘制图形界面:

- (IBAction)startDbTimer:(id)sender {
[self.audioPlayer setMeteringEnabled:YES];
__weak typeof (self)weakSelf = self;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
[weakSelf.audioPlayer updateMeters];
float averageDB = [weakSelf.audioPlayer averagePowerForChannel:0];
float peakDb = [weakSelf.audioPlayer peakPowerForChannel:0];
//绘制波形图
}];
}

AVAudioPlayerDelegate

AVAudioPlayerDelegate的方法很少。目前能用的只有两个。

audioPlayerDidFinishPlaying:successfully:

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag

当音频播放完毕以后,会回调此方法

audioPlayerDecodeErrorDidOccur:error:

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error

播放出错回调