AudioDataPacketCount returns ValueUnknown

2019-07-25 01:39发布

I'm playing an AAC (kAudioFormatMPEG4AAC) file using iOS' Audio Queue Services. It's playing fine, so my code works.

Now I'm looking into seek functionality. For this I need the total number of audio packets. When my property-listener-proc receives a kAudioFileStreamProperty_ReadyToProducePackets I do:

UInt64   totalPackets;
UInt32   size = sizeof(totalPackets);
OSStatus status;

status = AudioFileStreamGetProperty(inAudioFileStream,
                                    kAudioFileStreamProperty_AudioDataPacketCount,
                                    &packetCountSize,
                                    &myData->totalPackets);

The issue is that AudioFileStreamGetProperty() returns kAudioFileStreamError_ValueUnknown (1970170687 when printed in the debugger).

Am I doing something wrong?

1条回答
叼着烟拽天下
2楼-- · 2019-07-25 01:45

It turned out that I was not doing something wrong at all.

I found that the iOS APIs don't supply this because this file format may contain fragments, each having their own packet count. Hence the total packet count for the file can't be know after having having read the first header.

However, in many audio files there is only one fragment, so it's a bit sad that iOS won't just supply the packet count it knows at at certain point (i.e. after reading the file header).

When working with AudioFileStreamSeek() I thought of the following to squeeze the information out of iOS:

- (SInt64)getTotalPacketCount
{
    OSStatus  status;
    UInt32    ioFlags    = 0;
    long long byteOffset = 0;
    SInt64    lower      = 0;
    SInt64    upper      = 1000000; // Large enough to fit any packet count.
    SInt64    current;              // Current packet count.

    // Binary search to highest packet count that has successful seek.
    while (upper - lower > 1 || status != 0)
    {
        current = (upper + lower) / 2;
        status = AudioFileStreamSeek(audioFileStream, current, &byteOffset, &ioFlags);

        if (status == 0)
        {
            lower = current;
        }
        else
        {
            upper = current;
        }
    }

    return current + 1; // Go from packet number to count.
}
查看更多
登录 后发表回答