简体   繁体   English

使用Apple Audio File Stream Services,iOS 7无法解析M4A,AAC文件

[英]Fail Parsing M4A, AAC file with Apple Audio File Stream Services, iOS 7

I'm using this tutorial Multipeer Connectivity Audio Stream To Multiple Peers and this project Github Repository , in order to stream audio from NSInputStream, which is obtained by: 我正在使用本教程Multipeer Connectivity Audio Stream To Multiple Peers和这个项目Github Repository ,以流式传输来自NSInputStream的音频,该方法通过以下方式获得:

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

MCSession delegate method. MCSession委托方法。

After, this open a new Audio File Stream (TDAudioFileStreamer/Classes/AudioFileStream.m:39): 之后,这将打开一个新的音频文件流(TDAudioFileStreamer / Classes / AudioFileStream.m:39):

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

Then read bytes from NSInputStream and try to parse by this way (TDAudioFileStreamer/Classes/AudioFileStream.m:98): 然后从NSInputStream读取字节并尝试通过这种方式进行解析(TDAudioFileStreamer / Classes / AudioFileStream.m:98):

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

Or: 要么:

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

Depending of the data flow. 取决于数据流。

And finally, this fill AudioQueue Buffer with the parsed data in order to playback (i guess - TDAudioFileStreamer/Classes/TDAudioQueueFiller.m) . 最后,用解析的数据填充AudioQueue Buffer以便回放(我猜是TDAudioFileStreamer / Classes / TDAudioQueueFiller.m)。

This works really nice for MP3 format files, but with others formats when try to parse the bytes get "unsupported file format" error. 这对于MP3格式的文件确实非常好,但是在尝试解析字节时使用其他格式会出现“不支持的文件格式”错误。

The Apple documentation, says Audio File Stream services support a lot of formats and they are listed in this Link: Apple Stream Services supported formats , but for me only works with MP3. Apple文档说,音频文件流服务支持多种格式,并在此链接中列出: Apple Stream Services支持的格式 ,但对我而言仅适用于MP3。

I was trying too, when open the Audio File Stream pass a hint about file format like this and send a M4A or AAC file: 我也在尝试,当打开“音频文件流”时,传递有关这种文件格式的提示,然后发送M4A或AAC文件:

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

Where kAudioFileAAC_ADTSType is the type of sent file that will be streamed, by this way , the "unsupported file format error" disappears , but the application crashes and get a new error 其中kAudioFileAAC_ADTSType是将要流式传输的已发送文件的类型,通过这种方式,“不支持的文件格式错误”消失了,但是应用程序崩溃并收到新的错误 在此处输入图片说明

This says: io: lpc and client: aac. 这说:io:lpc和客户端:aac。

  • Someone know what this mean? 有人知道这是什么意思吗?
  • The Queue is expecting AAC format file? 队列需要AAC格式的文件吗?
  • Why LPCM( Linear Pulse Code Modulation), i'm sending M4A or AAC not LPCM? 为什么使用LPCM(线性脉冲编码调制),而不是LPCM发送M4A或AAC?

Thanks in advance. 提前致谢。

In order stream/parse M4A with AudioFileStream , the m4a file needs to be optimized for streaming. 为了使用AudioFileStream流/解析M4A,需要优化m4a文件以进行流传输。

That means the header needs to be in the front of the file and has the correct information that will let your parser to do its job. 这意味着标头必须位于文件的最前面,并具有正确的信息,以使您的解析器能够完成其工作。

Some encoders will optimize the m4a for you, but some encoders wont. 有些编码器会为您优化m4a,但有些编码器不会。 For example If you create an m4a file with itunes player, by simply right clicking and choosing "Create AAC Version", that will create an m4a file that is optimized for streaming. 例如,如果您使用iTunes播放器创建m4a文件,只需右键单击并选择“创建AAC版本”,这将创建一个针对流传输进行了优化的m4a文件。

You can check it by using http://ridiculousfish.com/hexfiend/ 您可以使用http://ridiculousfish.com/hexfiend/进行检查

在此处输入图片说明

but if you use lets say encoding.com to encode your m4a files, you will get a different type of encoding. 但是,如果使用“ encoding.com”来编码您的m4a文件,则会获得其他类型的编码。

they will both work when playing the whole file from disk but optimized version will be parsed/streamed correctly. 从磁盘播放整个文件时,它们都可以工作,但是优化版本将正确解析/流式传输。

Now the error you are getting tells you that parser couldnt get the correct AudioStreamBasicDescription from the file you are parsing, file probably refuse to give the bitrate info... 现在您得到的错误告诉您解析器无法从您正在解析的文件中获取正确的AudioStreamBasicDescription ,文件可能拒绝提供比特率信息...

Try to take a look at this code for better understanding handling m4a types http://www.cocoawithlove.com/2010/03/streaming-mp3aac-audio-again.html 尝试看一下这段代码,以更好地理解如何处理m4a类型http://www.cocoawithlove.com/2010/03/streaming-mp3aac-audio-again.html

The trick here is that you need to get and set the necessary properties for m4a format in the right place, namely in the callback (in your case) TDAudioFileStreamPropertyListener. 这里的技巧是,您需要在正确的位置(即在您的情况下)TDAudioFileStreamPropertyListener回调中获取并设置m4a格式的必要属性。 Check argument AudioFileStreamPropertyID when it will fit property kAudioFileStreamProperty_ReadyToProducePackets and then paste this: 检查参数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);
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM