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號