[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();
}
相关推荐
镭封13 分钟前
短剧多人对白怎么配?一人完成多角色配音的办法
人工智能·音视频·语音识别·媒体
技灵AI2 小时前
Wan 3.0 API怎么做多参考商品视频?从图片、视频、音频分工到30秒交付
人工智能·prompt·aigc·音视频·wan 3.0
赛博仓鼠3 小时前
MiniMax H3 实测:8GB显存跑2K视频+原生音频,开源视频生成的新卷王
开源·aigc·音视频
byte轻骑兵4 小时前
【LE Audio】PBP精讲[4]: 公共广播通告的设计逻辑与数据交互流程
人工智能·音视频·le audio·低功耗蓝牙音频
hz567895 小时前
手术室视频示教系统解决方案:让临床教学突破空间限制
安全·音视频·实时音视频·信息与通信·智能硬件
可乐鸡翅yeah_6 小时前
混合内容 Mixed‑Content 安全策略,HLS HTTPS 页面加载 HTTP 资源排错实战
运维·ffmpeg·音视频·媒体·m3u8
揽秀亭长8 小时前
音轨分离处理方案及效果测试分析
人工智能·音视频
美狐美颜SDK开放平台9 小时前
直播APP如何兼顾画质与低延迟?视频美颜SDK性能优化开发思路
人工智能·深度学习·音视频·美颜sdk·第三方美颜sdk
山顶夕景10 小时前
【VLM】Qwen3.8-Omni-Flash长音视频理解Agentic模型
音视频·vlm·视频理解·agentic·全模态
tedcloud12311 小时前
emilkowalski/skills:让 AI 写出来的网页更有“设计感”
服务器·人工智能·开源·音视频·ai编程