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

Qt6替代廢棄QMediaPlaylist的解決方案

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

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

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

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

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

二、核心痛點(diǎn)分析

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

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

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

3.1 類設(shè)計(jì)思路

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

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

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

  • 頭文件(ol_MediaPlaylist.h)
/****************************************************************************************/
/*
 * 程序名:ol_MediaPlaylist.h
 * 功能描述:Qt6 媒體播放列表類,替代廢棄的 QMediaPlaylist,支持以下特性:
 *          - 自動(dòng)綁定 QMediaPlayer,監(jiān)聽播放完成狀態(tài)
 *          - 三種播放模式:單次播放、單曲循環(huán)、列表循環(huán)
 *          - 播放結(jié)束自動(dòng)切換曲目/循環(huán)播放
 *          - 索引/媒體資源自動(dòng)管理,適配 Qt6
 *          - 支持信號(hào)通知索引變化,與音頻播放器聯(lián)動(dòng)
 * 作者: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
     * 實(shí)現(xiàn)播放列表管理、自動(dòng)循環(huán)切歌、播放模式控制,無需手動(dòng)處理音源切換
     */
    class MediaPlaylist : public QObject
    {
        Q_OBJECT
    public:
        /**
         * @brief 播放模式枚舉
         */
        enum class PlaybackMode : char
        {
            CurrentItemOnce, /**< 當(dāng)前曲目播放一次后自動(dòng)停止 */
            CurrentItemLoop, /**< 當(dāng)前曲目無限循環(huán)播放 */
            SequentialLoop   /**< 列表順序循環(huán),尾首自動(dòng)銜接 */
        };
    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 父對(duì)象
         */
        explicit MediaPlaylist(QObject* parent = nullptr);
        /**
         * @brief 向播放列表添加媒體資源
         * @param media 媒體資源 URL(支持 qrc 資源/本地文件)
         */
        void addMedia(const QUrl& media);
        /**
         * @brief 清空播放列表,重置索引
         */
        void clear();
        /**
         * @brief 設(shè)置當(dāng)前播放索引(自動(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 對(duì)象
         */
        void setPlayer(QMediaPlayer* player);
        /**
         * @brief 切換到下一首媒體
         * @return 下一首媒體的 URL
         */
        QUrl nextMedia();
        /**
         * @brief 切換到上一首媒體
         * @return 上一首媒體的 URL
         */
        QUrl previousMedia();
    signals:
        /**
         * @brief 播放索引改變信號(hào),用于用戶未來功能擴(kuò)展
         * @param newIndex 新的播放索引
         */
        void currentIndexChanged(int newIndex);
    private slots:
        /**
         * @brief 監(jiān)聽播放器狀態(tài),播放完成自動(dòng)處理切歌/循環(huán)
         * @param status 媒體播放狀態(tài)
         */
        void onMediaStatusChanged(QMediaPlayer::MediaStatus status);
    };
} // namespace ol
#endif // !OL_MEDIAPLAYLIST_H
  • 源文件(ol_MediaPlaylist.cpp)
/****************************************************************************************/
/*
 * 程序名:ol_MediaPlaylist.cpp
 * 功能描述:媒體播放列表類實(shí)現(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);

            // 自動(dòng)切換播放器音源
            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)聽信號(hào)
        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 枚舉實(shí)現(xiàn):

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

4.2 自動(dòng)綁定播放器

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

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

4.3 索引安全管理

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

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

五、項(xiàng)目集成示例

以實(shí)際項(xiàng)目中的 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();
}

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

六、總結(jié)

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

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

以上就是Qt6替代廢棄QMediaPlaylist的解決方案的詳細(xì)內(nèi)容,更多關(guān)于Qt6替代廢棄QMediaPlaylist的資料請(qǐng)關(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的實(shí)現(xiàn)

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

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

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

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

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

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

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

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

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

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

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

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

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

    C++標(biāo)準(zhǔn)庫是C++語言的核心功能模塊集合,包含容器、算法、迭代器、字符串處理、輸入/輸出等功能,它基于模板實(shí)現(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ù)

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

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

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

最新評(píng)論

台北市| 泗阳县| 海盐县| 绵竹市| 乌拉特后旗| 府谷县| 读书| 巴东县| 卢龙县| 南通市| 梅州市| 定日县| 陵川县| 齐齐哈尔市| 光泽县| 昭平县| 普宁市| 珠海市| 弋阳县| 金华市| 西和县| 伊宁市| 金乡县| 南康市| 万全县| 湘乡市| 乌兰察布市| 保亭| 沧源| 桐柏县| 嘉义市| 商城县| 昂仁县| 交城县| 井冈山市| 嘉定区| 米易县| 侯马市| 农安县| 广元市| 镇巴县|