Qt:如何在不阻塞主线程的情况下播放声音?

Posted

技术标签:

【中文标题】Qt:如何在不阻塞主线程的情况下播放声音?【英文标题】:Qt: How to play sound witout blocking main thread? 【发布时间】:2011-04-08 20:36:45 【问题描述】:

我想知道 Qt 中是否有一种简单的方法可以在不阻塞主线程的情况下播放声音?

我知道通常我应该启动一个单独的线程来执行此操作。但也许有捷径? :)

感谢您的帮助。

【问题讨论】:

【参考方案1】:

标准 QSound 和 Phonon 库在播放声音时都存在严重问题。它们都需要主消息循环,这意味着主线程中的轻微阻塞或播放声音的延迟。最终,他们都使用后台线程,但很容易注意到滞后。更不用说 Phonon 在许多平台上的支持存在问题。

我已经与这两者合作了一段时间,并尝试构建一个简单的声音系统来播放用户界面声音(只是偶尔发出哔哔声和弹出声)。使用标准 Qt 库是不可能的。

我建议使用 OpenAL,我最终也这样做了。这是一个相对简单的库,似乎有很好的跨平台支持。另一个选项是 SDL_mixer,但 OpenAL 似乎更容易在 Windows 上安装(虽然可能不是很多)。所以基本上,如果QSound::play 没有做你想做的事,那么标准的 Qt API 将不适合你。


另一个重要说明,不要费心尝试使用单独的线程修复 Qt 声音 api。它行不通。声子至少需要在主线程中被实例化和调用。

【讨论】:

+1 用于建议 OpenAL。早期版本的 SDL 很难集成到其他库的消息循环中。 QSound 对我来说很好用。很高兴了解 OpenAL,将来可能会有用。 我很高兴我没有尝试单独的线程路由。我无法在 Windows 上进行无缝播放,我考虑过使用 SDL。很高兴知道 OpenAL 也是一种选择。 为了将来参考,能否请您提供您使用的 Qt/OpenAL 版本,以及您测试的平台?【参考方案2】:

http://doc.qt.nokia.com/latest/qsound.html

Qt 提供了 GUI 应用程序中最常用的音频操作:异步播放声音文件。使用静态 play() 函数最容易做到这一点:

 QSound::play("mysounds/bells.wav");

这似乎是一个异步操作,所以它不应该阻塞你的主线程。

【讨论】:

请注意,这仅适用于声音文件,不适用于以编程方式生成的声音。前者可能是所有 OP 需要的,但后者我发现执行确实阻塞了 QAudioOutput::start()。【参考方案3】:

我一直在使用 QT 声音系统,尤其是线程问题。

这个解决方案对我有用:

    将任何 wav 转换为 mp3,因为在播放 wav 时存在问题 qt 5.5。 将这些 mp3 文件添加到 QT (qrc) 中的资源中。 使用 QMediaPlayer 播放声音。

例子:

http://doc.qt.io/qt-5/qtmultimediawidgets-player-player-cpp.html

https://www.youtube.com/watch?v=DS7CDpIrwN4

【讨论】:

【参考方案4】:

QMediaPlayer 不应阻塞您的线程。

#include <QtMultimedia/QMediaPlayer>

QMediaPlayer *player = new QMediaPlayer;
player->setMedia(QUrl::fromLocalFile("/path"));
player->setVolume(50);
player->play();

【讨论】:

以上是关于Qt:如何在不阻塞主线程的情况下播放声音?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不更改声音指示器的情况下在 iOS 中以最大音量播放声音文件

HTML:如何在不缓冲所有声音数据的情况下从 URL 中间文件开始声音播放

Naudio:如何在不停止所有其他声音的情况下正确删除 AsioOut 播放的几种声音中的一种?

在不导入自己的情况下播放系统声音

是否可以在不停止 iPod 音乐的情况下播放声音?

在单独的线程中播放短声音