上午看了关于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. mvn命令修改pom打包的版本号

    在java项目中打包经常需要修改镜像的版本号.可以使用如下命令 mvn versions: // 如果要打包使用人如下命令,打印详细信息使用 -X mvn clean deploy -e -Dskip ...

  2. nginx https 转发

    add_header Content-Security-Policy upgrade-insecure-requests;

  3. IfcEdge

    /* Generated By: IFC Tools Project EXPRESS TO JAVA COMPILER: Do not edit this file!! */ package ifc2 ...

  4. 解决StrToDateTime()不是有效日期类型的问题

    方法一: function GetDateFormat():string; var SysFrset: TFormatSettings; begin Result:=''; GetLocaleForm ...

  5. Qt 一张图片显示在其他组件之上

    图片放在QLabel上,注意设置QLable一些属性 QImage img("test.png"); img = img.scaledToWidth(,Qt::SmoothTran ...

  6. 使用gevent包实现concurrent.futures.executor 相同的公有方法。组成鸭子类

    类名不同,但公有方法的名字和提供的基本功能大致相同,但两个类没有共同继承的祖先或者抽象类 接口来规定他,叫鸭子类. 使并发核心池能够在 threadpoolexetor和geventpoolexecu ...

  7. Python原生调试工具pdb实践小结

    使用python -m pdb xxx.py进入单步调试模式,默认会在脚本的第一行可执行命令处停止.此时,通过 b function设置之后的函数断点会提示出错,从出错异常栈中可以看出,pdb是将fu ...

  8. mac ffmpeg mediainfo视频压缩

    最近在开发官网,官网上放了一些视频,但是本宝宝拿到的都是100多.200多.300多兆的原视频,怎么把他们变成统统20兆呢?宝宝用了如下方法,很好用哟- 1.安装视频压缩工具下载ffmpeg brew ...

  9. WinSCP-windows与Linux之间文件传输

    WinSCP是一款Windows下通过使用SSH协议的开源工具,用于连接Linux操作系统,可以上传或者下载文件使用! 开源顾名思义,无需注册,安装即可使用!(安装请自行百度WinSCP) 打开桌面上 ...

  10. python进阶---列表、字典、集合相关操作

    基本概念 列表 序列是python中一个基本的数据结构,每个元素都有一个索引index 操作 # 创建列表 list = [] # 修改列表 list[2] = 2001 # 删除列表 del lis ...