AudioQueue PropertyListener IsRunning 只回调一次

Posted

技术标签:

【中文标题】AudioQueue PropertyListener IsRunning 只回调一次【英文标题】:AudioQueue PropertyListener IsRunning only callback once 【发布时间】:2012-11-13 06:48:41 【问题描述】:
 OSStatus err = AudioQueueNewOutput(&audioDescription, AudioPlayerAQOutputCallback, ( void* )self, nil, nil, 0, &audioQueue);
    if( err != noErr )
        NSLog(@"Couldn't open AudioFile.");

    err = AudioQueueAddPropertyListener(audioQueue, kAudioQueueProperty_IsRunning, isRunningProc, self);
    if( err != noErr )
        NSLog(@"Couldn't register for playback state changes.");

这个回调函数只在AudioQueueStart(audioQueue, NULL);之后调用一次

我所说的 AudioQueuePause(audioQueue);

或音频到达终点。

static void isRunningProc(void *              inUserData,
                      AudioQueueRef           inAQ,
                      AudioQueuePropertyID    inID)

我错过了什么?

【问题讨论】:

【参考方案1】:

我对此做了一个简短的测试:

当您恢复暂停时,它确实看起来像回调,无论是暂停还是开始都不会调用它。

但这不是您无法解决的问题。你以某种方式开始了这首歌。这将触发属性监听器。同样,如果歌曲停止。或者你阻止它。您可能必须在播放例程中以某种方式自己触发属性侦听器:

if (bytesRead == 0) 
    //This will trigger the property listener
    AudioQueueStop(inAQ, false);

else 
    AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);

就 AudioQueue 而言,只要您不断向它提供音频缓冲区以供播放,它就会一直在播放。 (我还测试了根本不提供任何缓冲区,这不会触发停止,因此您必须显式调用停止来触发属性侦听器。)

这意味着您已经知道您的歌曲是否正在播放。通过单击您的按钮请求暂停或取消暂停。如果歌曲没有播放,不要做任何事情。如果歌曲正在播放,请调用 AudioQueuePause 并设置一个您已暂停音乐的标志。记得检查错误代码。 (见下文(1))。如果标志表明您已暂停音乐,请调用 AudioQueueStart,并清除表明您是否已暂停的标志。再次检查错误代码。

(1) 为什么要检查错误码?

首先,虽然不太可能,但可能会发生错误,因为它是蓝月亮。

但是,我担心的是多个线程。 AudioQueue 显然在与您的 GUI 不同的线程上运行。这意味着如果你测试一个标志是否正在播放音乐,这个状态不能完全被信任,因为它可能在你测试状态后发生了变化。另一个线程可能在您的测试和基于该测试的操作之间潜入。

假设您检查歌曲是否已经在播放。 (这是。) 然后你要求歌曲暂停,但歌曲真的停止了,因为在你要求歌曲暂停之前它已经到了结尾。 然后你要求暂停这首歌。但它已经停止了。

然后会发生什么?我真的不知道。在这种情况下,它甚至可能不是问题,但这样的事情值得考虑。它需要测试,或者至少需要查阅文档。

另外一个场景怎么样?如果歌曲停止了,而您要求重新开始,该怎么办。我认为这是一个更糟糕的情况,但这可能不是问题。再次考虑这些情况并检查文档,甚至自己测试。

【讨论】:

以上是关于AudioQueue PropertyListener IsRunning 只回调一次的主要内容,如果未能解决你的问题,请参考以下文章

AudioQueue 不起作用 Window Miniaturize

AudioQueue 样本值错误

iOS AudioQueue播放AAC数据总是延迟2-3秒

ios音频:使用audioqueue改变播放进度

AudioQueue 如何从 CallBack 读取缓冲区

iOS:使用 AudioQueue 时快进音频