Динамическое обнаружение и потоковая передача AAC с использованием AQ и аудиофайлов - PullRequest
3 голосов
/ 13 марта 2011

В настоящее время я транслирую радиостанции MP3 и AAC. Я читаю заголовки ICY / HTTP, и при обнаружении аудио / aac или audio / aacp в типе контента я предоставляю kAudioFileAAC_ADTSType в качестве подсказки для AudioFileStreamOpen, в противном случае я даю ему kAudioFileMP3Type.

Отлично работает, проблема в том, что станция воспроизводит AAC, но не отправляет аудио / aacp как тип контента в заголовках HTTP. Когда это происходит, я обычно создаю поток аудиофайлов с помощью подсказки mp3 (ничто не отличается от 0 в качестве подсказки), а затем обратные вызовы свойств потока аудиофайлов указывают, что поток думает, что читает MP3, обратный вызов formatList никогда не происходит, и когда наступает время, когда создание аудио-очереди завершается неудачей.

Есть ли способ заставить AudioFileStream работать с AAC без передачи подсказки AAC в его конструкторе, или у кого-нибудь есть какие-либо идеи о том, как обнаружить эти станции, кроме как пометить их каким-либо образом в базах данных моих станций? Я также предпочел бы не пытаться создавать новый аудиофайл с AAC в качестве подсказки каждый раз, когда я терплю неудачу в обычном режиме.

1 Ответ

1 голос
/ 13 марта 2011

Я давно не смотрел этот код, но думаю, что он должен сработать.

// 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 impl:

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;
}
...