上午看了关于AudioToolbox.framework相关的资料,结合网上的资料对AudioToolbox的基本使用有了整体上的认识,上一篇文章 笔谈AudioToolbox(一) 中提到使用AudioQueue来实现音频播放功能时最主要的步骤:

1. 打开播放音频文件
2. 取得播放音频文件的数据格式
3. 准备播放用的队列
4. 将缓冲中的数据移动到队列中
5. 开始播放
6. 在回调函数中进行队列处理

按照这个步骤实现了音频的播放。

 OSStatus status;

    NSString *path = [[NSBundle mainBundle] pathForResource:@"music_aac_48" ofType:@"aac"];
//打开音频文件
status=AudioFileOpenURL((CFURLRef)[NSURL fileURLWithPath:path], kAudioFileReadPermission, , &audioFile);
if (status != noErr) {
//错误处理
NSLog(@"*** Error *** PlayAudio - play:Path: could not open audio file. Path given was: %@", path);
return nil;
}
UInt32 size;

//取得音频数据格式
size = sizeof(dataFormat);
AudioFileGetProperty(audioFile, kAudioFilePropertyDataFormat, &size, &dataFormat)
 //创建播放用的音频队列
AudioQueueNewOutput(&dataFormat, BufferCallback, self,
nil, nil, , &queue);
//计算单位时间包含的包数
if (dataFormat.mBytesPerPacket== || dataFormat.mFramesPerPacket==) {
size=sizeof(maxPacketSize);
AudioFileGetProperty(audioFile, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize);
if (maxPacketSize > gBufferSizeBytes) {
maxPacketSize= gBufferSizeBytes;
}
//算出单位时间内含有的包数
numPacketsToRead = gBufferSizeBytes/maxPacketSize;
packetDescs=malloc(sizeof(AudioStreamPacketDescription)*numPacketsToRead);
}else {
numPacketsToRead= gBufferSizeBytes/dataFormat.mBytesPerPacket;
packetDescs=nil;
} //设置Magic Cookie,参见第二十七章的相关介绍
AudioFileGetProperty(audioFile, kAudioFilePropertyMagicCookieData, &size, nil);
if (size >) {
cookie=malloc(sizeof(char)*size);
AudioFileGetProperty(audioFile, kAudioFilePropertyMagicCookieData, &size, cookie);
AudioQueueSetProperty(queue, kAudioQueueProperty_MagicCookie, cookie, size);
} //创建并分配缓冲空间
packetIndex=;
for (i=; i<NUM_BUFFERS; i++) {
AudioQueueAllocateBuffer(queue, gBufferSizeBytes, &buffers[i]);
//读取包数据
if ([self readPacketsIntoBuffer:buffers[i]]==) {
break;
}
} //----------------------------------------------------------------------------
-(UInt32)readPacketsIntoBuffer:(AudioQueueBufferRef)buffer {
UInt32 numBytes,numPackets; //从文件中接受数据并保存到缓存(buffer)中
numPackets = numPacketsToRead;
AudioFileReadPackets(audioFile, NO, &numBytes, packetDescs, packetIndex, &numPackets, buffer->mAudioData);
if(numPackets >){
buffer->mAudioDataByteSize=numBytes;
AudioQueueEnqueueBuffer(queue, buffer, (packetDescs ? numPackets : ), packetDescs);
packetIndex += numPackets;
}
else{
return ;//意味着我们没有读到任何的包
}
return ;//0代表正常的退出
}
 Float32 gain=1.0;
//设置音量
AudioQueueSetParameter(queue, kAudioQueueParam_Volume, gain);
//队列处理开始,此后系统开始自动调用回调(Callback)函数
AudioQueueStart(queue, nil);
//回调函数(Callback)的实现
static void BufferCallback(void *inUserData,AudioQueueRef inAQ,
AudioQueueBufferRef buffer){
playAudio* player=(__bridge playAudio*)inUserData;
[player audioQueueOutputWithQueue:inAQ queueBuffer:buffer];
} //缓存数据读取方法的实现
-(void) audioQueueOutputWithQueue:(AudioQueueRef)audioQueue queueBuffer:(AudioQueueBufferRef)audioQueueBuffer{
OSStatus status; //读取包数据
UInt32 numBytes;
UInt32 numPackets=numPacketsToRead;
status = AudioFileReadPackets(audioFile, NO, &numBytes, packetDescs, packetIndex,&numPackets, audioQueueBuffer->mAudioData); //成功读取时
if (numPackets>) {
//将缓冲的容量设置为与读取的音频数据一样大小(确保内存空间)
audioQueueBuffer->mAudioDataByteSize=numBytes;
//完成给队列配置缓存的处理
status = AudioQueueEnqueueBuffer(audioQueue, audioQueueBuffer, numPackets, packetDescs);
//移动包的位置
packetIndex += numPackets;
}
}

  通过以上步骤和代码对AudioToolbox.framework的基本使用有了清晰的认识。但这仅仅是播放本地的音频文件,对于音频文件的暂停、回放等操作、以及对网络音频流的处理,这个是后续的学习内容了。

  本文的demo工程AudioToolboxPlayAudio 的下载地址为:http://pan.baidu.com/s/1c0pmpBM

实战AudioToolbox--在iOS平台上播放音频的更多相关文章

  1. ios平台cocos2d-x播放音频、视频、音效的Demo(支持网络视频)

    最近由ios应用转做游戏,游戏开始时需要播放一个视频,由于本身cocos2d-x播放视频的相关库,在网上搜到的资料都不是很全,我自己试过在cocos2dx直接调用ios的MediaPlayer来播放, ...

  2. 使用Vitamio开发iOS平台上的万能播放器

    迅速了解 Vitamio是干什么的?看官方怎么说: "Vitamio SDK for iOS是Yixia Ltd官方推出的 iOS 平台上使用的软件开发工具包(SDK),为iOS开发人员提供 ...

  3. 网页上播放音频、视频Mp3,Mp4

    昨天在处理网页上播放音频mp3,视频mp4上用了一天的时间来比较各种方案,最终还是选择了HTML5的 标签,谷歌浏览器.IE浏览器对标签的支持都很好,火狐上需要安装quicktime插件,效果比较差. ...

  4. iOS 平台上常见的安装包有三种,deb、ipa 和 pxl

    前言:目前 iOS 平台上常见的安装包有三种,deb.ipa 和 pxl. 其中 deb 格式是 Debian 系统(包含 Debian 和 Ubuntu )专属安装包格式,配合 APT 软件管理系统 ...

  5. Swift实现iOS录音与播放音频功能

    作用AVPLayer:可以用来播放在线及本地音视频AVAudioSession:音频会话,主要用来管理音频设置与硬件交互使用时需要导入 #import <AVFoundation/AVFound ...

  6. 实战FFmpeg + OpenGLES--iOS平台上视频解码和播放

    一个星期的努力终于搞定了视频的播放,利用FFmpeg解码视频,将解码的数据通过OpenGLES渲染播放.搞清楚了自己想知道的和完成了自己的学习计划,有点小兴奋.明天就是“五一”,放假三天,更开心啦. ...

  7. video/audio在ios/android上播放兼容

    1.audio自动播放 <audio src='xxx.mp3' autoplay></audio> 上面是audio标签autoplay属性是自动播放,但是在安卓部分浏览器和 ...

  8. unity 在安卓个IOS平台上 同一个按钮 点击后实现不同的功能

    #if UNITY_IOS UIEventListener.Get(mSprites["Recharge"].gameObject).onClick = OnIOSRecharge ...

  9. mui搜索框在ios平台上点击多次才弹出键盘的解决方法

    今天使用Hbuilder调试手机端时,发现搜索框在安卓系统下,点击一次就可以弹出键盘 但是在iso下非常的不规律,要点击多次 代码实现如下: <div class="mui-input ...

随机推荐

  1. Windows下将网络共享目录挂载到指定文件夹

    简述 因为某些原因,设计好的目录结构是不能动的,因此需要将网络共享目录挂载到指定目录下,以便扩容. 在Linux下这完全没有问题,但是Windows下的操作就稍微复杂一点. 1.直接使用net use ...

  2. 深入理解C++中的mutable,using,decltype等关键字

    深入理解C++中的mutable关键字 mutable的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词. 在C++中,mutable也是为了突破const的限制而设 ...

  3. bootcss 之 .table-hover 类 鼠标悬停

    通过添加 .table-hover 类可以让 <tbody> 中的每一行对鼠标悬停状态作出响应. <table class="table table-hover" ...

  4. 一个流行的网页动画JS库

    animejs https://animejs.com/ Anime.js (/ˈæn.ə.meɪ/) is a lightweight JavaScript animation library wi ...

  5. GenTree:基因进化和功能分析

    欢迎来到"bio生物信息"的世界 GenTree是一个集合多种数据的在线数据库. 总共涉及的基因有63152个,蛋白质编码基因有20300个. 评估基因年龄用的是UCSC数据库的1 ...

  6. EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器软件二次开发接口对接说明示列

    EasyDSS相关功能 EasyDSS流媒体服务器软件,提供一站式的转码.点播.直播.时移回放服务,极大地简化了开发和集成的工作.其中,点播版本主要包含:上传.转码.分发.直播版本主要包含:直播.录像 ...

  7. commitlint那些事儿

    这里主要介绍提交信息用到的 cz 工具集. 一.生成器 commitizen,cz`生成提交说明`,格式化 git commit message. # 全局安装cz npm install -g co ...

  8. zabbix自动停用与开启agent

    我们在升级环境时遇到了一个问题,那就是zabbix会自动发送邮件给领导,此时领导心里会嘎嘣一下,为了给领导营造一个良好的环境,减少不必要的告警邮件,减少嘎嘣次数,于是在升级之前,取消zabbix监控的 ...

  9. [bug]—console 在某些机型下的隐藏坑

    背景 我们的项目通过重写console对象上的方法实现日志上报的功能,截取代码片段如下: Class Logger() { debug() {}, info() {}, warn() {}, ... ...

  10. time 库

    time 库的三类函数 时间获取: >>> import time >>> time.time() 1570150181.4052463#单位为秒 >> ...