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

iOS(Objective-C)在AudioQueue中播放AAC文件时出现的问题,ios,objective-c,audioqueue,audioqueueservices,Ios,Objective C,Audioqueue,Audioqueueservices,这是我在这里的第一篇文章,我希望你能帮助我。我正在编写这段代码,以获得一个基于AudioQueue的AAC播放,我用WAV格式测试了它,它工作正常。当我放入.CAF或.M4A文件,然后触发播放方法时,会出现以下错误: 错误:>aq>1608:失败(-66674);将停止(66150/0帧) 我一直在苹果的开发支持文档中搜索这个错误代码-66674,并说我有一个错误,涉及AudioQueuePrime或AudioQueueStart的问题(目前AudioQueuePrime不在代码中,但我也一直在

这是我在这里的第一篇文章,我希望你能帮助我。我正在编写这段代码,以获得一个基于AudioQueue的AAC播放,我用WAV格式测试了它,它工作正常。当我放入.CAF或.M4A文件,然后触发播放方法时,会出现以下错误:

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

我一直在苹果的开发支持文档中搜索这个错误代码-66674,并说我有一个错误,涉及AudioQueuePrime或AudioQueueStart的问题(目前AudioQueuePrime不在代码中,但我也一直在测试)。我知道使用AAC和音频队列是可能的,就我而言,我相信这是准确同步声音最可靠的方法

- (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);

    }
}
-(iAction)播放:(id)发送方{
//骨状态结果;
NSArray*audioTracks=[NSArray arrayWithObjects:
@“/Users/mauro_ptt/Documents/XCODE/SimpleAQPlayViewController/Sample01.caf”,
零];
用于(音频曲目中的id对象){
//从现有NSString路径打开音频文件
NSURL*sndFileURL=[NSURL fileURLWithPath:object];
AudioFileOpenURL((uu桥CFURLRef)sndFileURL、kAudioFileReadPermission、0和mAudioFile);
//获取音频格式
UInt32 dataFormatSize=sizeof(mDataFormat);
AudioFileGetProperty(mAudioFile、kAudioFilePropertyDataFormat、dataFormatSize和mDataFormat);
//创建播放队列
AudioQueueNewOutput(&mDataFormat,AQOutputCallback,(uu桥空*)(self),CFRunLoopGetCurrent(),kCFRunLoopCommonModes,0,&mQueue);
//获取缓冲区大小、要读取的数据包数
UInt32最大包装尺寸;
UInt32 propertySize=sizeof(maxPacketSize);
//在不扫描整个文件的情况下获取理论上的最大数据包大小
AudioFileGetProperty(mAudioFile、kAudioFilePropertyPacketSizeUpperBound、propertySize和maxPacketSize);
//获取最多0.5秒音频的大小
DeriveBufferSize(mDataFormat、maxPacketSize、0.5、&bufferByteSize和mNumPacketsToRead);
//分配数据包描述数组
bool isFormatVBR=(mDataFormat.mBytesPerPacket==0 | | mDataFormat.mFramesPerPacket==0);
if(isFormatVBR){
mPacketsDescs=(AudioStreamPacketDescription*)malloc(mNumPacketsToRead*sizeof(AudioStreamPacketDescription));
}否则{
mPacketsDescs=NULL;
}
//获取魔法饼干(压缩AAC)
UInt32 cookieSize=尺寸of(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);
免费(magicCookie);
}
//分配和初始化音频队列缓冲区
mcurrentpack=0;
对于(int i=0;i

提前谢谢

一个月前,我也遇到过类似的问题,但我无法解决。所以最终使用了.wav。大小更大,但幸运的是我只需要播放5个文件。

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

您是如何实现的
AQOutputCallback
?我刚刚解决了它。这是一个关于AQOutputCallback放置对象而不是结构的问题,谢谢!我正在开发一个远程桌面应用程序,渲染视频和音频并分别发送数据,尝试使用音频队列服务进行同步,也取得了效果,但它在声音方面出现了故障,使用AudioQueueReset将声音与视频同步,但出现了故障。任何帮助都将不胜感激!