3

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

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

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

4

1 回答 1

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;
}
于 2011-03-13T18:46:14.633 回答