持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情
iOS 音频播放实现
在iOS 中实现音频的播放主要有如下3种方法:
-
通过
audioToolBox实现本地播放 -
通过
audioPlayer实现本地播放 -
通过
audioQueue实现本地和网络音频播放,通过audioUnit实现音频特效
下面我从实践上总结了下面两个方法的运用。
AudioPlayer实现本地音频的播放
在iOS 中使用音频需要先在APP上声明本App 调用音频AVAudiSession的category。具体的描述可下面引用,不在此一一描述。
AVAudioSession在实例化后,当前的App 如果被其他App 或者电话打断,需要通过监听AVAudioSessionInterruptionNotification的通知来实现。部分操作代码如下:
// 添加通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionInterruption:) name:AVAudioSessionInterruptionNotification object:nil];
// 将收到的通知进行回调
- (void)sessionInterruption:(NSNotification *)notification {
NSDictionary *info = notification.userInfo;
AVAudioSessionInterruptionType type = [info[AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
if (self.audioSessionBlock) {
self.audioSessionBlock(type);
}
}
- 实例化
AvAudioPlayer,并设置缓冲
// 本地路径
NSURL *localUrl = [NSURL fileURLWithPath:url];
// 实例化
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:localUrl error:nil];
// 准备播放
[self.player prepareToPlay];
// 实现代理用来监听本次播放是否完成(实现`audioPlayerDidFinishPlaying`代理方法)
self.player.delegate = self;
- 播放
// 实现播放
- (void)play {
if (!self.player.isPlaying) {
// 记录当前播放位置
self.player.currentTime = self.currentTime;
}
[self.player play];
}
- 暂停
// 实现暂停
- (void)pause {
if (self.player.isPlaying) {
// 记录当前播放位置
self.currentTime = self.player.currentTime;
[self.player pause];
}
}
- 滑动
// 实现滑动
- (void)seekToPosition:(CGFloat)position {
// 此处应该监听手指动作,手指抬起的时候才调用
[self.player pause];
self.player.currentTime = position;
[self.player play];
}
在AudioPlayer 中实现循环播放时,需要提前设置其loopNums属性,在prepareToPlay方法之后调用会导致闪退。那实现外部可改变的循环播放就需要在audioPlayerDidFinishPlaying方法中进行操作
AudioQueue 实现音频播放
AudioQueue 是官方推荐的音频操作类,可以用来实现录制和播放功能。可以应用在以下的功能下:
-
连接音频硬件
-
管理相关模块内存
-
使用编解码器
-
调解录制与播放
在AudioQueue启动之后需要通过AudioQueueAllocateBuffer生成若干个AudioQueueBufferRef结构,这些buffer 用来存储将要播放的音频数据,并且这些buffer 收到生成他们的AudioQueue管理,内存释放在AudioQueue被dispose 时也会被销毁。