使用Apple音频文件流服务,iOS 7,无法解析M4A,AAC文件

时间:2014-05-06 19:17:19

标签: ios objective-c audio-streaming audiotoolbox multipeer-connectivity

我正在使用本教程Multipeer Connectivity Audio Stream To Multiple Peers和此项目Github Repository,以便从NSInputStream流式传输音频,该音频来自:

-(void)session:didReceiveStream:withName:fromPeer:

MCSession委托方法。

之后,打开一个新的音频文件流(TDAudioFileStreamer / Classes / AudioFileStream.m:39):

OSStatus err = AudioFileStreamOpen((__bridge void *)self, TDAudioFileStreamPropertyListener, TDAudioFileStreamPacketsListener, 0, &_audioFileStreamID); 

然后从NSInputStream读取字节并尝试通过这种方式解析(TDAudioFileStreamer / Classes / AudioFileStream.m:98):

err = AudioFileStreamParseBytes(self.audioFileStreamID, length, data, kAudioFileStreamParseFlag_Discontinuity);

或者:

err = AudioFileStreamParseBytes(self.audioFileStreamID, length, data, 0);

取决于数据流。

最后,这个用解析后的数据填充AudioQueue Buffer以便播放(我猜--TDAudioFileStreamer / Classes / TDAudioQueueFiller.m)。

这对于MP3格式文件非常有用,但在尝试解析字节时使用其他格式得到"不支持的文件格式"错误。

Apple文档称音频文件流服务支持很多格式,它们列在此链接中:Apple Stream Services supported formats,但对我来说只适用于MP3。

我也在尝试,当打开音频文件流传递关于这样的文件格式的提示并发送M4A或AAC文件时:

OSStatus err = AudioFileStreamOpen((__bridge void *)self, TDAudioFileStreamPropertyListener, TDAudioFileStreamPacketsListener, kAudioFileAAC_ADTSType, &_audioFileStreamID);

其中kAudioFileAAC_ADTSType是将要流式传输的已发送文件的类型,通过这种方式,"不支持的文件格式错误"消失,但应用程序崩溃并获得新的错误 enter image description here

这说:io:lpc和客户:aac。

  • 有人知道这是什么意思吗?
  • 队列期待AAC格式文件?
  • 为什么选择LPCM(线性脉冲编码调制),我发送的M4A或AAC不是LPCM?

提前致谢。

2 个答案:

答案 0 :(得分:2)

为了使用AudioFileStream流式传输/解析M4A,需要针对流式传输优化m4a文件。

这意味着标头需要位于文件的前面,并且具有正确的信息,使您的解析器能够完成其工作。

有些编码器会为你优化m4a,但有些编码器不会。例如,如果使用itunes播放器创建m4a文件,只需右键单击并选择“创建AAC版本”,即可创建针对流优化的m4a文件。

您可以使用http://ridiculousfish.com/hexfiend/

进行检查

enter image description here

但如果您使用let say encoding.com对m4a文件进行编码,您将获得不同类型的编码。

从磁盘播放整个文件时它们都可以工作,但优化版本将被正确解析/流式传输。

现在您收到的错误告诉您,解析器无法从您正在解析的文件中获取正确的AudioStreamBasicDescription,文件可能拒绝提供比特率信息...

尝试查看此代码,以便更好地理解处理m4a类型http://www.cocoawithlove.com/2010/03/streaming-mp3aac-audio-again.html

答案 1 :(得分:0)

这里的技巧是,您需要在正确的位置(即在您的情况下)TDAudioFileStreamPropertyListener回调中获取并设置m4a格式的必要属性。检查参数AudioFileStreamPropertyID何时适合属性kAudioFileStreamProperty_ReadyToProducePackets,然后将其粘贴:

 UInt32 cookieSize = 0;
            OSStatus error = AudioFileStreamGetPropertyInfo(audioFileStream, kAudioFilePropertyMagicCookieData, &cookieSize, NULL);
            // If there is an error here, then track from stream doesn't have a cookie
            if (error == noErr && cookieSize != 0) {
                char *cookie = malloc(cookieSize * sizeof(char));
                error = AudioFileStreamGetProperty(audioFileStream, kAudioFilePropertyMagicCookieData, &cookieSize, cookie);
                if (error == noErr) {
                    error = AudioConverterSetProperty(audioConverterRef, kAudioConverterDecompressionMagicCookie, cookieSize, cookie);
                    if (error != noErr) {
                        printf("Could not Set kAudioConverterDecompressionMagicCookie on the Audio Converter!");
                    }
                } else {
                    printf("Could not Get kAudioFilePropertyMagicCookieData from stream!");
                }
                free(cookie);
            }