111人参与 • 2026-04-16 • C/C++
—— 之前使用qt5,如今使用qt6发现在qt6里qmediaplaylist已废弃,所以网上搜了一下,找到了该博主的博客,感想博主的代码,我在其基础上增加和修改,以适配qt5的写法。
qt5 中常用的 qmediaplaylist 类在 qt6 中被正式移除,这给大量依赖该类实现音频 / 视频播放列表管理的项目带来了兼容性问题。尤其对于棋牌、影音类应用(如本文的斗地主项目),播放列表是核心功能模块,急需一套轻量、兼容、易集成的替代方案。
本文基于实际项目经验,从零实现了一套 qt6 专属的 mediaplaylist 类,完全复刻 qmediaplaylist 核心能力,同时适配 qt6 新的多媒体架构(qmediaplayer + qaudiooutput),解决音频播放列表、循环切歌、播放模式控制等核心需求。
迁移 qt5 音频播放逻辑到 qt6 时,主要面临以下问题:
qmediaplaylist 直接移除,无官方替代类;qmediaplayer 需手动绑定 qaudiooutput,且播放状态监听逻辑变更;遵循 qt 信号槽设计规范,封装播放列表核心能力,核心设计目标:
qmediaplayer 新架构;/****************************************************************************************/
/*
* 程序名:ol_mediaplaylist.h
* 功能描述:qt6 媒体播放列表类,替代废弃的 qmediaplaylist,支持以下特性:
* - 自动绑定 qmediaplayer,监听播放完成状态
* - 三种播放模式:单次播放、单曲循环、列表循环
* - 播放结束自动切换曲目/循环播放
* - 索引/媒体资源自动管理,适配 qt6
* - 支持信号通知索引变化,与音频播放器联动
* 作者:ol
* 适用标准:qt 6.0及以上
*/
/****************************************************************************************/
#ifndef ol_mediaplaylist_h
#define ol_mediaplaylist_h
#include <qobject>
#include <qvector>
#include <qurl>
#include <qmediaplayer>
namespace ol
{
/**
* @brief 媒体播放列表类,适配 qt6 qmediaplayer
* 实现播放列表管理、自动循环切歌、播放模式控制,无需手动处理音源切换
*/
class mediaplaylist : public qobject
{
q_object
public:
/**
* @brief 播放模式枚举
*/
enum class playbackmode : char
{
currentitemonce, /**< 当前曲目播放一次后自动停止 */
currentitemloop, /**< 当前曲目无限循环播放 */
sequentialloop /**< 列表顺序循环,尾首自动衔接 */
};
private:
qvector<qurl> m_medialist; ///< 媒体资源 url 列表
int m_currentindex; ///< 当前播放索引,-1 表示未选中
playbackmode m_playbackmode; ///< 当前播放模式
qmediaplayer* m_player; ///< 绑定的 qt 媒体播放器
public:
/**
* @brief 构造函数
* @param parent 父对象
*/
explicit mediaplaylist(qobject* parent = nullptr);
/**
* @brief 向播放列表添加媒体资源
* @param media 媒体资源 url(支持 qrc 资源/本地文件)
*/
void addmedia(const qurl& media);
/**
* @brief 清空播放列表,重置索引
*/
void clear();
/**
* @brief 设置当前播放索引(自动切换播放器音源)
* @param index 目标播放索引
*/
void setcurrentindex(int index);
/**
* @brief 获取当前播放索引
* @return 当前索引,-1 表示无效
*/
inline int getcurrentindex() const { return m_currentindex; }
/**
* @brief 获取当前播放的媒体 url
* @return 有效 url / 空 qurl
*/
qurl getcurrentmedia() const;
/**
* @brief 获取列表总媒体数量
* @return 媒体资源总数
*/
inline qsizetype getmediacount() const { return m_medialist.size(); }
/**
* @brief 设置播放模式
* @param mode 目标播放模式
*/
inline void setplaybackmode(playbackmode mode) { m_playbackmode = mode; }
/**
* @brief 获取当前播放模式
* @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 监听播放器状态,播放完成自动处理切歌/循环
* @param status 媒体播放状态
*/
void onmediastatuschanged(qmediaplayer::mediastatus status);
};
} // namespace ol
#endif // !ol_mediaplaylist_h/****************************************************************************************/
/*
* 程序名:ol_mediaplaylist.cpp
* 功能描述:媒体播放列表类实现文件
* 作者: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;
// 绑定状态监听信号
if (m_player)
{
connect(m_player, &qmediaplayer::mediastatuschanged, this, &mediaplaylist::onmediastatuschanged);
// 默认加载当前音源
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)
{
// 仅处理播放完成状态
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
复刻 qt5 qmediaplaylist 三种经典模式,通过 playbackmode 枚举实现:
currentitemonce:播放完成后自动停止;currentitemloop:单曲无限循环(播放完成后重新播放);sequentialloop:列表循环(播放完成自动切下一首,最后一首切回第一首)。通过 setplayer 方法绑定 qmediaplayer,实现两个核心能力:
mediastatuschanged 信号,无需外部手动处理播放完成事件;setsource,避免外部重复编写音源切换逻辑。所有索引操作(setcurrentindex/nextmedia/previousmedia)均做合法性校验:
以实际项目中的 bgmcontrol 类为例,展示如何快速集成自定义 mediaplaylist:
// 音频控制类中初始化播放列表
bgmcontrol::bgmcontrol(qobject* parent) : qobject(parent)
{
// 初始化5组音频单元(男女音效/bgm/辅助音效/结束音效)
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列表循环,其他单次播放)
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(); // 开始播放
}
本文实现的 mediaplaylist 类完全适配 qt6 多媒体架构,核心优势:
qmediaplaylist,项目迁移时无需大幅修改业务逻辑;currentindexchanged 信号,支持后续 ui 同步、日志记录等扩展;以上就是qt6替代废弃qmediaplaylist的解决方案的详细内容,更多关于qt6替代废弃qmediaplaylist的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论