[iOS]使用Audio Queue Services 播放和录制音频
2015-07-02 14:36
453 查看
要在iOS设备上播放和录制音频,苹果推荐我们使用AVFoundation框架中的AVAudioPlayer和AVAudioRecorder类。虽然用法比较简单,但是不支持流式;这就意味着:在播放音频前,必须等到整个音频加载完成后,才能开始播放音频;录音时,也必须等到录音结束后,才能获取到录音数据。这给应用造成了很大的局限性。为了解决这个问题,我们就需要使用Audio Queue Services来播放和录制音频;为了简化音频文件的处理,这里还需要用到Audio
File Services(以前以为C语言没有音频文件处理的函数库,现在找到了)。
在使用之前,我们需要了解AudioQueue Service的基本工作原理。
图1一个录音音频队列(Recording Audio Queue)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/e12bb3572898674d7300b26b016f8794.gif)
由上图可以得知,一个Recording Audio Queue,包括Buffer(缓冲器)组成的Buffer Queue(缓冲队列),以及一个Callback(回调)。他们之间是如何工作的呢?
图2 录音流程
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/ca690d4fdf3e58b60366ca9a0c4161ee.gif)
1. 将音频填入第一个缓冲器中
2. 当队列中的第一个缓冲器填满时,会自动填充下一个缓冲器。此时,会触发回调。
3. 在回调函数中需要将音频数据流写入磁盘
4. 然后,需要在回调函数中将该缓冲器重新放入缓冲队列,以便重复使用该缓冲器。重复步骤2。
在了解录音的流程之后,让我们来看看播放基本体系结构。
图3 一个播放音频队列(A playback audio queue)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/49ab7e3fe94566d603cd081c3d893537.gif)
由上图可以得知,其结构和录音音频队列基本一致,只是回调触发的时机不同,工作流程略有差异。
图4 播放流程
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/125213b7239fdc9c6737d0cf50109ea6.gif)
1. 将音频读入到缓存器中。一旦填充满一个缓存器,就会进入缓存队列,此时处于待命状态。
2. 应用程序命令发出指令,要求音频队列开始播放。
3. 音频会从第一个缓存器中取数据,并开始播放。
4. 一旦播放完成,就会触发回调,并开始播放下一个缓存器中的内容。
5. 回调中需要给该缓存器取后面的音频数据,然后重新放入缓存队列中。重复步骤3。
至此,Audio QueueServices的基本原理就算介绍完了。在实际的应用中,还需要处理好各种状态,以及异常情况,例如播放中断、没有录音设备等。关于Audio File Services 的使用,我这里就不做介绍了,详细参考源码。
与本文配套的源代码示例:http://download.csdn.net/detail/midfar/4044390
参考资料:
Audio Queue Services Programming Guide
https://developer.apple.com/library/ios/#documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005343
Audio Queue Services Reference
https://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/uid/TP40005117
Audio File Services Reference
https://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/AudioFileConvertRef/Reference/reference.html#//apple_ref/doc/uid/TP40006072
File Services(以前以为C语言没有音频文件处理的函数库,现在找到了)。
在使用之前,我们需要了解AudioQueue Service的基本工作原理。
图1一个录音音频队列(Recording Audio Queue)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/e12bb3572898674d7300b26b016f8794.gif)
由上图可以得知,一个Recording Audio Queue,包括Buffer(缓冲器)组成的Buffer Queue(缓冲队列),以及一个Callback(回调)。他们之间是如何工作的呢?
图2 录音流程
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/ca690d4fdf3e58b60366ca9a0c4161ee.gif)
1. 将音频填入第一个缓冲器中
2. 当队列中的第一个缓冲器填满时,会自动填充下一个缓冲器。此时,会触发回调。
3. 在回调函数中需要将音频数据流写入磁盘
4. 然后,需要在回调函数中将该缓冲器重新放入缓冲队列,以便重复使用该缓冲器。重复步骤2。
在了解录音的流程之后,让我们来看看播放基本体系结构。
图3 一个播放音频队列(A playback audio queue)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/49ab7e3fe94566d603cd081c3d893537.gif)
由上图可以得知,其结构和录音音频队列基本一致,只是回调触发的时机不同,工作流程略有差异。
图4 播放流程
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/125213b7239fdc9c6737d0cf50109ea6.gif)
1. 将音频读入到缓存器中。一旦填充满一个缓存器,就会进入缓存队列,此时处于待命状态。
2. 应用程序命令发出指令,要求音频队列开始播放。
3. 音频会从第一个缓存器中取数据,并开始播放。
4. 一旦播放完成,就会触发回调,并开始播放下一个缓存器中的内容。
5. 回调中需要给该缓存器取后面的音频数据,然后重新放入缓存队列中。重复步骤3。
至此,Audio QueueServices的基本原理就算介绍完了。在实际的应用中,还需要处理好各种状态,以及异常情况,例如播放中断、没有录音设备等。关于Audio File Services 的使用,我这里就不做介绍了,详细参考源码。
与本文配套的源代码示例:http://download.csdn.net/detail/midfar/4044390
参考资料:
Audio Queue Services Programming Guide
https://developer.apple.com/library/ios/#documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005343
Audio Queue Services Reference
https://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/doc/uid/TP40005117
Audio File Services Reference
https://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/AudioFileConvertRef/Reference/reference.html#//apple_ref/doc/uid/TP40006072
相关文章推荐
- [前端] marquee使用
- Building an MFC project for a non-Unicode character set is deprecated
- 编译android源码遇到的问题use BUILD_PREBUILT instead
- MQTT的学习研究(十七)Mosquitto简要教程(安装&使用)
- 【android】开发笔记系列UI篇
- private static final long serialVersionUID的作用
- UITableView添加UITapGestureRecognizer与didSelectRowAtIndexPath冲突解决
- Activity中UI框架基本概念
- MQTT的学习研究(十六) MQTT的Mosquitto的window安装部署
- MQTT的学习研究(十四) MQTT moquette 的 Callback API 消息发布订阅的实现
- MQTT的学习研究(十二) MQTT moquette 的 Future API 消息发布订阅的实现
- MQTT的学习研究(十)【转】mosquitto——一个开源的mqtt代理
- MUI开发注意事项 Uncaught ReferenceError: plus is not defined
- 小胖说事23-----UICollectionView基础笔记
- 黑马程序员----OC学习笔记之NSNumber和NSValue
- NSInteger 与 NSUInteger 和 int 区别
- UITextView 200字符限制,中文算1个字,英文算0.5个字
- 前端优化:RequireJS Optimizer 的使用和配置方法(二)
- 前端优化:RequireJS Optimizer 的使用和配置方法(一)
- 动态计算UITableViewCell高度详解 -- 学习