本文以婚语APP为例,来讲解集体使用方法。
在婚语APP中,分别使用了AVAudioPlayer,AVPlayer,AVQueuePlayer来实现音频播放功能,下面以婚语的实际需求分别介绍它们的使用方法和区别。
需求1
档期备忘:用户新建档期记录时,可以进行录音备忘,录音完成后可直接播放,保存档期时将录音文件上传到服务器。
分析1:因为录音备忘一般时长较短文件较小,所以录音完将录音文件上传到服务器的同时,本地也保留录音文件,用户查看档期并点击播放语音备忘时,先读取本地录音文件,找不到时再到服务器下载保存到本地,然后再使用AVAudioPlayer实现本地音频播放。
需求2
婚礼音乐播放:如图,用户可以在线试听一些婚礼现场使用的背景音乐,只能选中某一首背景音乐进行播放,播放完成后停止,不能自动播放下一首。
image
分析2:因为试听的音乐是在服务器上,而AVAudioPlayer只能播放本地音乐文件,所以需要使用支持在线音乐的AVPlayer进行播放。
需求3 婚语开场白:如图,在需求2的前提下,支持列表自动播放,类似于网易音乐。同时支持后台播放、锁屏歌曲信息显示和控制、耳机控制等
image
分析3:此时可以使用AVPlayer的子类AVQueuePlayer进行列表播放。AVAudioPlayer,AVPlayer,AVQueuePlayer都支持后台播放、锁屏信息、耳机控制等
接下来,详细讲解一下这几个类:
一、 AVAudioPlayer
主要提供以下了几种播放音频的方法:
System Sound Services
System Sound Services是最底层也是最简单的声音播放服务,调用 AudioServicesPlaySystemSound 这个方法就可以播放一些简单的音频文件,使用此方法只适合播放一些很小的提示或者警告音,因为它有很多限制:
■ 声音长度要小于 30 秒
■ In linear PCM 或者 IMA4 (IMA/ADPCM) 格式的
■ 打包成 .caf, .aif, 或者 .wav 的文件
■ 不能控制播放的进度
■ 调用方法后立即播放声音
■ 没有循环播放和立体声控制
另外,它还可以调用系统的震动功能,方法也很简单。具体的代码可以参考官方的示例 SysSound
,但是官方的示例只有一些简单的用法,从文档中我们发现可以通过 AudioServicesAddSystemSoundCompletion 方法为音频播放添加CallBack 函数,有了 CallBack 函数我们可以解决不少问题,比如可以克服 System Sound Services本身不支持循环播放的问题。
AVAudioPlayer 是 AVFoundation.framework 中定义的一个类,所以使用要先在工程中引入AVFoundation.framework。我们可以把 AVAudioPlayer看作是一个高级的播放器,它支持广泛的音频格式,主要是以下这些格式:
■ AAC
■ AMR(AdaptiveMulti-Rate, aformatforspeech)
■ ALAC(AppleLossless)
■ iLBC(internetLowBitrateCodec, anotherformatforspeech)
■ IMA4(IMA/ADPCM)
■ linearPCM(uncompressed)
■ µ-lawanda-law
■ MP3(MPEG-1audiolayer3
AVAudioPlayer可以播放任意长度的音频文件、支持循环播放、可以同步播放多个音频文件、控制播放进度以及从音频文件的任意一点开始播放等,更高级的功能可以参考 AVAudioPlayer的文档 。要使用 AVAudioPlayer的对象播放文件,你只需为其指定一个音频文件并设定一个实现了 AVAudioPlayerDelegate协议的 delegate 对象。
只要将 AVAudioPlayer 的 numberOfLoops属性设为负数,音频文件就会一直循环播放直到调用 stop 方法。
虽然 AVAudioPlayer可以播放很多格式,但是我们在实际开发过程中还是最好使用一些没有压缩的格式,比如 WAVE文件,这样可以减少系统处理单元的资源占用,以便更好的完成程序的其他功能。另外,在使用 AVAudioPlayer 连续播放 mp3这类经过压缩的音频文件时,在连接处可能出现一定的间隔时间。
如果以上两种音频播放的解决方案都无法满足你的需求,那么我想你肯定需要使用 Audio QueueServices。使用 Audio Queue Services对音频进行播放,你可以完全实现对声音的控制。例如,你可以在声音数据从文件读到内存缓冲区后对声音进行一定处理再进行播放,从而实现对音频的快速/慢速播放的功能。
因为 Audio Queue Services 相对复杂很多,Apple官方已经把它整理为一本书了,具体可以参考 Audio QueueServices ProgrammingGuide 和 SpeakHere 的程序示例。
OpenAL 是一套跨平台的开源的音频处理接口,与图形处理的 OpenGL类似,它为音频播放提供了一套更加优化的方案。它最适合开发游戏的音效,用法也与其他平台下相同。
AVAudioPlayer类封装了播放单个声音的能力。播放器可以用NSURL或者NSData来初始化,要注意的是NSURL不可以是网络url而必须是本地文件url,因为AVAudioPlayer不具备播放网络音频的能力。
一个AVAudioPlayer只能播放一个音频,如果你想混音你可以创建多个AVAudioPlayer实例,每个相当于混音板上的一个轨道。
可以通过音频的NSData或者本地音频文件的url,来创建一个AVAudioPlayer实例,如加载本地的music.mp3的音频文件:
NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:@"music" withExtension:@"mp3"];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:nil];
if (self.player) {
[self.player prepareToPlay];
}
加载音频文件后,可以调用prepareToPlay方法,这样可以提前获取需要的硬件支持,并加载音频到缓冲区。在调用play方法时,减少开始播放的延迟。
当调用play方法后,开始播放音乐:
[self.player play];
1
可以调用pause或stop来暂停播放,这里的stop方法的效果也只是暂停播放,不同之处是stop会撤销prepareToPlay方法所做的准备。
[self.player stop];
1
另外,我们可以进行更多的操作:
单独设置音乐的音量(默认1.0,可设置范围为0.0至1.0,两个极端为静音、系统音量):
self.player.volume = 0.5;
1
修改左右声道的平衡(默认0.0,可设置范围为-1.0至1.0,两个极端分别为只有左声道、只有右声道):
self.player.pan = -1;
1
设置播放速度(默认1.0,可设置范围为0.5至2.0,两个极端分别为一半速度、两倍速度):
self.player.rate = 0.5;
1
设置循环播放(默认1,若设置值大于0,则为相应的循环次数,设置为-1可以实现无限循环):
self.player.numberOfLoops = -1;
这个类对应的AVAudioPlayerDelegater的委托方法。audioPlayerDidFinishPlaying:successfully:当音频播放完成之后触发。当播放完成之后,可以处理一些事情
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successf