iOS 上的 MP3 流式传输
Posted
技术标签:
【中文标题】iOS 上的 MP3 流式传输【英文标题】:MP3 streaming on iOS 【发布时间】:2010-07-19 09:01:20 【问题描述】:我想使用 OpenAL 在 ios 游戏中播放音乐。音乐文件以 mp3 格式存储,我想使用缓冲区队列流式传输它们。我使用 AudioFileReadPacketData() 将音频数据加载到缓冲区中。然而,播放缓冲区只会给我带来噪音。它适用于 caf 文件,但不适用于 mp3。我是否错过了解码文件的一些重要步骤?
我用来打开声音文件的代码:
- (void) openFile:(NSString*)fileName
NSBundle *bundle = [NSBundle mainBundle];
CFURLRef url = (CFURLRef)[[NSURL fileURLWithPath:[bundle pathForResource:fileName ofType:@"mp3"]] retain];
AudioFileOpenURL(url, kAudioFileReadPermission, 0, &audioFile);
AudioStreamBasicDescription theFormat;
UInt32 formatSize = sizeof(theFormat);
AudioFileGetProperty(audioFile, kAudioFilePropertyDataFormat, &formatSize, &theFormat);
freq = (ALsizei)theFormat.mSampleRate;
CFRelease(url);
我用来填充缓冲区的代码:
- (void) loadOneChunkIntoBuffer:(ALuint)buffer
char data[STREAM_BUFFER_SIZE];
UInt32 loadSize = STREAM_BUFFER_SIZE;
AudioStreamPacketDescription packetDesc[STREAM_PACKETS];
UInt32 numPackets = STREAM_PACKETS;
AudioFileReadPacketData(audioFile, NO, &loadSize, packetDesc, packetsLoaded, &numPackets, data);
alBufferData(buffer, AL_FORMAT_STEREO16, data, loadSize, freq);
packetsLoaded += numPackets;
【问题讨论】:
【参考方案1】:因为您正在读取 MP3 数据的字节并将它们视为 PCM 数据。
你几乎肯定想要 编辑: 除了它仍然给你 MP3 数据;它只是在数据包中提供它并(可能)解析数据包头。AudioFileReadPacketData()
。
如果您不需要 OpenAL,AVAudioPlayer 可能是更好的选择(根据Multimedia Programming Guide,如果您想要更多控制权,还有音频队列服务)。
如果您真的需要使用 OpenAL,根据TN2199,您需要将其转换为原生字节顺序的 PCM。有关使用扩展音频文件服务执行此操作的示例,请参阅 oalTouch/Classes/MyOpenALSupport.c。请注意,TN2199 表示格式“必须……不使用硬件解压缩”——根据多媒体编程指南,自 OS 3.0 以来,除了 HE-AAC 之外的所有内容都支持软件解码。另请注意,软件 MP3 解码可能会占用大量 CPU 时间。
或者,使用 AudioConverter 或(可能)带有 kAudioUnitSubType_AUConverter 的 AudioUnit 显式转换音频。如果这样做,可能值得将所有内容解压缩一次并将其保存在内存中以最大程度地减少开销。
【讨论】:
感谢您的回复。我用 AudioFileReadPacketData() 替换了 AudioFileReadBytes()。我用我的新代码更新了这个问题。但问题仍然存在,我得到的只是噪音。 出于兴趣,您决定选择什么? 我正在使用 AVAudioPlayer,它非常适合我的需求。仍然不知道我怎么会错过它。再次感谢您的出色回答。以上是关于iOS 上的 MP3 流式传输的主要内容,如果未能解决你的问题,请参考以下文章
我可以在 iOS 上使用 AV Foundation Framework 流式传输 .mp3 链接吗?