AudioQueueStop 后音频队列无法重新启动

Posted

技术标签:

【中文标题】AudioQueueStop 后音频队列无法重新启动【英文标题】:Audio Queue cannot start again after AudioQueueStop 【发布时间】:2013-09-07 21:38:00 【问题描述】:

我可以设置一个音频队列进行录制,AudioQueueStart 可以很好地开始录制。

但是在调用AudioQueueStop之后,我发现同样的Audio Queue不能再启动了,我需要创建一个新的Audio Queue和Buffers来再次开始录制。

停止后是否可以重复使用相同的音频队列?

谢谢。

【问题讨论】:

【参考方案1】:

我遇到了同样的问题。仔细研究文档并没有发现有关此问题根源的任何线索,但查看示例代码所有记录队列仅使用一次 - 没有迹象表明它们可以重复使用。

文档中的唯一提示是 AudioQueueStart 用于在使用 AudioQueuePause 暂停队列后RESUME

似乎录音队列是为一次性使用而设计的,需要在最后处理 (AudioQueueDispose) 并为任何后续录音重新创建。

【讨论】:

【参考方案2】:

尽管没有任何文档,但似乎确实有办法做到这一点。

需要确保在异步调用AudioQueueStop之后,任何仍在队列中的数据都得到妥善处理。

因此,在停止录制的调用中,我们有一个状态变量 (recordingState) 来跟踪正在发生的事情。鉴于此函数和回调在不同的线程中执行,我们尝试通过同步到当前类(在本例中称为 Listener)来避免任何可能的复杂性:

-(void) stopRecording

    @synchronized(self)
    
        if(self.recordingState != RecordingStateRunning) return;

        self.recordingState = RecordingStateStopping;
        AudioQueueStop(self.audioQueue, false);
    

实验表明,异步调用AudioQueueStop(即参数inImmediate设置为false)后,回调会被多调用几次,所以我们有机会整理一下:

static void AQInputCallback(void *inUserData,
                        AudioQueueRef inAQ,
                        AudioQueueBufferRef inBuffer,
                        const AudioTimeStamp *inStartTime,
                        UInt32 inNumberPacketDescriptions,
                        const AudiostreamPacketDescription *inPacketDescs)

    Listener *listener = (__bridge Listener *) inUserData;

    @synchronized(listener)
    
        if(listener.recordingState == RecordingStateRunning)
        
            // Do audio processing here.
            // ...
        
        else if(listener.recordingState == RecordingStateStopping)
        
            listener.recordingState = RecordingStateStopped;

            // Do tidying here.
            // ...
        

        AudioQueueEnqueueBuffer(listener.audioQueue, inBuffer, 0, NULL);
    

【讨论】:

以上是关于AudioQueueStop 后音频队列无法重新启动的主要内容,如果未能解决你的问题,请参考以下文章

停止并快速重放 AudioQueue

播放流后音频队列无法录制音频

关闭并重新打开我的应用程序后无法从 URI 播放音频

iPhone XCode 在后台时无法重新激活音频捕获会话

exchange邮件服务器队列queue大小有限制吗

iOS利用FFmpeg解码音频数据并播放