Qt 播放音频文件的几种方式

Posted DreamLife.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 播放音频文件的几种方式相关的知识,希望对你有一定的参考价值。

文章目录


关键字: QtQSoundQSoundEffectQMediaPlayermultimedia

摘要

这篇文章至少拖了有一两个月了,这不阳了,在家实在是难受的要死,无心处理工作的事情,那就写写博客吧,因为项目中需要用到播放音频的功能,CV了部分代码,这里就简单的扯扯我对QSound QSoundEffect QMediaPlayer一点点浅陋的认知。

1 QMediaPlayer

官网描述

The QMediaPlayer class is a high level media playback class. It can be used to playback such content as songs, movies and internet radio. The content to playback is specified as a QMediaContent object, which can be thought of as a main or canonical URL with additional information attached. When provided with a QMediaContent playback may be able to commence.

我理解呢,就是说QMediaPlayer 是一个高级媒体播放类,它可以用于播放歌曲电影网络广播等内容。要播放的内容被指定为QMediaContent对象,可以将其视为带有附加新的主要或规范的URL,当提供QMediaContent时,就可以开始播放了。

1.1 播放音频文件

播放音频文件的话,这里贴一下官方的示例代码;

 player = new QMediaPlayer;
 connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
 player->setMedia(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3"));
 player->setVolume(50);
 player->play();

第一行,我们新建了一个QMediaPlayer对象;

第二行,我们将这个对象的位置改变信号连接到了位置改变的槽函数上

第三行,我们指定了我们音频文件的URL路径;

第四行,我们设置了播放器的音量为50 ;

第五行,开始播放音频文件。

1.2 播放视频文件

QVideoWidget can be used with QMediaPlayer for video rendering and QMediaPlaylist for accessing playlist functionality.

这里出现了一个新的类QVideoWidget ,官方描述说QVideoWidget 可以与QMediaPlayer 一起,用于视频渲染,与QMediaPlaylist 一起用于访问播放列表功能。同样,看下官方的示例代码。

 playlist = new QMediaPlaylist;
 playlist->addMedia(QUrl("http://example.com/movie1.mp4"));
 playlist->addMedia(QUrl("http://example.com/movie2.mp4"));
 playlist->addMedia(QUrl("http://example.com/movie3.mp4"));
 playlist->setCurrentIndex(1);
 player = new QMediaPlayer;
 player->setPlaylist(playlist);
 videoWidget = new QVideoWidget;
 player->setVideoOutput(videoWidget);
 videoWidget->show();
 player->play();

第一行,新建一个QMediaPlaylist对象,也就是播放列表对象;

第二行,第三行,第四行,分别向播放列表中加入视频文件;

第五行,把播放列表的当前索引值设置为1,也就是默认播放第二个视频(这里不确定哈);

第六行,新建一个QMediaPlayer对象;

第七行,给QMediaPlayer对象设置播放列表;

第八行,新建一个QVideoWidget对象,用于视频渲染;

第九行,设置QMediaPlayer的视频输出对象,就是我们第八行新建的视频渲染窗口;

第十行,显示QVideoWidget视频渲染窗口;

第十一行,开始播放。

1.3 我遇到的问题

这里说说我遇到的问题,我开始的需求是用QMediaPlayer来播放wav音频文件,当做提示音的,就是那种按钮按下的信息,警告信息啥的,这类音频好像被统称为提示音。但是呢,我遇到的问题主要就是延迟问题,就是总感觉这个音频播放的是慢半拍,开始以为是我音频文件问题,有淡入和淡出。处理了音频文件后,问题并没有太多的改善,尽管研究QMediaPlayer的时候,发现有一个低延迟的参数,但是好像还是不咋理想。

2 QSound

Qt provides the most commonly required audio operation in GUI applications: asynchronously playing a sound file. This is most easily accomplished using the static play() function:

Qt 提供了 GUI 应用程序中最常需要的音频操作:异步播放声音文件。 使用静态 play() 函数最容易实现这一点。粗略看,就是播放音频文件的一个简单类。可以直接使用静态函数play()播放音频。

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

另一种,就是创建一个QSound对象,完了再调用play函数来播放音频。

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

这个类我没有具体使用过,其他的信息也没有啥有价值的经验分享。但是我在扒拉这个类的时候,发现了一个应该可以解决我问题的新类,如下图

它说,如果我想更好的控制播放声音,请考虑QSoundEffect或者QAudioOutput;QAudioOutput咱没用过,但是QSoundEffect看着比较对口味。所以我有扒拉了扒拉QSoundEffect

3 QSoundEffect

This class allows you to play uncompressed audio files (typically WAV files) in a generally lower latency way, and is suitable for “feedback” type sounds in response to user actions (e.g. virtual keyboard sounds, positive or negative feedback for popup dialogs, or game sounds). If low latency is not important, consider using the QMediaPlayer class instead, since it supports a wider variety of media formats and is less resource intensive.

这个官方描述中就直接说了,此类允许您以通常较低的延迟方式播放未压缩的音频文件(通常是 WAV 文件),并且适用于响应用户操作的“反馈”类型声音(例如虚拟键盘声音、弹出对话框的正面或负面反馈,或 游戏声音)。 如果低延迟不重要,请考虑改用 QMediaPlayer 类,因为它支持更广泛的媒体格式并且占用资源更少。

所以这会终于找对了。

 QSoundEffect effect;
 effect.setSource(QUrl::fromLocalFile("engine.wav"));
 effect.setLoopCount(QSoundEffect::Infinite);
 effect.setVolume(0.25f);
 effect.play();

用法基本大差不差,

第一行,新建一个QSoundEffect对象;

第二行,设置资源文件路径;

第三行,设置循环次数(这里就是无限循环);

第四行,设置音量,这里要看下,和前面的数量级不一样,这个是0-1;

第五行,播放音频

这个代码改完了,在项目中使用还是有不错的效果的,建议有遇到的小伙伴,可以尝试一下。

4 QAudioOutput

You can construct an audio output with the system’s default audio output device. It is also possible to create QAudioOutput with a specific QAudioDeviceInfo. When you create the audio output, you should also send in the QAudioFormat to be used for the playback (see the QAudioFormat class description for details).

这个更没有使用过了,不过看文档描述,感觉这个应该是更接近底层的播放类,可以设置更多的音频参数,官方描述说是:您可以使用系统默认的音频输出设备构建音频输出。 也可以使用特定的 QAudioDeviceInfo 创建 QAudioOutput。 创建音频输出时,还应发送用于播放的 QAudioFormat(有关详细信息,请参阅 QAudioFormat 类描述)。和面有用到再做详细解释。

官方示例代码如下:

 QFile sourceFile;   // class member.
 QAudioOutput* audio; // class member.
 
     sourceFile.setFileName("/tmp/test.raw");
     sourceFile.open(QIODevice::ReadOnly);

     QAudioFormat format;
     // Set up the format, eg.
     format.setSampleRate(8000);
     format.setChannelCount(1);
     format.setSampleSize(8);
     format.setCodec("audio/pcm");
     format.setByteOrder(QAudioFormat::LittleEndian);
     format.setSampleType(QAudioFormat::UnSignedInt);

     QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
     if (!info.isFormatSupported(format)) 
         qWarning() << "Raw audio format not supported by backend, cannot play audio.";
         return;
     

     audio = new QAudioOutput(format, this);
     connect(audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));
     audio->start(&sourceFile);
 

以上是关于Qt 播放音频文件的几种方式的主要内容,如果未能解决你的问题,请参考以下文章

Android播放音频的几种方式介绍

Android播放音频MediaPlayer的几种方式介绍

用 Qt 的 QAudioOutput 类播放 WAV 音频文件

官方认可的从 Qt5.x 下的资源播放音频的方式

几种播放音频文件的方式(十三) —— OpenAL框架之分步解析

用 Qt 的 QAudioOutput 类播放 WAV 音频文件(使用了libsndfile外部库)