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

Posted

技术标签:

【中文标题】iOS(Objective-C)在AudioQueue中播放AAC文件的问题【英文标题】:Problems on iOS (Objective-C) playing AAC files in AudioQueue 【发布时间】:2014-02-23 00:53:09 【问题描述】:

这是我在这里的第一篇文章,希望你能帮助我。我正在编写此代码以获取基于 AudioQueue 的 AAC 播放,我使用 WAV 格式对其进行了测试,并且可以正常工作。当我放置 .CAF 或 .M4A 文件然后触发播放方法时会发生这种情况,出现此错误:

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

我一直在 Apple 的开发支持文档中搜索此错误代码 -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);

    

提前致谢!

【问题讨论】:

你们是如何实现AQOutputCallback的? 我刚刚解决了。这是关于 AQOutputCallback 放置对象而不是结构的问题,谢谢! 【参考方案1】:

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

【讨论】:

我正在开发一个远程桌面应用程序,渲染视频和音频并分别发送数据尝试使用音频队列服务进行同步,也达到了结果,但它在声音中出现了故障,使用 AudioQueueReset 与同步声音视频但出现故障。任何帮助将不胜感激!【参考方案2】:

一个月前我遇到了类似的问题,但我想不通。所以最终使用.wav。尺寸更大,但幸运的是我只需要播放 5 个文件。

【讨论】:

以上是关于iOS(Objective-C)在AudioQueue中播放AAC文件的问题的主要内容,如果未能解决你的问题,请参考以下文章

在 OS X (Objective-C) 和 iOS (Swift) 之间共享代码

如何从Javascript调用Objective-C方法并将数据发送回iOS中的Javascript?

如何在 iOS 13 Objective-c 中处理鼠标事件

iOS/Objective-C:在后台线程中保存到核心数据

iOS 上的 Objective-C 套接字发送和接收

如何通过NEHotspotHelper获取WiFi列表(IOS,objective-c)