[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();
}
相关推荐
启雀AI9 小时前
AI 驱动的视频课程自动摘要与知识点提取:ASR + LLM 流水线工程实践
人工智能·阿里云·华为云·音视频·培训saas平台
FinelyYang11 小时前
基于 LiveKit 实现一对一视频通话:从信令到媒体进房的完整实践
音视频·媒体
程序员老陆18 小时前
M3U8(HLS 索引协议)深度详解:它不存一帧画面,却指挥了整个互联网视频
音视频·hls·m3u8
雪的季节18 小时前
音视频(51-52)
音视频
hz5678919 小时前
视频会议终端品牌如何选择?主流产品特点与选型标准
安全·音视频·实时音视频·信息与通信
NutShell Wang21 小时前
国产全模态开源潮:从语言模型到视频模型,中国开源生态再升级
人工智能·语言模型·开源·大模型·音视频·多模态·vibe coding
民乐团扒谱机1 天前
【读论文】复调音乐信号的主旋律提取:方法、应用与挑战
开发语言·人工智能·算法·音视频·音乐
byte轻骑兵1 天前
【AVDTP】规范精讲[8-3]: 流配置核心三步:从参数下发到动态重配置全拆解
音视频·avrcp·蓝牙耳机·蓝牙车机·蓝牙音频控制
微帧Visionular1 天前
GenOpt像素智绘引擎|AI生成视频需要怎样的视觉优化算法?
人工智能·aigc·音视频
杀生丸学AI2 天前
【世界模型】MotionForesight:视频模型应用于未来的三维场景流预测
音视频