1.AudioToolbox概述
通过AudioToolbox框架,可以将短声音注册到system sound服务上,被注册到system sound服务上的声音称之为 system sounds。它必须满足下面几个条件。
(1).播放的时间不能超过30秒
(2).数据必须是 PCM或者IMA4流格式
(3).必须被打包成下面三个格式之一:Core Audio Format (.caf), Waveform audio (.wav), 或者 Audio Interchange File (.aiff)
声音文件必须放到设备的本地文件夹下面。通过AudioServicesCreateSystemSoundID方法注册这个声音文件.
2.AudioToolbox使用
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
typedef void (^ZTypewriteEffectBlock)(void);
@interface ZTypewriteEffectLabel : UILabel
{
SystemSoundID soundID;
}
/** Z
* 设置单个字打印间隔时间,默认 0.3 秒
*/
@property (nonatomic) NSTimeInterval typewriteTimeInterval;
/** Z
* 开始打印的位置索引,默认为0,即从头开始
*/
@property (nonatomic) int currentIndex;
/** Z
* 输入字体的颜色
*/
@property (nonatomic, strong) UIColor *typewriteEffectColor;
/** Z
* 是否有打印的声音,默认为 YES
*/
@property (nonatomic) BOOL hasSound;
/** Z
* 打印完成后的回调block
*/
@property (nonatomic, copy) ZTypewriteEffectBlock typewriteEffectBlock;
/** Z
* 开始打印
*/
-(void)startTypewrite;
@end
#import "ZTypewriteEffectLabel.h"
@implementation ZTypewriteEffectLabel
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.hasSound = NO;
self.typewriteTimeInterval = 0.3;
}
return self;
}
-(void)startTypewrite
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"typewriter" ofType:@"wav"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &soundID);
[NSTimer scheduledTimerWithTimeInterval:self.typewriteTimeInterval target:self selector:@selector(outPutWord:) userInfo:nil repeats:YES];
}
-(void)outPutWord:(id)atimer
{
if (self.text.length == self.currentIndex) {
[atimer invalidate];
atimer = nil;
self.typewriteEffectBlock();
}else{
self.currentIndex++;
NSDictionary *dic = @{NSForegroundColorAttributeName: self.typewriteEffectColor};
NSMutableAttributedString *mutStr = [[NSMutableAttributedString alloc] initWithString:self.text];
[mutStr addAttributes:dic range:NSMakeRange(0, self.currentIndex)];
[self setAttributedText:mutStr];
if (self.hasSound==YES)
AudioServicesPlaySystemSound (soundID);
else
AudioServicesPlaySystemSound (0);
}
}
运行效果这样的
以下转载:http://blog.csdn.net/ch_soft/article/details/7381976
AudioToolbox这个库是C的接口,偏向于底层,用于在线流媒体音乐的播放,可以调用该库的相关接口自己封装一个在线播放器类,AudioStreamer是老外封装的一个播放器类,有兴趣的朋友可以研究下。
其实IOS库中有两个可以播放在线音乐的播放器类,AVPlayer和MPMusicPlayerController这两个做简单的播放还不错,但是如果要做专业的音乐播放项目,功能还不够强大,例如:边听边存、断点续传、播放事件等等都无法满足。一下是以前做的笔记,仅供参考
播放流程图:
数据结构及接口说明:
- • 数据类型
- 1.AudioFileStreamID 文件流
- 2.AudioQueueRef 播放队列
- 3.AudioStreamBasicDescription 格式化音频数据
- 4.AudioQueueBufferRef 数据缓冲
- • 回调函数
- 1.AudioFileStream_PacketsProc 解析音频数据回调
- 2.AudioSessionInterruptionListener 音频会话被打断
- 3.AudioQueueOutputCallback 一个AudioQueueBufferRef播放完
- • 主要函数
- 0.AudioSessionInitialize (NULL, NULL, AudioSessionInterruptionListener, self);
- 初始化音频会话
- 1.AudioFileStreamOpen(
- (void*)self,
- &AudioFileStreamPropertyListenerProc,
- &AudioFileStreamPacketsProc,
- 0,
- &audio_file_stream);
- 建立一个文件流AudioFileStreamID,传输解析的数据
- 2.AudioFileStreamParseBytes(
- audio_file_stream,
- datalen,
- [data bytes],
- kAudioFileStreamProperty_FileFormat);
- 解析音频数据
- 3.AudioQueueNewOutput(&audio_format, AudioQueueOutputCallback, (void*)self, [[NSRunLoop currentRunLoop] getCFRunLoop], kCFRunLoopCommonModes, 0, &audio_queue);
- 创建音频队列AudioQueueRef
- 4.AudioQueueAllocateBuffer(queue, [data length], &buffer);
- 创建音频缓冲数据AudioQueueBufferRef
- 5.AudioQueueEnqueueBuffer(queue, buffer, num_packets, packet_descriptions);
- 把缓冲数据排队加入到AudioQueueRef等待播放
- 6.AudioQueueStart(audio_queue, nil); 播放
- 7.AudioQueueStop(audio_queue, true);
- AudioQueuePause(audio_queue); 停止、暂停
- • 断点续传
- 1。在http请求头中设置数据的请求范围,请求头中都是key-value成对
- key:Range value:bytes=0-1000
- [request setValue:range forHTTPHeaderField:@"Range"];
- 可以实现,a.网络断开后再连接能继续从原来的断点下载
- b.可以实现播放进度可随便拉动
首先获得文件路径:CFURLCreateFromFileSyste
获得音频文件属性: AudioFileGetProperty
取得音频文件数据: AudioFileReadPackets
初始化 AudioComponentDescriptio
通过 AURenderCallbackStruct 创建一个回调函数并通过 AudioUnitSetProperty 设置其回调属性。
最后进行 AudioUnitInitialize 进行初始化完毕操作。
通过AudioOutputUnitStart进行播放,AudioOutputUnitStop进行暂停。
AudioToolbox.framework框架学习
AudioFile类
一个c编程接口,使用AudioFile可以从内存或硬盘中读取或写入多种格式的音频数据。
AudioFileStream类
提供了一个借口,用来解析流音频文件。
功能:从网络中读取数据流,把数据流解析成音频文件。
音频文件流是不容易获取的。当需要从stream中读取data时,以前的data可能已无法使用,而新的data还没有到达,而从网络中获取的data可能还包含packets数据。为了解析audio stream,parser必须记着已经获取的数据,等待剩余的数据。
缓冲区是在哪设置的?
//创建一个new stream parse
AudioFileStreamOpen(self, AudioFileStream_PropertyListenerProc inPropertyListenerProc, AudioFileStream_PacketsProc inPacketsProc, AudioFileTypeID inFileTypeHint, AudioFileStreamID *outAudioFileStream);
//aquire some data
AudioFileStreamParseBytes(<#AudioFileStreamID inAudioFileStream#>, <#UInt32 inDataByteSize#>, <#const void *inData#>, <#UInt32 inFlags#>);
//设置从流文件中读取data时的offset
AudioFileStreamSeek(<#AudioFileStreamID inAudioFileStream#>, <#SInt64 inPacketOffset#>, <#SInt64 *outDataByteOffset#>, <#UInt32 *ioFlags#>);
//获取完数据后,关闭该流对象
AudioFileClose(<#AudioFileID inAudioFile#>)
AudioServices
AudioQueue
使用一个缓冲队列来存储data,用来播放或录音。播放或录音的时候,数据以流的形式操作,可以边获取数据变播放,或者边录音,边存储。
Resources:https://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html
AudioQueue
一个c编程接口,是Core Audio的一部分。功能:录音、播放音频。
AudioQueue类播放音频时,在内存中维护着一个buffer queue。只要buffer中有数据就可以播放,因此,一般使用AudioQueue对象来播放音频流,这样可以“边下载边播放”。
audioqueue中的方法都是静态方法,使用时传递进去的参数前缀是in,传递出来的参数前缀是out播放音频的方法:
AudioQueueNewOutput
1、用来创建一个播放音频队列的对象AudioQueueRef,然后就是对该audioqueue对象进行操作。
2、用来添加一个回调方法AudioQueueOutputCallback,调用该方法时会返回一个audioqueue的buffer,该buffer中的数据已经被使用,需要在这个方法中填充新数据。
3、
AudioQueueEnqueueBuffer
想缓冲区中添加新的数据(数据一般从file或网络中获取)
AudioQueueAllocateBuffer
为一个audioqueue分配一个queueBuffer,每调用一次创建一个缓冲区,最后所有的缓冲区组成一个缓冲队列。
AudioQueueCreateTimeline
创建一个与audioqueue相关的时间轴。如果想要显示audio的时间,需要熟悉uyutimeLine相关的方法。
audioqueue的属性操作:
具体属性类型见官方文档:https://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/c/func/AudioQueueAddPropertyListener
AudioQueueSetProperty
用来设置某一个audioqueue对象的属性,具体属性以 kAudioQueueProperty_*开头
AudioQueueGetProperty
获取audioqueue对象的某一个属性值。首先应该先调用AudioQueueGetPropertySize方法获取value的大小(byte形式)
AudioQueueAddPropertyListener
添加一个属性监听器。当一个audioqueue的对应属性值改变时,会回调这个监听器。
audioqueue的参数操作:
AudioQueueSetParameter
AudioQueueGetParameter
对参数的修改和获取,具体参数parameter包括:音量的调节、声道的调节、以及音量的渐变设置
NSFileHandle 用来从文件、socket中读取数据
CFReadStream
用来读取一个字节流byte stream,该字节流可以来自于内存、一个文件、一个socket。在读bytes之前,流stream需要被打开。
CFWriteStream
用来写一个字节流
AudioStreamBasicDescription
音频数据流格式的描述.Callback Method 回调函数,系统规定好了回调函数的参数,以及调用的地方,你只需要保证参数的格式正确,向函数里添加代码即可,函数的方法名称可以随便写,没有强制的规定。
AudioQueueNewOutput的第三个参数:inUserData 这是由用户来自定义的,数据的来源。只需要传递一个对象进去即可。使用,当系统自动调用回调函数MyAudioQueueOutputCallback或者MyAudioQueueInputCallback时候,返回的第一个参数inUserData就是你在AudioQueueNewOutput中设置的第三个参数。然后,你需要在回调函数中使用这个对象填充buffer(播放音频,当一个buffer为空时自动调用)或者读取buffer的数据(录音,当一个buffer满时自动调用)。
AudioFileStream_PropertyListenerProc
当在audio stream中找到一个property value后,回调该方法。
AudioFileStream_PacketsProc当在stream中找到audio data后回调该方法。
在参数中的in和out个代表的意思:in代表的是这个参数需要你在外面得到然后传递进去,在这个方法中要使用;out开头的参数表示这个参数是这个方法返回的值,你一般只需要定义一个引用,然后传递进去,执行完这个方法后,这个参数就实例化了。oh,my god!坑爹的苹果。
//====下载=====
CFReadStream
CFReadStreamClientCallBack回调函数在CFReadStreamSetClient中调用,是第三个参数。CFReadStreamClientCallBack只有在满足CFReadStreamSetClient中添加的streamEvents发生时才会别回调。
CFReadStreamScheduleWithRunLoop方法把stream加到一个线程中。然后,CFReadStreamSetClient在设置的东西就起作用了。当各种streamEvent发生时,client都会得到通知,client判断是否执行回调方法CFReadStreamClientCallBack。
AudioSession类
一个c接口,用来管理应用中audio的行为。
线程的操作,暂停后可能是县城就停止了。
对线程的操作 让某一个线程停下来。
参考阅读:
AudioToolbox之AudioQueue.h(二)Creating and Disposing of Audio Queues