[QtCPP]Examples使用示例-(2)QtMultimedia Audio音频引擎测试mp3播放【linux/win】

core_audio文件夹

audioprompt.cpp
cpp 复制代码
#include "audioprompt.h"
#include <QUrl>
#include <QDebug>
#include <QFileInfo>

AudioPrompt *AudioPrompt::m_instance = nullptr;

void AudioPrompt::setDebugEnabled(bool enabled)
{
    m_debugEnabled = enabled;
}

void AudioPrompt::setProgressPrintEnabled(bool enabled)
{
    m_progressPrintEnabled = enabled;
}

AudioPrompt *AudioPrompt::instance()
{
    if (!m_instance) {
        m_instance = new AudioPrompt();
    }
    return m_instance;
}

AudioPrompt::AudioPrompt(QObject *parent) : QObject(parent)
{
    m_player = new QMediaPlayer(this);
    m_playlist = new QMediaPlaylist(this);

    m_playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
    m_player->setPlaylist(m_playlist);

    connect(m_player, &QMediaPlayer::currentMediaChanged, this, &AudioPrompt::onCurrentMediaChanged);

    m_progressTimer = new QTimer(this);
    m_progressTimer->setInterval(1000);
    connect(m_progressTimer, &QTimer::timeout, this, &AudioPrompt::printProgress);

    connect(m_player, &QMediaPlayer::stateChanged, this, [this](QMediaPlayer::State state){
        if (state == QMediaPlayer::PlayingState) {
            m_progressTimer->start();
        } else {
            m_progressTimer->stop();
        }
    });
}

void AudioPrompt::play(const QString &filePath)
{
    QFileInfo fileInfo(filePath);
    if (!fileInfo.exists()) {
        if (m_debugEnabled) qWarning() << "文件不存在:" << filePath;
        emit errorOccurred(QString("文件不存在: %1").arg(filePath));
        return;
    }

    m_playlist->clear();
    QUrl url = QUrl::fromLocalFile(fileInfo.absoluteFilePath());
    m_playlist->addMedia(url);
    m_playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
    m_playlist->setCurrentIndex(0);

    if (m_debugEnabled) qDebug() << "开始播放:" << fileInfo.fileName();
    m_player->play();
    emit playbackStarted(filePath);
}

void AudioPrompt::stop()
{
    m_player->stop();
    if (m_debugEnabled) qDebug() << "停止播放";
    emit playbackStopped();
}

void AudioPrompt::onCurrentMediaChanged(const QMediaContent &media)
{
    if (!media.isNull()) {
        if (m_debugEnabled) qDebug() << "\n切换播放文件:" << media.request().url().fileName();
    }
}

void AudioPrompt::printProgress()
{
    if (!m_progressPrintEnabled) return;
    if (m_player->state() == QMediaPlayer::PlayingState) {
        qint64 position = m_player->position();
        qint64 duration = m_player->duration();
        if (duration > 0) {
            qDebug() << "正在播放:" << m_player->currentMedia().request().url().fileName()
                     << "| 时间:" << formatTime(position) << "/" << formatTime(duration);
        }
    }
}

QString AudioPrompt::formatTime(qint64 milliseconds)
{
    qint64 seconds = milliseconds / 1000;
    qint64 mins = seconds / 60;
    qint64 secs = seconds % 60;
    return QString("%1:%2")
            .arg(mins, 2, 10, QChar('0'))
            .arg(secs, 2, 10, QChar('0'));
}
audioprompt.h
cpp 复制代码
#ifndef AUDIOPROMPT_H
#define AUDIOPROMPT_H

#include <QObject>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QMediaContent>
#include <QTimer>

class AudioPrompt : public QObject
{
    Q_OBJECT

public:
    static AudioPrompt *instance();

    void play(const QString &filePath);
    void stop();
    void setDebugEnabled(bool enabled);
    void setProgressPrintEnabled(bool enabled);

signals:
    void playbackStarted(const QString &filePath);
    void playbackStopped();
    void errorOccurred(const QString &error);

private:
    AudioPrompt(QObject *parent = nullptr);
    AudioPrompt(const AudioPrompt &) = delete;
    AudioPrompt &operator=(const AudioPrompt &) = delete;

private slots:
    void onCurrentMediaChanged(const QMediaContent &media);

private:
    void printProgress();
    QString formatTime(qint64 milliseconds);

private:
    static AudioPrompt *m_instance;
    QMediaPlayer *m_player;
    QMediaPlaylist *m_playlist;
    QTimer *m_progressTimer;
    bool m_debugEnabled = true;//控制所有调试信息
    bool m_progressPrintEnabled = true;//仅仅控制正在播放的调试信息
};

#endif // AUDIOPROMPT_H
core_audio.pri
cpp 复制代码
INCLUDEPATH += $$PWD

HEADERS += \
    $$PWD/audioprompt.h

SOURCES += \
    $$PWD/audioprompt.cpp

linux {

}

.pro

bash 复制代码
QT += multimedia

#音频
include ($$PWD/core_audio/core_audio.pri)

main.cpp

cpp 复制代码
#include "audioprompt.h" //引入音频播放提示 头文件  

int main(int argc, char *argv[]){


   QApplication a(argc, argv);

//调用测试
    AudioPrompt::instance()->play("F:/QTcode/test/audio/testaudio/rkaudiov1/v2package/不将就.mp3");
   //AudioPrompt::instance()->play("/data/mjt/test/testaudio/v1/bin/不将就.mp3");   // /data/mjt/test/testaudio/v1/bin/不将就.mp3
    QTimer::singleShot(20000, [&a](){
        qDebug() << "20秒到,执行停止...";
        AudioPrompt::instance()->stop();
        //QTimer::singleShot(500, [&a](){ a->quit(); });
    });

}

ui_main.cpp

cpp 复制代码
//#include "audioprompt.h" //引入音频播放提示 头文件 

// 第二阶段设置:在 QApplication 创建后调用
bool ui_Setup(QApplication *app, QQuickView *view)
{

    AudioPrompt::instance()->play("F:/QTcode/test/audio/testaudio/rkaudiov1/v2package/不将就.mp3");
    //AudioPrompt::instance()->play("/data/mjt/test/testaudio/v1/bin/不将就.mp3");   // /data/mjt/test/testaudio/v1/bin/不将就.mp3
    QTimer::singleShot(20000, [&app](){
        qDebug() << "20秒到,执行停止...";
        AudioPrompt::instance()->stop();
        //QTimer::singleShot(500, [&app](){ app->quit(); });
    });

//。。。。。。。

}

添加中转信号:

qmlcppintermedium.h(添加槽声明)
cpp 复制代码
#ifndef QMLCPPINTERMEDIUM_H
#define QMLCPPINTERMEDIUM_H

#include <QObject>
#include "audioprompt.h"  // 新增:包含 AudioPrompt 头文件

class QmlCppIntermedium : public QObject
{
    Q_OBJECT
public:
    static QmlCppIntermedium* instance();
    // ... 其他现有声明 ...

public slots:
    // ... 其他现有槽 ...
    Q_INVOKABLE void setAudioPath(const QString &filePath);  // 新增:设置音频路径+文件
    Q_INVOKABLE void stopAudio();                          // 新增:停止音频播放
};

#endif // QMLCPPINTERMEDIUM_H
qmlcppintermedium.cpp(实现槽逻辑)
cpp 复制代码
qmlcppintermedium.cpp(实现槽逻辑)
cpp 复制代码
#include "qmlcppintermedium.h"
#include "audioprompt.h"  // 确保包含 AudioPrompt 头文件

// ... 其他现有代码 ...

// 实现 setAudioPath 槽:调用 AudioPrompt 播放音频
void QmlCppIntermedium::setAudioPath(const QString &filePath) {
    AudioPrompt::instance()->play(filePath);
}

// 实现 stopAudio 槽:调用 AudioPrompt 停止播放
void QmlCppIntermedium::stopAudio() {
    AudioPrompt::instance()->stop();
}

// ... 其他现有代码 ...
main.cpp(替换原有调用)
cpp 复制代码
#include "ui_main.h"
#include <QQuickView>
#include <QApplication>
#include "datamiddlelayer.h"
#include "data_sender.h"
#include "qmlcppintermedium.h"
#include <QTimer>
#include "audioprompt.h"  // 可选:若需直接调用 AudioPrompt,保留;否则可移除

int main(int argc, char *argv[]) {
    // ... 其他现有代码 ...

    // 替换为 QmlCppIntermedium 调用
    QmlCppIntermedium::instance()->setAudioPath("/data/mjt/test/testaudio/v1/bin/不将就.mp3");
    
    QTimer::singleShot(20000, [&a](){
        qDebug() << "20秒到,执行停止...";
        QmlCppIntermedium::instance()->stopAudio();  // 调用 stopAudio 槽
        QTimer::singleShot(500, [&a](){ a->quit(); });
    });

    // ... 其他现有代码 ...
    return a.exec();
}
相关推荐
RTC实战笔记1 天前
实时互动数字人怎么做,才不是一个只会说话的视频?
音视频·数字人·rtc·数字人接入
RTC实战笔记13 天前
Android 实时音视频接入教程:媒体补充增强信息(SEI)
音视频·媒体·rtc
潜创微科技14 天前
HDMI1.3 无线传输芯片方案 空旷 150 米量产级音视频方案
音视频
VidDown14 天前
VidDown 工具站:免费、本地优先的开发者工具箱
javascript·编辑器·音视频·视频编解码·视频
换个昵称都难14 天前
音频格式之WAV
音视频
AI创界者14 天前
PilotTTS 一键整合包(Win/Mac):8G 显存畅跑,实测解锁情绪与副语言的精准控制
人工智能·macos·aigc·音视频
u1521096484914 天前
S.S.Audio PRO A2音频隔离器
嵌入式硬件·音视频·实时音视频·视频编解码·视频
VidDown14 天前
显卡处理视频技术详解:从硬解码到 NVENC,GPU 如何让视频处理起飞?
javascript·编辑器·音视频·视频编解码·视频
EasyDSS14 天前
全能音视频平台/私有化音视频系统EasyDSS!直播/点播/会议/集群对讲一站式落地
音视频
Damon_X14 天前
车载音频复习
音视频