Qt播放音频,支持进度条,设置语速,播放暂停
原需求:
需要实现文字转语音功能,最开始采用的技术方法是QTextToSpeech,但是无法获取进度,导致出现很多的问题。
后面就改了方案,使用Windows自带的SAPI将文字转为音频,保存本地。
然后使用QMediaPlayer来播放音频。
QMediaPlayer比较强大,支持所有的需求(进度条、播放、暂停、继续播放、设置语速、设置音量)
Demo:
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QDebug> #include <QMediaPlayer> #include <QMediaPlaylist> #include <QDir> #include <QStandardPaths> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); public slots: void fn_play(); void fn_test(); void fn_setRate(int rate); void fn_position(qint64 pos); void fn_duration(qint64 duration); private: Ui::Widget *ui; QMediaPlayer* player = nullptr; }; #endif // WIDGET_H
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // 加载本地音频文件(不支持mp3,支持wmv) QString dir_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); QString file_path = dir_path + "/1.wmv"; player = new QMediaPlayer; player->setMedia(QUrl::fromLocalFile(file_path)); connect(player, &QMediaPlayer::durationChanged, this, &Widget::fn_duration); connect(player, &QMediaPlayer::positionChanged, this, &Widget::fn_position); connect(ui->radioButton, &QRadioButton::clicked, this, [=](){fn_setRate(0);}); connect(ui->radioButton_2, &QRadioButton::clicked, this, [=](){fn_setRate(1);}); connect(ui->radioButton_3, &QRadioButton::clicked, this, [=](){fn_setRate(2);}); connect(ui->pushButton, &QPushButton::clicked, this, &Widget::fn_bofang); connect(ui->pushButton_2, &QPushButton::clicked, this, &Widget::fn_test); } Widget::~Widget() { delete ui; } void Widget::fn_bofang() { if(player->state() == QMediaPlayer::StoppedState){ player->play(); } else if(player->state() == QMediaPlayer::PlayingState){ player->pause(); } else if(player->state() == QMediaPlayer::PausedState){ player->play(); } } void Widget::fn_test() { qDebug() << "rate:" << player->playbackRate(); qDebug() << "state:" << player->state(); } void Widget::fn_setRate(int rate) { if(rate == 0 ){player->setPlaybackRate(0.8);} if(rate == 1 ){player->setPlaybackRate(1.0);} if(rate == 2 ){player->setPlaybackRate(1.2);} } void Widget::fn_position(qint64 pos) { qDebug() << "pos:" << pos; ui->horizontalSlider->setValue(pos); } void Widget::fn_duration(qint64 duration) { qDebug() << "duration:" << duration; ui->horizontalSlider->setMinimum(0); ui->horizontalSlider->setMaximum(duration); }
我的实际项目是根据QTextEdit的文字转的语音,QTextEdit的文字改变后,需要重新生成音频,播放新的音频。
播放新的音频,需要先把Media置空,然后在设置新的音频,这样才能生效,不然一直播放的是之前的音频。
if(player->state() == QMediaPlayer::StoppedState) { player->stop(); player->setMedia(QMediaContent()); QString file_name = QDir::tempPath() + "/tts.wmv"; if(QFile::exists(file_name)) { bool ret = QFile::remove(file_name); qDebug() << "remove:" << ret; } QString file_path = fn_textToAudio(true); player->setMedia(QUrl::fromLocalFile(file_path)); player->play(); }


浙公网安备 33010602011771号