iOS 音频播放实现

1,620 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情

iOS 音频播放实现

在iOS 中实现音频的播放主要有如下3种方法:

  1. 通过audioToolBox实现本地播放

  2. 通过audioPlayer实现本地播放

  3. 通过audioQueue实现本地和网络音频播放,通过audioUnit 实现音频特效

下面我从实践上总结了下面两个方法的运用。

AudioPlayer实现本地音频的播放

在iOS 中使用音频需要先在APP上声明本App 调用音频AVAudiSessioncategory。具体的描述可下面引用,不在此一一描述。

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);

}

}

  1. 实例化AvAudioPlayer,并设置缓冲

// 本地路径

NSURL *localUrl = [NSURL fileURLWithPath:url];

// 实例化

self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:localUrl error:nil];

// 准备播放

[self.player prepareToPlay];

// 实现代理用来监听本次播放是否完成(实现`audioPlayerDidFinishPlaying`代理方法)

self.player.delegate = self;

  1. 播放

// 实现播放

- (void)play {

if (!self.player.isPlaying) {

// 记录当前播放位置

self.player.currentTime = self.currentTime;

}

[self.player play];

}

  1. 暂停

// 实现暂停

- (void)pause {

if (self.player.isPlaying) {

// 记录当前播放位置

self.currentTime = self.player.currentTime;

[self.player pause];

}

}

  1. 滑动

// 实现滑动

- (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 时也会被销毁。