- (voID)mediAPIcker: (MPMediAPIckerController *)mediAPIcker dIDPickMediaItems:(MPMediaItemCollection *)mediaItemCollection{ NSArray *arr = mediaItemCollection.items; MPMediaItem *song = [arr objectAtIndex:0]; NSData *songData = [NSData dataWithContentsOfURL:[song valueForProperty:MPMediaItemPropertyAssetURL]];}
然后我有这个Game Center的方法来接收数据:
- (voID)match:(GKMatch *)match dIDReceiveData:(NSData *)data fromPlayer:(Nsstring *)playerID
我有很多麻烦,弄清楚如何通过GameCenter发送此AVAsset,然后在接收设备上播放。
我已阅读:
http://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/AudioStreamReference/Reference/reference.html#//apple_ref/doc/uid/TP40006162
http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/MultimediaPG/UsingAudio/UsingAudio.html#//apple_ref/doc/uid/TP40009767-CH2-SW5
http://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html
http://developer.apple.com/library/mac/#documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/Introduction/Introduction.html
我只是迷路了信息超载。
我已经实现了可爱与爱的音频流代码,但我无法弄清楚如何采取通过GameCenter收到的NSData并将其推入他的代码。
http://cocoawithlove.com/2008/09/streaming-and-playing-live-mp3-stream.html
有人可以帮我弄清楚吗?所以我需要帮助的部分就是简单地将歌曲数据分解成数据包(或者可以工作),然后迭代通过这些数据包并通过游戏包发送,然后解析在接收设备上播放的数据AS PLAY它AS它进来
解决方法 你需要看的API是 “Audio Queue Services”。对,这里有一个基本的概述,你需要做什么。
播放音频时,您可以设置队列或服务。该队列将要求一些音频数据。然后,当它已经播放了所有这一切,它会要求更多。这样一来,直到你停止队列,或者没有更多的数据要播放。
iOS中的两个主要的较低级别的API是音频单元和音频队列。在较低的层次上,我的意思是一个API,比说“播放这个mp3”或其他任何东西,都有点肮脏。
我的经验是音频单元的延迟较低,但是音频队列更适合流式传输音频。所以,我认为,后者是一个更好的选择。
您需要做的一个关键部分是缓冲。这意味着足够加载数据,以便您的播放没有间隙。您可能希望通过初始加载更大量的数据来处理此问题。然后你正在前进。您将在内存中拥有足够大的缓冲区,同时在后台线程上同时接收更多数据。
我建议仔细研究的示例项目是SpeakHere.特别看类SpeakHereController.mm和AQPlayer.mm。
控制器处理像启动和停止AQPlayer这样的事情。 AQPlayer代表AudioQueue。仔细观察AQPlayer :: AQBufferCallback。这是当队列需要更多数据时调用的回调方法。
您需要确保队列数据的设置以及您收到的数据格式正好相符。检查通道数量(单声道或立体声?),帧数,整数或浮点数以及采样率。如果有什么不匹配的话,你可以通过相应的缓冲区来获得EXC_BAD_ACCESS错误,否则会产生白噪声,或者 – 在采样率不正确的情况下,声音听起来慢下来向上。
请注意,SpeakHere运行两个音频队列;一个用于录制,一个用于播放。所有音频文件都使用数据缓冲区。所以你总是将圆指针传递给缓冲区。所以,例如在播放过程中,您将会说一个具有20秒音频的内存缓冲区。也许每秒钟你的回调将被队列调用,基本上是说“给我另一秒的数据值”。您可以将其视为播放头,通过您的数据请求更多信息。
我们再来看看这个更详细一点。不同的是,您将要在内存缓冲区中使用,而不是将音频写入临时文件。
请注意,如果您正在处理大量数据,则在iOS设备上,您将别无选择,只能将其大部分存储在磁盘上。特别是如果用户可以重放音频,倒带等等,那么您需要将其全部放在某个地方!
无论如何,假设AQPlayer将从内存读取,我们需要如下更改它。
首先,在某个地方保存数据,在AQPlayer.h中:
voID SetAudioBuffer(float *inAudioBuffer) { mMyAudioBuffer = inAudioBuffer; }
您已经在NSData对象中拥有该数据,因此您只需传入从[myData字节]的调用返回的指针。
什么提供数据到音频队列?这是AQPlayer中设置的回调方法:
voID AQPlayer::AQBufferCallback(voID * inUserData,AudioQueueRef inAQ,AudioQueueBufferRef inCompleteAQBuffer)
我们将用于将部分数据添加到音频队列的方法是AudioQueueEnqueueBuffer:
AudioQueueEnqueueBuffer(inAQ,inCompleteAQBuffer,NulL);
inAQ是我们回调接收到的队列的引用。
inCompleteAQBuffer是指向音频队列缓冲区的指针。
那么如何获取你的数据 – 这是通过调用你的NSData对象的bytes方法返回的指针到CompleteAQBuffer中的音频队列缓冲区?
使用memcpy:
memcpy(inCompleteAQBuffer->mAudioData,THIS->mMyAudioBuffer + (THIS->mMyPlayBufferposition / sizeof(float)),numBytesTocopy);
您还需要设置缓冲区大小:
inCompleteAQBuffer->mAudioDataByteSize = numBytesTocopy;
numBytesTocopy总是一样的,除非你即将用完数据。例如,如果你的缓冲区是2秒的音频数据,你有9秒播放,那么对于前四个回调你将通过2秒的价值。对于最后的回调,您只剩下1秒的数据。 numBytesTocopy必须反映出来。
// Calculate how many bytes are remaining? It Could be less than a normal buffer // size. For example,if the buffer size is 0.5 seconds and recording stopped // halfway through that. In which case,we copy across only the recorded bytes // and we don't enqueue any more buffers. SInt64 numRemainingBytes = THIS->mPlayBufferEndposition - THIS->mPlayBufferposition; SInt64 numBytesTocopy = numRemainingBytes < THIS->mBufferByteSize ? numRemainingBytes : THIS->mBufferByteSize;
最后,我们推进播放头。在我们的回调中,我们给了队列一些数据。下次什么时候得到回调?我们不想再给出相同的数据。除非你正在做一些有趣的dj循环的东西!
所以我们提前了,这基本上只是一个指向我们的音频缓冲区的指针。指针像记录上的针一样移动缓冲区:
SELF->mPlayBufferposition += numBytesTocopy;
而已!还有一些其他的逻辑,但是您可以通过研究SpeakHere中的完整回调方法来获得。
几点我必须强调。首先,不要只是复制粘贴我的代码。绝对确保你明白你在做什么无疑你会遇到问题,你需要了解发生了什么。
其次,请确保音频格式相同,甚至更好地了解音频格式。这在Audio Queue Services Programming Guide in Recording Audio中讨论。看列表2-8指定音频队列的音频数据格式。
了解您拥有最原始的数据单位(无论是整数还是浮点数)至关重要。单声道或立体声您在一帧中有一个或两个通道。这定义了该帧中有多少整数或浮点数。那么你每帧都有帧(大概是1)。您的采样率决定了每秒数据包的数量。
这些都在文档中。只要确保一切匹配,或者你会有一些很奇怪的声音!
祝你好运!
总结以上是内存溢出为你收集整理的iphone – iOS流音频从一个iOS设备到另一个全部内容,希望文章能够帮你解决iphone – iOS流音频从一个iOS设备到另一个所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)