【问题标题】:Dynamically detecting and streaming AAC using AQ's and audiofilestream使用 AQ 和 audiofilestream 动态检测和流式传输 AAC
【发布时间】:2011-03-13 16:25:32
【问题描述】:

我目前正在播放 MP3 和 AAC 广播电台。 我正在读取 ICY/HTTP 标头,当检测到内容类型中的音频/aac 或音频/aacp 时,我提供 kAudioFileAAC_ADTSType 作为 AudioFileStreamOpen 的线索,否则我给它 kAudioFileMP3Type。

效果很好,问题是电台正在播放 AAC,但没有在 HTTP 标头中将音频/aacp 作为内容类型发送。发生这种情况时,我通常使用 mp3 线索创建音频文件流(0 作为线索也没有什么不同),然后音频文件流的属性回调表明流认为它正在读取 MP3,formatList 回调也永远不会发生,当是时候创建音频队列失败了。

有没有办法让 AudioFileStream 与 A​​AC 一起工作,而无需在其构造函数中传递 AAC 提示,或者是否有人对如何检测这些电台有任何其他想法,而不是在我的电台数据库中以某种方式标记它们?每次我正常失败时,我也不想尝试使用 AAC 作为提示创建新的音频文件流。

【问题讨论】:

    标签: iphone objective-c cocoa-touch core-audio aac


    【解决方案1】:

    我有一段时间没看这段代码了,但我认为它应该可以解决问题。

    // the file stream parser is now ready to produce audio packets.
    // get the stream format.
    AudioFormatListItem afli = GetFirstPlayableAudioFormatForFile(inAudioFileStream);
    AudioStreamBasicDescription asbd = afli.mASBD;
    ...
    // create the audio queue
    err = AudioQueueNewOutput(&asbd, MyAudioQueueOutputCallback, myData, NULL, NULL, 0, &myData->audioQueue);
    

    GetFirstPlayableAudioFormatForFile 实现:

    AudioFormatListItem GetFirstPlayableAudioFormatForFile(AudioFileStreamID inAudioFileStream)
    {
        AudioFormatListItem *formatListPtr = NULL;
        AudioFormatListItem formatItem = {0};
        UInt32 propertySize;
    
        OSStatus status = noErr;
    
        if (NULL == inAudioFileStream) return formatItem;
    
        status = AudioFileStreamGetPropertyInfo(inAudioFileStream, kAudioFileStreamProperty_FormatList, &propertySize, NULL);
        if (noErr == status) {
    
            // allocate memory for the format list items
            formatListPtr = (AudioFormatListItem *)malloc(propertySize);
            if (NULL == formatListPtr) return formatItem;
    
            // get the list of Audio Format List Item's
            status = AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_FormatList, &propertySize, formatListPtr);
            if (noErr == status) {
                // print out some helpful information
                UInt32 numFormats = propertySize / sizeof(AudioFormatListItem);
                printf ("This file has a %d layered data format:\n", (int)numFormats);
                /*for (unsigned int i = 0; i < numFormats; ++i) {
                    CAStreamBasicDescription(formatListPtr[i].mASBD).Print();
                }*/
    
                UInt32 itemIndex;
                UInt32 indexSize = sizeof(itemIndex);
    
                // get the index number of the first playable format -- this index number will be for
                // the highest quality layer the platform is capable of playing
                status = AudioFormatGetProperty(kAudioFormatProperty_FirstPlayableFormatFromList, propertySize,
                                                formatListPtr, &indexSize, &itemIndex);
                if (noErr == status) {
                    printf ("Returning AudioFormatListItem at index %d.\n", (int)itemIndex);
                    // copy the format item at index we want returned
                    formatItem =  formatListPtr[itemIndex];
                }
            }
    
            free(formatListPtr);
        } else {
            AudioStreamBasicDescription asbd;
            UInt32 asbdSize = sizeof(asbd);
            /*status = */AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_DataFormat, &asbdSize, &asbd);
            //if (err) { errorDidOccur(myData, err, @"get kAudioFileStreamProperty_DataFormat"); return err; }
    
            formatItem.mASBD = asbd;
        }
    
    
        return formatItem;
    }
    

    【讨论】:

    • 感谢您的回复,但是正如我在 OP 中所说的那样,我的问题是我的代码中已经实现了这个逻辑,并且有时它可以工作。但是我无法从 audiofilestream 中获取 formatList 属性 - 只要我不向 AudioFileStream 构造函数提供 AAC 提示,也无法为其获取 audiofilestream 属性回调。并且我只能在我知道我正在处理来自 HTTP 标头的 AAC 流时才能提供提示,但这些都不够可靠,所以我需要另一种解决方法来知道何时应该使用 AAC 提示创建 AudioFileStream
    • 为此添加了一些赏金
    • 同样的问题,而且如果我将0传递给AudioFileStreamOpen中的fileFormat参数,那么它甚至无法区分MP2,它将它确定为MP1并且播放速度很快。但如果我手动传递 MP2 则效果很好,但对于特定文件。
    猜你喜欢
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 2020-09-06
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多