iOS (Objective-C)在AudioQueue中播放AAC文件的问题。

时间:2022-05-15 17:32:35

this is my first post here, I hope you can help me with this. I'm working on this code to get an AAC playback based on AudioQueue, I tested this with WAV format, and it works. The thing happens when I put either a .CAF or .M4A file and then I trigger the play method, this error comes up:

这是我的第一个帖子,希望你能帮我。我正在编写这个代码以获得基于AudioQueue的AAC回放,我用WAV格式测试了这个,并且它有效。当我输入。caf或。m4a文件然后触发播放方法时,这个错误就出现了:

ERROR: >aq> 1608: failed (-66674); will stop (66150/0 frames)

错误:>aq> 1608:失败(-66674);将停止(66150/0帧)

I've been searching for this error code -66674 on Apple's Dev support documents and says that I have an error involving a problem with AudioQueuePrime or AudioQueueStart (right now AudioQueuePrime is not on the code, but I've been testing this also). I know that it's possible to use AAC w/AudioQueues, and in my case I believe this is the most reliable way to sync sounds accurately.

我在苹果的Dev支持文档中搜索了这个错误代码-66674,并说我有一个错误,涉及到AudioQueuePrime或AudioQueueStart的问题(现在AudioQueuePrime不是在代码中,但是我也在测试它)。我知道使用AAC w/ audioqueue是可能的,在我的例子中,我认为这是最可靠的同步声音的方法。

- (IBAction)play:(id)sender {
    //OSStatus result;
    NSArray *audioTracks = [NSArray arrayWithObjects:
                            @"/Users/mauro_ptt/Documents/XCODE/SimpleAQPlayViewController/Sample01.caf",
                            nil];

    for (id object in audioTracks) {
    // Open the audio file from an existing NSString path
    NSURL *sndFileURL = [NSURL fileURLWithPath:object];

    AudioFileOpenURL((__bridge CFURLRef)sndFileURL, kAudioFileReadPermission, 0, &mAudioFile);

    // get audio format
    UInt32 dataFormatSize = sizeof(mDataFormat);
    AudioFileGetProperty(mAudioFile, kAudioFilePropertyDataFormat, &dataFormatSize, &mDataFormat);

    // create playback queue
    AudioQueueNewOutput(&mDataFormat, AQOutputCallback, (__bridge void *)(self), CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &mQueue);

    // get buffer size, number of packets to read
    UInt32 maxPacketSize;
    UInt32 propertySize = sizeof(maxPacketSize);
    // get the theoretical max packet size without scanning the entire file
    AudioFileGetProperty(mAudioFile, kAudioFilePropertyPacketSizeUpperBound, &propertySize, &maxPacketSize);
    // get sizes for up to 0.5 seconds of audio
    DeriveBufferSize(mDataFormat, maxPacketSize, 0.5, &bufferByteSize, &mNumPacketsToRead);

    // allocate packet descriptions array
    bool isFormatVBR = (mDataFormat.mBytesPerPacket == 0 || mDataFormat.mFramesPerPacket == 0);
    if (isFormatVBR) {
        mPacketsDescs = (AudioStreamPacketDescription*) malloc(mNumPacketsToRead * sizeof(AudioStreamPacketDescription));
    } else {
        mPacketsDescs = NULL;
    }

    // Get magic cookie (COMPRESSED AAC)
    UInt32 cookieSize = sizeof(UInt32);
    OSStatus couldNotGetProperty = AudioFileGetPropertyInfo(mAudioFile, kAudioFilePropertyMagicCookieData, &cookieSize, NULL);
    if ((couldNotGetProperty == noErr) && cookieSize) {
        char *magicCookie = (char *) malloc(cookieSize);
        AudioFileGetProperty(mAudioFile, kAudioFilePropertyMagicCookieData, &cookieSize, magicCookie);
        AudioQueueSetProperty(mQueue, kAudioQueueProperty_MagicCookie, magicCookie, cookieSize);
        free(magicCookie);
    }

    // Allocate and prime audio queue buffers
    mCurrentPacket = 0;
    for (int i=0; i < kNumberBuffers; ++i) {
        AudioQueueAllocateBuffer(mQueue, bufferByteSize, &mBuffers[i]);
        AQOutputCallback((__bridge void *)(self), mQueue, mBuffers[i]);
    }
        mIsRunning = true;
    AudioQueueStart(mQueue, NULL);

    }
}

Thanks in advance!

提前谢谢!

2 个解决方案

#1


1  

Was a problem regarding AQOutputCallback, must be careful on placing the right types on each function arguments.

关于AQOutputCallback的问题,必须小心在每个函数参数上放置正确的类型。

#2


0  

I had a similar issue a month ago and I couldn’t figured it out. So ended up using .wav. The size was bigger but luckily I only had to play 5 files.

一个月前我也有过类似的问题,但我想不出来。最后用。wav。尺寸更大,但幸运的是我只需要播放5个文件。

#1


1  

Was a problem regarding AQOutputCallback, must be careful on placing the right types on each function arguments.

关于AQOutputCallback的问题,必须小心在每个函数参数上放置正确的类型。

#2


0  

I had a similar issue a month ago and I couldn’t figured it out. So ended up using .wav. The size was bigger but luckily I only had to play 5 files.

一个月前我也有过类似的问题,但我想不出来。最后用。wav。尺寸更大,但幸运的是我只需要播放5个文件。