最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt6替代廢棄QMediaPlaylist的解決方案

 更新時間:2026年04月16日 09:11:21   作者:ol木子李lo  
本文介紹了一種自定義的Qt6多媒體播放列表類,以兼容Qt6的新多媒體架構(gòu),該類支持三種播放模式,并自動綁定QMediaPlayer,實現(xiàn)了自動切換媒體的功能,作者還提供了代碼實現(xiàn),并通過實際項目中的BGMControl類進(jìn)行了集成示例,需要的朋友可以參考下

—— 之前使用Qt5,如今使用Qt6發(fā)現(xiàn)在Qt6里QMediaPlaylist已廢棄,所以網(wǎng)上搜了一下,找到了該博主的博客,感想博主的代碼,我在其基礎(chǔ)上增加和修改,以適配Qt5的寫法。

一、背景:Qt6 多媒體模塊的重大變更

Qt5 中常用的 QMediaPlaylist 類在 Qt6 中被正式移除,這給大量依賴該類實現(xiàn)音頻 / 視頻播放列表管理的項目帶來了兼容性問題。尤其對于棋牌、影音類應(yīng)用(如本文的斗地主項目),播放列表是核心功能模塊,急需一套輕量、兼容、易集成的替代方案。

本文基于實際項目經(jīng)驗,從零實現(xiàn)了一套 Qt6 專屬的 MediaPlaylist 類,完全復(fù)刻 QMediaPlaylist 核心能力,同時適配 Qt6 新的多媒體架構(gòu)(QMediaPlayer + QAudioOutput),解決音頻播放列表、循環(huán)切歌、播放模式控制等核心需求。

二、核心痛點分析

遷移 Qt5 音頻播放邏輯到 Qt6 時,主要面臨以下問題:

  1. QMediaPlaylist 直接移除,無官方替代類;
  2. Qt6 多媒體架構(gòu)調(diào)整,QMediaPlayer 需手動綁定 QAudioOutput,且播放狀態(tài)監(jiān)聽邏輯變更;
  3. 原有播放模式(單曲循環(huán)、列表循環(huán)、單次播放)需重新實現(xiàn);
  4. 音頻索引切換、自動切歌等核心邏輯需手動封裝。

三、解決方案:自定義 MediaPlaylist 類實現(xiàn)

3.1 類設(shè)計思路

遵循 Qt 信號槽設(shè)計規(guī)范,封裝播放列表核心能力,核心設(shè)計目標(biāo):

  • 兼容 Qt6 QMediaPlayer 新架構(gòu);
  • 支持三種經(jīng)典播放模式;
  • 自動監(jiān)聽播放完成狀態(tài),實現(xiàn)無感切歌;
  • 提供簡潔的外部接口,最小化項目改造成本。

3.2 完整代碼實現(xiàn)

  • 頭文件(ol_MediaPlaylist.h)
/****************************************************************************************/
/*
 * 程序名:ol_MediaPlaylist.h
 * 功能描述:Qt6 媒體播放列表類,替代廢棄的 QMediaPlaylist,支持以下特性:
 *          - 自動綁定 QMediaPlayer,監(jiān)聽播放完成狀態(tài)
 *          - 三種播放模式:單次播放、單曲循環(huán)、列表循環(huán)
 *          - 播放結(jié)束自動切換曲目/循環(huán)播放
 *          - 索引/媒體資源自動管理,適配 Qt6
 *          - 支持信號通知索引變化,與音頻播放器聯(lián)動
 * 作者:ol
 * 適用標(biāo)準(zhǔn):Qt 6.0及以上
 */
/****************************************************************************************/
#ifndef OL_MEDIAPLAYLIST_H
#define OL_MEDIAPLAYLIST_H
#include <QObject>
#include <QVector>
#include <QUrl>
#include <QMediaPlayer>
namespace ol
{
    /**
     * @brief 媒體播放列表類,適配 Qt6 QMediaPlayer
     * 實現(xiàn)播放列表管理、自動循環(huán)切歌、播放模式控制,無需手動處理音源切換
     */
    class MediaPlaylist : public QObject
    {
        Q_OBJECT
    public:
        /**
         * @brief 播放模式枚舉
         */
        enum class PlaybackMode : char
        {
            CurrentItemOnce, /**< 當(dāng)前曲目播放一次后自動停止 */
            CurrentItemLoop, /**< 當(dāng)前曲目無限循環(huán)播放 */
            SequentialLoop   /**< 列表順序循環(huán),尾首自動銜接 */
        };
    private:
        QVector<QUrl> m_mediaList;   ///< 媒體資源 URL 列表
        int m_currentIndex;          ///< 當(dāng)前播放索引,-1 表示未選中
        PlaybackMode m_playbackMode; ///< 當(dāng)前播放模式
        QMediaPlayer* m_player;      ///< 綁定的 Qt 媒體播放器
    public:
        /**
         * @brief 構(gòu)造函數(shù)
         * @param parent 父對象
         */
        explicit MediaPlaylist(QObject* parent = nullptr);
        /**
         * @brief 向播放列表添加媒體資源
         * @param media 媒體資源 URL(支持 qrc 資源/本地文件)
         */
        void addMedia(const QUrl& media);
        /**
         * @brief 清空播放列表,重置索引
         */
        void clear();
        /**
         * @brief 設(shè)置當(dāng)前播放索引(自動切換播放器音源)
         * @param index 目標(biāo)播放索引
         */
        void setCurrentIndex(int index);
        /**
         * @brief 獲取當(dāng)前播放索引
         * @return 當(dāng)前索引,-1 表示無效
         */
        inline int getCurrentIndex() const { return m_currentIndex; }
        /**
         * @brief 獲取當(dāng)前播放的媒體 URL
         * @return 有效 URL / 空 QUrl
         */
        QUrl getCurrentMedia() const;
        /**
         * @brief 獲取列表總媒體數(shù)量
         * @return 媒體資源總數(shù)
         */
        inline qsizetype getMediaCount() const { return m_mediaList.size(); }
        /**
         * @brief 設(shè)置播放模式
         * @param mode 目標(biāo)播放模式
         */
        inline void setPlaybackMode(PlaybackMode mode) { m_playbackMode = mode; }
        /**
         * @brief 獲取當(dāng)前播放模式
         * @return 播放模式枚舉值
         */
        inline PlaybackMode getPlaybackMode() const { return m_playbackMode; }
        /**
         * @brief 綁定 Qt 媒體播放器
         * @param player 待綁定的 QMediaPlayer 對象
         */
        void setPlayer(QMediaPlayer* player);
        /**
         * @brief 切換到下一首媒體
         * @return 下一首媒體的 URL
         */
        QUrl nextMedia();
        /**
         * @brief 切換到上一首媒體
         * @return 上一首媒體的 URL
         */
        QUrl previousMedia();
    signals:
        /**
         * @brief 播放索引改變信號,用于用戶未來功能擴展
         * @param newIndex 新的播放索引
         */
        void currentIndexChanged(int newIndex);
    private slots:
        /**
         * @brief 監(jiān)聽播放器狀態(tài),播放完成自動處理切歌/循環(huán)
         * @param status 媒體播放狀態(tài)
         */
        void onMediaStatusChanged(QMediaPlayer::MediaStatus status);
    };
} // namespace ol
#endif // !OL_MEDIAPLAYLIST_H
  • 源文件(ol_MediaPlaylist.cpp)
/****************************************************************************************/
/*
 * 程序名:ol_MediaPlaylist.cpp
 * 功能描述:媒體播放列表類實現(xiàn)文件
 * 作者:ol
 */
/****************************************************************************************/
#include "ol_MediaPlaylist.h"
#include <QMediaPlayer>

namespace ol
{
    MediaPlaylist::MediaPlaylist(QObject* parent)
        : QObject(parent), m_currentIndex(-1), m_playbackMode(PlaybackMode::CurrentItemOnce), m_player(nullptr)
    {
    }

    void MediaPlaylist::addMedia(const QUrl& media)
    {
        m_mediaList.append(media);
        if (m_currentIndex == -1) setCurrentIndex(0);
    }

    void MediaPlaylist::clear()
    {
        m_mediaList.clear();
        m_currentIndex = -1;
        emit currentIndexChanged(m_currentIndex);
    }

    void MediaPlaylist::setCurrentIndex(int index)
    {
        if (index >= 0 && index < m_mediaList.size() && index != m_currentIndex)
        {
            m_currentIndex = index;
            emit currentIndexChanged(m_currentIndex);

            // 自動切換播放器音源
            if (m_player) m_player->setSource(getCurrentMedia());
        }
    }

    QUrl MediaPlaylist::getCurrentMedia() const
    {
        if (m_currentIndex >= 0 && m_currentIndex < m_mediaList.size()) return m_mediaList.at(m_currentIndex);
        return QUrl();
    }

    void MediaPlaylist::setPlayer(QMediaPlayer* player)
    {
        // 斷開舊播放器連接
        if (m_player) disconnect(m_player, nullptr, this, nullptr);

        m_player = player;

        // 綁定狀態(tài)監(jiān)聽信號
        if (m_player)
        {
            connect(m_player, &QMediaPlayer::mediaStatusChanged, this, &MediaPlaylist::onMediaStatusChanged);

            // 默認(rèn)加載當(dāng)前音源
            const QUrl url = getCurrentMedia();
            if (url.isValid()) m_player->setSource(url);
        }
    }

    QUrl MediaPlaylist::nextMedia()
    {
        if (m_mediaList.isEmpty()) return QUrl();

        setCurrentIndex((m_currentIndex + 1) % m_mediaList.size());
        return getCurrentMedia();
    }

    QUrl MediaPlaylist::previousMedia()
    {
        if (m_mediaList.isEmpty()) return QUrl();

        setCurrentIndex((m_currentIndex - 1 + m_mediaList.size()) % m_mediaList.size());
        return getCurrentMedia();
    }

    void MediaPlaylist::onMediaStatusChanged(QMediaPlayer::MediaStatus status)
    {
        // 僅處理播放完成狀態(tài)
        if (status != QMediaPlayer::EndOfMedia || !m_player) return;
        if (m_mediaList.isEmpty()) return;

        switch (m_playbackMode)
        {
        case PlaybackMode::CurrentItemOnce:
            m_player->stop();
            break;
        case PlaybackMode::CurrentItemLoop:
            m_player->play();
            break;
        case PlaybackMode::SequentialLoop:
            nextMedia();
            m_player->play();
            break;
        }
    }

} // namespace ol

四、核心功能解析

4.1 播放模式控制

復(fù)刻 Qt5 QMediaPlaylist 三種經(jīng)典模式,通過 PlaybackMode 枚舉實現(xiàn):

  • CurrentItemOnce:播放完成后自動停止;
  • CurrentItemLoop:單曲無限循環(huán)(播放完成后重新播放);
  • SequentialLoop:列表循環(huán)(播放完成自動切下一首,最后一首切回第一首)。

4.2 自動綁定播放器

通過 setPlayer 方法綁定 QMediaPlayer,實現(xiàn)兩個核心能力:

  1. 自動監(jiān)聽 mediaStatusChanged 信號,無需外部手動處理播放完成事件;
  2. 切換索引時自動調(diào)用 setSource,避免外部重復(fù)編寫音源切換邏輯。

4.3 索引安全管理

所有索引操作(setCurrentIndex/nextMedia/previousMedia)均做合法性校驗:

  • 索引越界時不執(zhí)行任何操作;
  • 空列表時返回空 URL,避免程序崩潰;
  • 首次添加媒體自動選中第一個索引,降低使用成本。

五、項目集成示例

以實際項目中的 BGMControl 類為例,展示如何快速集成自定義 MediaPlaylist

// 音頻控制類中初始化播放列表
BGMControl::BGMControl(QObject* parent) : QObject(parent)
{
    // 初始化5組音頻單元(男女音效/BGM/輔助音效/結(jié)束音效)
    for (int i = 0; i < 5; ++i)
    {
        QAudioOutput* output = new QAudioOutput(this);
        QMediaPlayer* player = new QMediaPlayer(this);
        ol::MediaPlaylist* playlist = new ol::MediaPlaylist(this);

        // 綁定播放器與播放列表
        player->setAudioOutput(output);
        playlist->setPlayer(player);
        output->setVolume(1.0f);

        // 配置播放模式(BGM列表循環(huán),其他單次播放)
        if (i == 2) {
            playlist->setPlaybackMode(ol::MediaPlaylist::PlaybackMode::SequentialLoop);
        } else {
            playlist->setPlaybackMode(ol::MediaPlaylist::PlaybackMode::CurrentItemOnce);
        }

        m_outputs.push_back(output);
        m_players.push_back(player);
        m_playlists.push_back(playlist);
    }

    // 加載音頻資源
    initPlayList();
}

// 啟動BGM示例
void BGMControl::startBGM(float volume)
{
    m_outputs[2]->setVolume(volume);
    m_playlists[2]->setCurrentIndex(0); // 選中第一個BGM
    m_players[2]->play();               // 開始播放
}

六、總結(jié)

本文實現(xiàn)的 MediaPlaylist 類完全適配 Qt6 多媒體架構(gòu),核心優(yōu)勢:

  1. 低改造成本:接口設(shè)計貼近 Qt5 QMediaPlaylist,項目遷移時無需大幅修改業(yè)務(wù)邏輯;
  2. 高穩(wěn)定性:完善的索引校驗、內(nèi)存管理,避免空指針 / 越界崩潰;
  3. 強擴展性:保留 currentIndexChanged 信號,支持后續(xù) UI 同步、日志記錄等擴展;
  4. 零依賴:僅依賴 Qt6 Core 和 Multimedia 模塊,無需第三方庫。

以上就是Qt6替代廢棄QMediaPlaylist的解決方案的詳細(xì)內(nèi)容,更多關(guān)于Qt6替代廢棄QMediaPlaylist的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺析C語言中strtol()函數(shù)與strtoul()函數(shù)的用法

    淺析C語言中strtol()函數(shù)與strtoul()函數(shù)的用法

    這篇文章主要介紹了淺析C語言中strtol()函數(shù)與strtoul()函數(shù)的用法,注意其將字符串轉(zhuǎn)換成long型的區(qū)別,需要的朋友可以參考下
    2015-08-08
  • C++基于灰度圖上色GrayToColorFromOther的實現(xiàn)

    C++基于灰度圖上色GrayToColorFromOther的實現(xiàn)

    本文主要介紹了C++基于灰度圖上色GrayToColorFromOther的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • C++中的六個函數(shù)

    C++中的六個函數(shù)

    本文給大家介紹了C++中的六個函數(shù),非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-05-05
  • 深入分析C++模板特化與偏特化

    深入分析C++模板特化與偏特化

    這篇文章主要介紹了C++模板特化與偏特化的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下
    2020-08-08
  • C語言科學(xué)計算入門之矩陣乘法的相關(guān)計算

    C語言科學(xué)計算入門之矩陣乘法的相關(guān)計算

    這篇文章主要介紹了C語言科學(xué)計算入門之矩陣乘法的相關(guān)計算,文章中還介紹了矩陣相關(guān)的斯特拉森算法的實現(xiàn),需要的朋友可以參考下
    2015-12-12
  • C++多態(tài)的實現(xiàn)及原理詳細(xì)解析

    C++多態(tài)的實現(xiàn)及原理詳細(xì)解析

    C++的多態(tài)性用一句話概括就是:在基類的函數(shù)前加上virtual關(guān)鍵字,在派生類中重寫該函數(shù),運行時將會根據(jù)對象的實際類型來調(diào)用相應(yīng)的函數(shù)。如果對象類型是派生類,就調(diào)用派生類的函數(shù);如果對象類型是基類,就調(diào)用基類的函數(shù)
    2013-09-09
  • C++之CNoTrackObject類和new delete操作符的重載實例

    C++之CNoTrackObject類和new delete操作符的重載實例

    這篇文章主要介紹了C++之CNoTrackObject類和new delete操作符的重載實例,是C++程序設(shè)計中比較重要的概念,需要的朋友可以參考下
    2014-10-10
  • C++ 標(biāo)準(zhǔn)庫入門到精通

    C++ 標(biāo)準(zhǔn)庫入門到精通

    C++標(biāo)準(zhǔn)庫是C++語言的核心功能模塊集合,包含容器、算法、迭代器、字符串處理、輸入/輸出等功能,它基于模板實現(xiàn),與C++語言緊密集成,是開發(fā)高效、可移植程序的基礎(chǔ)工具,本文介紹C++ 標(biāo)準(zhǔn)庫概述,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • linux下C語言中的mkdir函數(shù)與rmdir函數(shù)

    linux下C語言中的mkdir函數(shù)與rmdir函數(shù)

    以下是對C語言中的mkdir函數(shù)與rmdir函數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下
    2013-08-08
  • C++常見的stl容器與相關(guān)操作 示例解析

    C++常見的stl容器與相關(guān)操作 示例解析

    所謂容器,就是可以承載,包含元素的一個器件,它是STL六大組件之一,是容器、算法、迭代器中最重要也是最核心的一部分
    2022-10-10

最新評論

枣庄市| 茶陵县| 上林县| 讷河市| 南康市| 汪清县| 舟山市| 梁山县| 永丰县| 绥中县| 南投市| 库车县| 屯昌县| 玉林市| 扶沟县| 海城市| 习水县| 周宁县| 黄大仙区| 维西| 沐川县| 芜湖市| 大石桥市| 庆阳市| 会理县| 威海市| 湘西| 永兴县| 金湖县| 通江县| 翁牛特旗| 道孚县| 北京市| 尉氏县| 莎车县| 南安市| 自贡市| 囊谦县| 桦南县| 寿光市| 绥宁县|