AudioToolbox--AudioQueue实现流播放接口

AudioMedia_ios.h

[cpp] view plaincopy

  1. //
  2. //  AudioMedia_ios.h
  3. //  mmsplayer
  4. //
  5. //  Created by Weiny on 12-4-4.
  6. //  Copyright (c) 2012年 Weiny Zhou. All rights reserved.
  7. //
  8. #ifndef mmsplayer_AudioMedia_ios_h
  9. #define mmsplayer_AudioMedia_ios_h
  10. #include "wdef.h"
  11. typedef void* wAudio;
  12. #ifdef __cplusplus
  13. extern "C"
  14. {
  15. #endif
  16. wAudio audio_open(int sample,int nchannles,int bits,int nFrameSize);//初始化声音接口
  17. int audio_play(wAudio audio);//播放
  18. int audio_pause(wAudio audio);
  19. int audio_wirte(wAudio audio,unsigned char* pcm,size_t count,int64_t dts);//写入音频数据
  20. int audio_stop(wAudio audio);//停止
  21. int audio_close(wAudio audio);//关闭
  22. #ifdef __cplusplus
  23. };
  24. #endif
  25. #endif

AudioMedia_ios.c

[cpp] view plaincopy

    1. //
    2. //  AudioMedia_ios.cpp
    3. //  mmsplayer
    4. //
    5. //  Created by Weiny on 12-4-4.
    6. //  Copyright (c) 2012年 Weiny Zhou. All rights reserved.
    7. //
    8. #include "AudioMedia_ios.h"
    9. #include <AudioToolbox/AudioQueue.h>
    10. #include "system/thread.h"
    11. #include "base/wlist.h"
    12. #include "system/lx_lock.h"
    13. #define AUDIO_LIST_COUNT 3
    14. #define AUDIO_BUFFER_SECONDS  1
    15. typedef struct WAudio_Ios
    16. {
    17. int playRequested;
    18. int framesize;
    19. Wlock mlock,mdecdonelock,mqueuelock;
    20. wlist_t mAudiolist;//声音队列
    21. wlist_func mlistfunc;
    22. AudioQueueRef queue;//player list
    23. AudioQueueBufferRef mBuffers[AUDIO_LIST_COUNT];
    24. AudioStreamBasicDescription mDataFormat;
    25. AudioQueueBufferRef emptyAudioBuffer;//空音频队列
    26. }WAudio_Ios;
    27. typedef struct
    28. {
    29. void* data;
    30. size_t size;
    31. int64_t dst;
    32. }WAudio_item;
    33. void wAudio_CallBack(void * in,AudioQueueRef intq,AudioQueueBufferRef outQB);
    34. void wAudtio_fillAudioBuffer(WAudio_Ios* audio,AudioQueueBufferRef buffer);
    35. static inline void waudio_free_back(void* lpvoid,wlist_item_ptr data)
    36. {
    37. WAudio_item* item;
    38. INTOFUNC();
    39. if(!data){PRINTF_ERROR_VALUE(ERROR_INITPARAM);goto error_lab;}
    40. item=(WAudio_item*)data;
    41. SAFE_FREE(item->data);
    42. SAFE_FREE(item);
    43. error_lab:
    44. EXITFUNC();
    45. }
    46. wAudio audio_open(int sample,int nchannles,int bits,int nFrameSize)
    47. {
    48. WAudio_Ios* ptr=NULL;
    49. uint32_t err=0;
    50. int i=0;
    51. INTOFUNC();
    52. ptr=WOS_MALLOC_(WAudio_Ios, 1);
    53. if(!ptr){
    54. PRINTF_ERROR_VALUE(ERROR_NEWMEM);
    55. goto error_lab;
    56. }
    57. memset(ptr,0,sizeof(WAudio_Ios));
    58. ptr->mDataFormat.mSampleRate=sample;//设置采样率
    59. ptr->mDataFormat.mChannelsPerFrame=nchannles;
    60. ptr->mDataFormat.mBitsPerChannel=bits;
    61. ptr->mDataFormat.mFormatID=kAudioFormatLinearPCM;//设置数据格式
    62. ptr->mDataFormat.mFormatFlags=kLinearPCMFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked;
    63. ptr->mDataFormat.mFramesPerPacket=1;
    64. ptr->mDataFormat.mBytesPerFrame=
    65. ptr->mDataFormat.mBitsPerChannel/
    66. ptr->mDataFormat.mChannelsPerFrame;
    67. ptr->mDataFormat.mBytesPerPacket=
    68. ptr->mDataFormat.mBytesPerFrame*ptr->mDataFormat.
    69. mFramesPerPacket;
    70. err=AudioQueueNewOutput(&ptr->mDataFormat,wAudio_CallBack, ptr, NULL,
    71. NULL/*kCFRunLoopCommonModes*/, 0
    72. , &ptr->queue);
    73. if(err){
    74. WERROR_A("init audio output error,sample=%d,channles=%d,bits=%d.\n",sample,nchannles,bits);
    75. goto error_lab;
    76. }
    77. for (i=0;i<AUDIO_LIST_COUNT;++i)
    78. {
    79. err=AudioQueueAllocateBufferWithPacketDescriptions(ptr->queue,
    80. bits*AUDIO_BUFFER_SECONDS/8,
    81. sample*AUDIO_BUFFER_SECONDS/nFrameSize+1,ptr->mBuffers+i);
    82. if(err){
    83. WERROR_A("can‘t allocate audio queue buffer: %d",err);
    84. goto error_lab;
    85. }
    86. }
    87. ptr->mlock=lx_lock_init();
    88. ptr->mdecdonelock=lx_lock_init();
    89. ptr->mqueuelock=lx_lock_init();
    90. ptr->mlistfunc=wlist_getfunc();
    91. ptr->mAudiolist.free=waudio_free_back;
    92. ptr->framesize=nFrameSize;
    93. #if 1
    94. err=AudioQueueStart(ptr->queue,NULL);
    95. if(err){
    96. WERROR_A("Error: Audio queue failed to start: %d", err);
    97. goto error_lab;
    98. }
    99. ptr->playRequested=1;
    100. WDEBUG_OUT("Started Audio queue.",NULL);
    101. #endif
    102. #if 0
    103. agc.FrameCount = FRAME_COUNT;
    104. bufferSize = agc.FrameCount * agc.mDataFormat.mBytesPerFrame;
    105. for (i=0; i<AUDIO_BUFFERS; i++)
    106. {
    107. err = AudioQueueAllocateBuffer(agc.queue,bufferSize,&agc.mBuffers[i]);
    108. if(err) return err;
    109. AQBufferCallback(&agc,agc.queue,agc.mBuffers[i]);
    110. }
    111. err = AudioQueueStart(agc.queue,NULL);
    112. if(err) return err;
    113. while (agc.playPtr<agc.sampleLen)
    114. {
    115. select(NULL,NULL,NULL,NULL,1.0);
    116. }
    117. #endif
    118. error_lab:
    119. if(err){
    120. audio_close(ptr);
    121. SAFE_FREE(ptr);
    122. }
    123. EXITFUNC();
    124. return (wAudio)ptr;
    125. }
    126. int audio_play(wAudio audio)
    127. {
    128. int nResult=0;
    129. WAudio_Ios* ptr=NULL;
    130. INTOFUNC();
    131. if(!audio){
    132. WERROR_A("input audio is null",NULL);
    133. nResult=ERROR_INITPARAM;
    134. goto error_lab;
    135. }
    136. ptr=(WAudio_Ios*)audio;
    137. if(ptr->playRequested==0||ptr->playRequested==2)
    138. {WERROR_A("state is %d",ptr->playRequested);goto error_lab;}
    139. ptr->playRequested=1;
    140. AudioQueueStart(ptr->queue,NULL);
    141. error_lab:
    142. EXITFUNC();
    143. return nResult;
    144. }
    145. int audio_pause(wAudio audio)
    146. {
    147. int nResult=0;
    148. WAudio_Ios* ptr=NULL;
    149. INTOFUNC();
    150. if(!audio){
    151. WERROR_A("input audio is null",NULL);
    152. nResult=ERROR_INITPARAM;
    153. goto error_lab;
    154. }
    155. ptr=(WAudio_Ios*)audio;
    156. if(1!=ptr->playRequested)
    157. {WERROR_A("state is %d",ptr->playRequested);goto error_lab;}
    158. ptr->playRequested=2;
    159. AudioQueuePause(ptr->queue);
    160. error_lab:
    161. EXITFUNC();
    162. return nResult;
    163. }
    164. int audio_wirte(wAudio audio,unsigned char* pcm,size_t count,int64_t dst)
    165. {
    166. int nResult=0;
    167. WAudio_Ios* ptr=NULL;
    168. WAudio_item* item=NULL;
    169. INTOFUNC();
    170. if(!audio){
    171. WERROR_A("input audio is null",NULL);
    172. nResult=ERROR_INITPARAM;
    173. goto error_lab;
    174. }
    175. ptr=(WAudio_Ios*)audio;
    176. item=WOS_MALLOC_(WAudio_item,1);
    177. if(!item){
    178. nResult=ERROR_NEWMEM;PRINTF_ERROR_VALUE(nResult);goto error_lab;
    179. }
    180. item->data=pcm;
    181. item->size=count;
    182. item->dst=dst;
    183. lx_lock(ptr->mqueuelock);
    184. //先加入队列
    185. ptr->mlistfunc.push_back(&ptr->mAudiolist,item);
    186. //
    187. if(ptr->emptyAudioBuffer)
    188. wAudtio_fillAudioBuffer(ptr,ptr->emptyAudioBuffer);//填充空buffer
    189. lx_unlock(ptr->mqueuelock);
    190. error_lab:
    191. EXITFUNC();
    192. return nResult;
    193. }
    194. int audio_stop(wAudio audio)
    195. {
    196. int nResult=0;
    197. WAudio_Ios* ptr=NULL;
    198. INTOFUNC();
    199. if(!audio){
    200. WERROR_A("input audio is null",NULL);
    201. nResult=ERROR_INITPARAM;
    202. goto error_lab;
    203. }
    204. ptr=(WAudio_Ios*)audio;
    205. AudioQueueStop(ptr->queue,false);
    206. ptr->playRequested=0;
    207. error_lab:
    208. EXITFUNC();
    209. return nResult;
    210. }
    211. int audio_close(wAudio audio)
    212. {
    213. int nResult=0;
    214. WAudio_Ios* ptr=NULL;
    215. INTOFUNC();
    216. if(!audio){
    217. WERROR_A("input audio is null.",NULL);
    218. nResult=ERROR_INITPARAM;
    219. goto error_lab;
    220. }
    221. ptr=(WAudio_Ios*)audio;
    222. ptr->mlistfunc.clear(&ptr->mAudiolist);//清空播放队列
    223. lx_lock_free(ptr->mqueuelock);
    224. lx_lock_free(ptr->mdecdonelock);
    225. lx_lock_free(ptr->mlock);
    226. AudioQueueDispose(ptr->queue,false);
    227. SAFE_FREE(ptr);
    228. error_lab:
    229. EXITFUNC();
    230. return nResult;
    231. }
    232. #if 0
    233. void AQBufferCallback( void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB)
    234. {
    235. AQCallbackStruct *agc;
    236. short *coreAudiobuffer;
    237. short sample;
    238. int i;
    239. agc=(AQCallbackStruct *) in;
    240. coreAudiobuffer =(short*) outQB->mAudioData;
    241. printf("Sync:%i / %i \n",agc->playPtr,agc->sampleLen);
    242. if (agc->FrameCount >0)
    243. {
    244. outQB->mAudioDataByteSize = 4*agc->FrameCount;
    245. for (i=0; i<agc->FrameCount*2; i++)
    246. {
    247. if(agc->playPtr > agc->sampleLen || agc->playPtr<0)
    248. {
    249. sample =0;
    250. }
    251. else
    252. {
    253. sample = (agc->pcmBuffer[agc->playPtr]);
    254. }
    255. coreAudiobuffer[i] = sample;
    256. coreAudiobuffer[i+1] = sample;
    257. agc->playPtr++;
    258. }
    259. AudioQueueEnqueueBuffer(inQ,outQB,0,NULL);
    260. }
    261. }
    262. #endif
    263. void wAudtio_fillAudioBuffer(WAudio_Ios* audio,AudioQueueBufferRef buffer)
    264. {
    265. AudioTimeStamp bufferStartTime;
    266. uint32_t err;
    267. INTOFUNC();
    268. buffer->mAudioDataByteSize=0;
    269. buffer->mPacketDescriptionCount=0;
    270. if(audio->mAudiolist.size<=0){
    271. WERROR_A("Warning: No audio packets in queue.",NULL);
    272. audio->emptyAudioBuffer=buffer;
    273. goto error_lab;
    274. }
    275. audio->emptyAudioBuffer=NULL;
    276. while(audio->mAudiolist.size&&buffer->mPacketDescriptionCount <
    277. buffer->mPacketDescriptionCapacity)
    278. {
    279. wlist_item* item=audio->mlistfunc.pop_front(&audio->mAudiolist);
    280. WAudio_item* data=(WAudio_item*)item->data;
    281. if(buffer->mAudioDataBytesCapacity -
    282. buffer->mAudioDataByteSize >=data->size)
    283. {
    284. if(buffer->mAudioDataBytesCapacity==0)
    285. {
    286. bufferStartTime.mSampleTime=data->dst*audio->framesize;
    287. bufferStartTime.mFlags=kAudioTimeStampSampleTimeValid;
    288. }
    289. memcpy((uint8_t *)buffer->mAudioData + buffer->mAudioDataByteSize, data->data, data->size);
    290. buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mStartOffset = buffer->mAudioDataByteSize;
    291. buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mDataByteSize = data->size;
    292. buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mVariableFramesInPacket = audio->framesize;
    293. buffer->mAudioDataByteSize += data->size;
    294. ++buffer->mPacketDescriptionCount;
    295. lx_lock(audio->mqueuelock);
    296. audio->mlistfunc.remove(&audio->mAudiolist,0);
    297. lx_unlock(audio->mqueuelock);
    298. }
    299. else
    300. break;
    301. }
    302. if(buffer->mPacketDescriptionCount>0)
    303. {
    304. if(err=AudioQueueEnqueueBufferWithParameters(audio->queue,
    305. buffer,0,NULL,0,0,0,NULL,&bufferStartTime,NULL))
    306. WERROR_A("Error enqueuing audio buffer: %d", err);
    307. //decodelock
    308. lx_lock(audio->mdecdonelock);
    309. if(!audio->playRequested&&audio->mAudiolist.size==0){
    310. if(err=AudioQueueStop(audio->queue,false))
    311. WERROR_A("Error: Failed to stop audio queue: %d", err);
    312. else
    313. WERROR_A("Stopped audio queue",NULL);
    314. }
    315. lx_unlock(audio->mdecdonelock);
    316. //decodeunlock
    317. }
    318. error_lab:
    319. EXITFUNC();
    320. }
    321. void wAudio_CallBack(void * in,AudioQueueRef intq,AudioQueueBufferRef buffer)
    322. {
    323. wAudtio_fillAudioBuffer((WAudio_Ios*)in,buffer);
    324. }

来源:http://blog.csdn.net/tigerleap/article/details/7628105

时间: 2024-07-30 02:11:20

AudioToolbox--AudioQueue实现流播放接口的相关文章

苹果平台上的媒体流播放技术HLS

近日在和朋友聊起媒体流的服务器端实时转码技术的时候,发现苹果的各种终端上的视频播放并未使用常见的基于UDP的RTSP/RTP,而强制使用了Http Live Stream技术,这里稍稍总结了如下. 苹果的视频数据流播放技术要求 一如苹果的强势作风,苹果对其旗下的iPhone.iPod.iPad.Apple TV各种设备上的视频数据播放有强制的技术限制.首先,说说音视频数据的数据压缩格式要求. 1.必须使用H.264的编码压缩格式.iPhone 3G或者更新版本.iPod touch 第二代或者更

iOS音频播放之AudioQueue(一):播放本地音乐

AudioQueue简介 AudioStreamer说明 AudioQueue详解 AudioQueue工作原理 AudioQueue主要接口 AudioQueueNewOutput AudioQueueAllocateBuffer AudioQueueEnqueueBuffer AudioQueueStart Pause Stop Flush Reset Dispose AudioQueueFreeBuffer AudioQueueGetProperty AudioQueueSetProper

优酷,迅雷视屏播放接口

优酷:优酷的视频播放器接口连接为:http://open.youku.com/tools/ 里面已经有教详细的说明了.在这里也做一些说明吧:导入js文件: 1 <script type="text/javascript" src="http://player.youku.com/jsapi"> 调用: 1 <script type="text/javascript"> 2 player = new YKU.Player('

FireBreath开发实时播放接口(Yate + SIP + FFMPEG + SDL)

当时真的是需要这样的一个博文来指导做这个功能模块,可惜网上FireBreath的资料很少,本身对C++的不是很熟悉,所以一路上是不断尝试和摸索,好在马马虎虎的将这个模块实现了,现在记录下来. 首先说明一点,我们的Yate的 SIP Server和终端的SIP Client以及Android的上面的SIP Client还有Windows PC终端的SIP Client和Linux PC终端的SIP Client都实现了. 所以大家的是建议借助这个现有的条件去实现web service实时播放的功能

IJKPlayer集成直播拉流播放

iOS端集成ijkplayer实现直播播放 前言 ijkplayer框架是专门用来做 视频直播 的开源框架,基于ffmpeg,同时支持 Android 和 iOS 平台. 对于 App 中的直播功能,如果我们成功集成ijkplayer ,那么就算完成一半的工程了.接下来,只要获取到 拉流 URL,就能实现视频直播功能了. 但是初次集成这个框架,对于新手还是有一定难度的. 本篇主要介绍如何快速集成 ijkplayer 框架. 最终效果.gif 一.下载 ijkplayer 1.下载 ijkplay

限流(二)接口限流

如果某个接口可能出现突发情况,比如"秒杀"活动,那么很有可能因为突然爆发的访问量造成系统奔溃,我们需要最这样的接口进行限流. 在上一篇"限流算法"中,我们简单提到了两种限流方式: 1)(令牌桶.漏桶算法)限速率,例如:每 5r/1s = 1r/200ms 即一个请求以200毫秒的速率来执行: 2)(计数器方式)限制总数.或者单位时间内的总数,例如:设定总并发数的阀值,单位时间总并发数的阀值. 一.限制总并发数 我们可以采用java提供的atomicLong类来实现

流媒体服务器的拉流播放

首先安装nginx: yum -y install gcc gcc-c++ make auotmake autoconf libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel 但是要做依赖包的关系: wget https://github.com/arut/nginx-rtmp-module/archive/master.zip mkdir /xl unzip master.zip -d /xl/ cd /xl/ mv ngi

视频转换 rtsp 流 转rtmp流播放(未完)

前言:之前的博客找的rtsp流地址,和按照red5 都是为写这篇文章铺垫. 这篇文章,选择 ffmepg命令 把rtsp流转为rtmp, 接着vlc插件测试下生成的rtmp流. 最后 已经配置好了red5 服务器,并测试成功看到画面之后: 下面就来利用red5 实时查看rtmp 视频流:总体思路是这样. 原文地址:https://www.cnblogs.com/yizhizhangBlog/p/9953675.html

C# 实现播放RTSP 标准协议码流播放

http://www.codeproject.com/Articles/507218/Managed-Media-Aggregation-using-Rtsp-and-Rtphttp://www.streamcoders.com/http://net7mma.codeplex.com/http://ffmpegdotnet.codeplex.com/ http://download.csdn.net/detail/szlkcqb/8277719