AuidioStreamPlayer简易实现
来源:互联网 发布:c语言闰年代码 编辑:程序博客网 时间:2024/05/06 16:30
首先可以先从下面列出的参考中进行对整个Audio Stream进行一定程度的理解
参考:
https://github.com/muhku/FreeStreamer
https://github.com/mattgallagher/AudioStreamer
http://msching.github.io/blog/2014/07/09/audio-in-ios-3/
http://msching.github.io/blog/2014/08/02/audio-in-ios-5/
主要数据结构:
typedef struct AudioStream{ AudioFileStreamID mAudioFileStream; AudioQueueRef mQueue; AudioQueueBufferRef mBuffer[kNumbersOfBuffer]; AudioStreamPacketDescription mPacketDecs[kMaxPacketDescs]; AudioStreamBasicDescription mAudioStreamBasicDesc; unsigned int mFillBufferIndex; UInt32 mPacketBufferSize; size_t mBytesFilled; size_t mPacketsFilled; bool mInused[kNumbersOfBuffer]; NSInteger mBuffersUsed;}AS;typedef struct StreamFile{ UInt32 mBitRate; NSInteger mFileLength; NSInteger mDataOffset; UInt64 mAudioDataByteCount;}SF;extern NSString * const ASStatusChangedNotification;@interface FileStreamPlayer : NSObject{ AS audioStream; BOOL discontinuous; NSThread *internalThread; NSURL *url; NSDictionary *httpHeader; NSString *fileExtension; SF streamFile; double sampleRate; double packetDuration; CFReadStreamRef stream; pthread_mutex_t queueBuffersMutex; pthread_cond_t queueBufferReadyCondition; AudioStreamState state; AudioStreamStopReason stopReason; NSNotificationCenter *notificationCenter;}
首先,要实现AudioStream的获取,通过CFNetWorking的库来发送HTTP请求,并通过建立客户端接受数据将数据加入到当前RunLoop中:
CFHTTPMessageRef message= CFHTTPMessageCreateRequest(NULL, (CFStringRef)@"GET", (CFURLRef)url, kCFHTTPVersion1_1); stream = CFReadStreamCreateForHTTPRequest(NULL, message); CFRelease(message); CFDictionaryRef proxySettings = CFNetworkCopySystemProxySettings(); CFReadStreamSetProperty(stream, kCFStreamPropertyHTTPProxy, proxySettings); CFRelease(proxySettings); CFStreamClientContext context = {0, self, NULL, NULL, NULL}; CFReadStreamSetClient( stream, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, ASReadStreamCallBack, &context); CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
这里会要求实现网络流数据获取后的回调函数:ReadStreamCallBack
static void ASReadStreamCallBack(CFReadStreamRef aStream, CFStreamEventType eventType, void* inClientInfo) { FileStreamPlayer* this = (FileStreamPlayer *)inClientInfo; [this handleReadFromStream:aStream eventType:eventType];}
函数参数中要求:当前数据流,流事件类型,以及上下文对象
成功读取数据以后,通过:AudioFileStreamOpen将数据打开,可以理解成AudioFile读取时候打开一个数据流,然后进行解析
AudioFileStreamOpen AudioFileStreamParseBytes
OpenStream中要求填入两个回调函数:PropertyListenerProc和ASPacketsProc,分别作为流信息和流解析分离帧的回调之后的分离帧解析中,每次都会回调刚刚填入的回调函数
static void ASPropertyListenerProc(//callback from audioStream header void * inClientData, AudioFileStreamID inAudioFileStream, AudioFileStreamPropertyID inPropertyID, UInt32 * ioFlags) { FileStreamPlayer* this = (FileStreamPlayer *)inClientData; [this handleFileStreamPropertyChange:inAudioFileStream fileStreamPropertyID:inPropertyID ioFlags:ioFlags];}static void ASPacketsProc(//callback from audioStream body void * inClientData, UInt32 inNumberBytes, UInt32 inNumberPackets, const void * inInputData, AudioStreamPacketDescription *inPacketDescriptions) { FileStreamPlayer* this = (FileStreamPlayer *)inClientData; [this handleAudioPackets:inInputData numberBytes:inNumberBytes numberPackets:inNumberPackets packetDescriptions:inPacketDescriptions];}
接下来的操作就是包括流信息解析后存入相应的数据结构中,利用Buffer存储塞到AudioQueue中去进行运行,设置相应的AudioQueue的回调函数对完成任务后的buffer进行再次调用:
AudioQueueNewOutput(&audioStream.mAudioStreamBasicDesc, ASAudioQueueOutputCallback, self, NULL, NULL, 0, &audioStream.mQueue);static void ASAudioQueueOutputCallback(//callBack from Running Queue Buffers completed void* inClientData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) { FileStreamPlayer* this = (FileStreamPlayer*)inClientData; [this handleCompleteBuffer:inAQ buffer:inBuffer];}
接下来就可以对AudioQueue进行各种操作了,播放暂停和停止等。另外,还要注意各个操作过程中线程资源之间的调用必须要用锁进行保护,在这里我主要参考了AudioStreamer,所以采用了互斥锁pthread_和@synchronized(self)。
最后,附上我的DEMO:
http://download.csdn.net/detail/atomic123/9323745
0 0
- AuidioStreamPlayer简易实现
- 计算器简易实现
- javascript实现简易计算器
- 简易同学录JSP实现
- moss简易master实现
- socket实现简易聊天工具
- JS树简易实现
- js实现简易计算器
- JEditorPane实现简易浏览器
- spring IOC 简易实现
- BitMap简易实现
- BloomFilter简易实现
- 正则表达式简易实现
- 实现简易计算器
- 简易计算器的实现
- JAVA实现简易计算器
- 简易栈的实现
- js实现简易计算器
- 推送通知,非常详细
- Moebius for SQLServer负载均衡
- 小乐乐大逃亡HLG
- HDU 1853 Cyclic Tour && HDU 3488Tour KM算法
- android IPC通信(上)-sharedUserId&&Messenger
- AuidioStreamPlayer简易实现
- samba configure on Cent OS 6.4
- DIV常用边框样式css
- 实习整理(十七)
- [leetcode:13] 罗马数字转十进制
- 大数据时代下的SQL Server第三方负载均衡方案----Moebius测试
- 小乐乐想出门HLG
- 存储过程分页Sql语句
- ln 命令