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();
    }

 

posted @ 2025-07-28 19:59  十一的杂文录  阅读(52)  评论(0)    收藏  举报