Qt开发:QMediaPlayer的介绍和使用

一、QMediaPlayer 功能介绍

  QMediaPlayer 是 Qt Multimedia 模块提供的一个类,用于音频和视频的播放。它提供了播放控制、音量设置、媒体源设置、播放进度获取等功能,常与 QVideoWidget 或 QMediaPlaylist 搭配使用,适用于音视频播放器等功能场景。OMediaPlayer可以播放经过压缩的音频或视频文件,如mp3、mp4、wmv等文件,OMediaPlaye可以播放单个文件,也可以和QMediaPlaylist类结合,对一个播放列表进行播放。所以使用QMediaPlayer和QMediaPlaylist可以轻松地设计一个自已的音乐或视频播放器。

1.1 引入头文件和模块
使用前需添加模块:

#include <QMediaPlayer>
#include <QVideoWidget>
#include <QMediaPlaylist>

在 .pro 文件中添加:

QT += multimedia multimediawidgets

二、QMediaPlayer 的常用函数

2.1 QAudio::Role QMediaPlayer::audioRole() const
作用:是用于获取当前音频的角色类型的函数,返回的是 QAudio::Role 枚举类型。这个功能主要用于音频管理系统,尤其在多媒体设备(如智能手机、车载系统等)中有实际作用。

QAudio::Role 枚举说明:
该枚举用于标识当前音频的用途/类别,比如音乐、语音通话、闹钟等:
在这里插入图片描述
使用示例:

QMediaPlayer* player = new QMediaPlayer(this);

// 设置媒体文件
player->setMedia(QUrl::fromLocalFile("C:/music/test.mp3"));
player->play();

// 获取当前音频角色
QAudio::Role role = player->audioRole();
qDebug() << "当前音频角色:" << role;

// 输出结果可能是:QAudio::MusicRole(默认)

设置音频角色(Qt 6 中新增)
在 Qt 6 中,QMediaPlayer 提供了 setAudioRole(QAudio::Role) 用于设置角色。

player->setAudioRole(QAudio::GameRole);

但在 Qt 5 中,audioRole 是只读的,不能设置,只能查询。

2.2 int QMediaPlayer::bufferStatus() const
作用:是一个用于查询当前媒体缓冲状态的函数,返回一个整数,表示缓冲完成的百分比。

返回值:

  • 返回值范围是 0 ~ 100,表示缓冲完成的百分比。
  • 仅适用于流媒体或需要缓冲的媒体源,例如在线播放的视频或音频。
  • 对于本地文件,通常始终返回 100。

典型应用场景:

  • 实现流媒体的缓冲动画/提示;
  • 显示播放器进度条的缓冲部分;
  • 判断是否可以开始播放;
  • 判断是否发生缓冲中断(用于弱网环境)。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

// 监听缓冲状态变化
connect(player, &QMediaPlayer::bufferStatusChanged, this, [=](int percent) {
   
   
    qDebug() << "缓冲状态:" << percent << "%";
    if (percent < 100) {
   
   
        qDebug() << "正在缓冲...";
    } else {
   
   
        qDebug() << "缓冲完成!";
    }
});

// 播放网络媒体
player->setMedia(QUrl("http://example.com/video.mp4"));
player->play();

同时你可以在其他时刻主动获取当前状态:

int status = player->bufferStatus();
qDebug() << "当前缓冲百分比:" << status;

2.3 QMediaContent QMediaPlayer::currentMedia() const
作用:用于获取当前正在播放的媒体信息的函数。它返回一个 QMediaContent 对象,表示当前设置或正在播放的媒体资源。通过它进一步获取媒体的 URL、元信息等。

返回值说明:
返回的是 QMediaContent 对象。常用的查询方式有:

QMediaContent media = player->currentMedia();
QUrl url = media.canonicalUrl();
qDebug() << "当前媒体URL:" << url.toString();

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);
player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"));
player->play();

// 获取当前媒体信息
QMediaContent media = player->currentMedia();
QUrl url = media.canonicalUrl();
qDebug() << "当前播放的媒体是:" << url.toLocalFile();

输出示例:

当前播放的媒体是: "C:/music/song.mp3"

与播放列表结合使用(推荐)
如果你使用 QMediaPlaylist,这个函数可以帮助你获取当前播放的条目:

QMediaPlaylist* playlist = new QMediaPlaylist();
playlist->addMedia(QUrl::fromLocalFile("C:/music/1.mp3"));
playlist->addMedia(QUrl::fromLocalFile("C:/music/2.mp3"));
playlist->setCurrentIndex(0);

QMediaPlayer* player = new QMediaPlayer(this);
player->setPlaylist(playlist);
player->play();

QMediaContent media = player->currentMedia();
qDebug() << "当前播放的是:" << media.canonicalUrl().toString();

常用 QMediaContent 成员函数
在这里插入图片描述
2.4 QNetworkConfiguration QMediaPlayer::currentNetworkConfiguration() const
作用:用于获取当前媒体播放器所使用的网络配置(QNetworkConfiguration)的函数。这个功能主要在播放网络流媒体(如在线视频、网络音频)时才有实际意义。

需要包含模块:

QT += multimedia network

包含头文件:

#include <QMediaPlayer>
#include <QNetworkConfiguration>
#include <QNetworkConfigurationManager>

返回值说明:返回一个 QNetworkConfiguration 对象,表示当前用于播放网络媒体的网络配置。例如是使用 WiFi、移动网络、VPN 等。如果当前没有播放网络流媒体,或者播放器未使用网络,该函数可能返回无效(isValid() == false)的配置。

使用示例:

QMediaPlayer* player = new QMediaPlayer(this);
player->setMedia(QUrl("http://example.com/media.mp3"));  // 网络媒体
player->play();

// 获取网络配置
QNetworkConfiguration config = player->currentNetworkConfiguration();
if (config.isValid()) {
   
   
    qDebug() << "网络名称:" << config.name();
    qDebug() << "是否漫游:" << config.isRoaming();
    qDebug() << "类型:" << config.bearerTypeName();
} else {
   
   
    qDebug() << "当前没有使用有效的网络配置。";
}

示例输出(取决于你的网络环境):

网络名称: "WLAN_5G"
是否漫游: false
类型: "WLAN"

常用 QNetworkConfiguration 成员函数
在这里插入图片描述

2.5 qint64 QMediaPlayer::duration() const
作用:是 QMediaPlayer 提供的一个函数,用于获取当前媒体(音频或视频)的总时长,单位是 毫秒(ms)。

功能说明:

  • 返回当前加载的媒体文件的总时长;
  • 单位为 毫秒(1000 毫秒 = 1 秒);
  • 若媒体未加载或加载失败,返回值为 0;
  • 可配合 position() 显示播放进度条。

常见用途:

  • 显示音频/视频总时长;
  • 计算播放进度百分比;
  • 创建进度条 QSlider 上限;
  • 判断是否播放完成。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

// 播放媒体
player->setMedia(QUrl::fromLocalFile("C:/music/test.mp3"));
player->play();

// 获取总时长(单位 ms)
connect(player, &QMediaPlayer::durationChanged, this, [=](qint64 dur){
   
   
    qDebug() << "总时长:" << dur << "毫秒";

    int seconds = dur / 1000;
    int minutes = seconds / 60;
    seconds = seconds % 60;

    qDebug() << QString("总时长为 %1:%2").arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0'));
});

配套函数:
在这里插入图片描述

用于进度条示例:

QSlider* slider = new QSlider(Qt::Horizontal, this);
slider->setRange(0, 0); // 初始设置为0

connect(player, &QMediaPlayer::durationChanged, slider, [=](qint64 dur){
   
   
    slider->setMaximum(dur);
});

connect(player, &QMediaPlayer::positionChanged, slider, [=](qint64 pos){
   
   
    slider->setValue(pos);
});

注意事项:

  • 媒体必须成功加载后才能获得有效时长;
  • 本地文件时长读取较快,网络媒体需等待缓冲;
  • 返回值为 qint64,以支持超过 2GB 的大文件(超过 30 分钟以上的视频等)。

2.6 QMediaPlayer::Error QMediaPlayer::error() const
作用:用于获取 QMediaPlayer 当前遇到的错误类型,以便判断播放失败的原因。

错误类型枚举(Qt 5)

enum QMediaPlayer::Error {
   
   
    NoError,
    ResourceError,
    FormatError,
    NetworkError,
    AccessDeniedError,
    ServiceMissingError,
    MediaIsPlaylist // Qt 5.15+
};

在这里插入图片描述
示例代码:

QMediaPlayer* player = new QMediaPlayer(this);
player->setMedia(QUrl::fromLocalFile("C:/music/test.mp3"));
player->play();

connect(player, &QMediaPlayer::error, this, [=]() {
   
   
    qDebug() << "播放失败,错误码:" << player->error();
    qDebug() << "错误信息:" << player->errorString();
});

2.7 QString QMediaPlayer::errorString() const
作用:用于返回 QMediaPlayer 当前遇到错误的详细文本描述,通常配合 error() 函数一起使用,用于调试或显示错误信息给用户。

功能说明:

  • 返回最近一次错误的字符串说明;
  • 如果当前没有错误(即 error() == QMediaPlayer::NoError),则返回一个空字符串;
  • 适用于调试输出、日志记录、或在界面中提示用户错误详情。

示例代码(Qt 5):

QMediaPlayer* player = new QMediaPlayer(this);

// 设置一个无效的媒体路径
player->setMedia(QUrl::fromLocalFile("C:/not_found.mp3"));
player->play();

// 监听错误
connect(player, &QMediaPlayer::error, this, [=]() {
   
   
    qDebug() << "错误代码:" << player->error();
    qDebug() << "错误信息:" << player->errorString();
});

输出示例:

错误代码: QMediaPlayer::ResourceError
错误信息: "Failed to open media"

2.8 bool QMediaPlayer::isAudioAvailable() const
作用:用于判断当前媒体是否包含音频流,即是否有可播放的音频轨道。

功能说明:

  • 如果当前加载的媒体中包含可用的音频,返回 true;
  • 如果媒体中没有音频,或者媒体还没加载成功,返回 false;
  • 可用于 UI 上的音频相关按钮(如音量调节、静音按钮)的启用控制。

使用示例:

QMediaPlayer* player = new QMediaPlayer(this);
player->setMedia(QUrl::fromLocalFile("C:/videos/sample.mp4"));
player->play();

// 稍后判断是否有音频
QTimer::singleShot(1000, this, [=]() {
   
   
    if (player->isAudioAvailable()) {
   
   
        qDebug() << "该媒体包含音频";
    } else {
   
   
        qDebug() << "该媒体不包含音频或尚未加载完成";
    }
});

注意:isAudioAvailable() 返回值依赖于媒体的加载状态,播放刚开始时立即调用可能返回 false,应等待 mediaStatusChanged 信号变为 LoadedMedia 或 BufferedMedia 后再检查。

更稳健的用法:信号配合判断

connect(player, &QMediaPlayer::mediaStatusChanged, this, [=](QMediaPlayer::MediaStatus status){
   
   
    if (status == QMediaPlayer::LoadedMedia || status == QMediaPlayer::BufferedMedia) {
   
   
        if (player->isAudioAvailable()) {
   
   
            qDebug() << "媒体中有音频";
        } else {
   
   
            qDebug() << "媒体中无音频";
        }
    }
});

2.9 bool QMediaPlayer::isMuted() const
作用:用于判断当前 QMediaPlayer 是否处于静音状态。

功能说明:

  • 如果播放器处于静音状态(即声音被关闭),返回 true;
  • 如果播放器未静音,返回 false;
  • 可用于音量图标切换、UI 状态同步等场景;
  • 搭配 setMuted(bool) 使用可控制静音开关。

配套函数:
在这里插入图片描述
示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

// 设置为静音
player->setMuted(true);

// 查询是否静音
if (player->isMuted()) {
   
   
    qDebug() << "当前是静音状态";
} else {
   
   
    qDebug() << "当前未静音";
}

2.10 bool QMediaPlayer::isSeekable() const
作用:用于判断当前媒体是否支持拖动(跳转)播放进度,即是否可以调用 setPosition(qint64) 来改变播放位置。

功能说明:

  • 返回 true:表示当前媒体是可定位的(可以快进、拖动、跳转)。
  • 返回 false:表示媒体不支持定位,例如某些实时流媒体或广播。

典型应用场景:

  • 启用/禁用进度条拖动功能;
  • 实现“快进”、“后退”按钮时判断是否支持;
  • 播放器中显示“当前媒体不可跳转”提示。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);
player->setMedia(QUrl::fromLocalFile("C:/videos/movie.mp4"));
player->play();

// 延迟判断是否可定位
connect(player, &QMediaPlayer::mediaStatusChanged, this, [=](QMediaPlayer::MediaStatus status){
   
   
    if (status == QMediaPlayer::LoadedMedia || status == QMediaPlayer::BufferedMedia) {
   
   
        if (player->isSeekable()) {
   
   
            qDebug() << "该媒体支持快进/定位播放";
        } else {
   
   
            qDebug() << "该媒体不支持跳转播放";
        }
    }
});

搭配使用的函数:
在这里插入图片描述
进度条启用控制示例:

QSlider* slider = new QSlider(Qt::Horizontal, this);
slider->setEnabled(false); // 默认禁用拖动

connect(player, &QMediaPlayer::mediaStatusChanged, this, [=](QMediaPlayer::MediaStatus status){
   
   
    if (status == QMediaPlayer::LoadedMedia && player->isSeekable()) {
   
   
        slider->setEnabled(true);
    }
});

2.11 bool QMediaPlayer::isVideoAvailable() const
作用:用于判断当前加载的媒体是否包含视频流(即是否有可播放的视频画面)。

功能说明:

  • 如果当前媒体中包含有效的视频轨道,返回 true;
  • 如果是纯音频文件(如 MP3),或媒体尚未加载完成、加载失败,返回 false;
  • 适用于视频播放器中控制是否显示 QVideoWidget 或视频画面区域。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);
player->setMedia(QUrl::fromLocalFile("C:/videos/sample.mp4"));
player->play();

connect(player, &QMediaPlayer::mediaStatusChanged, this, [=](QMediaPlayer::MediaStatus status) {
   
   
    if (status == QMediaPlayer::LoadedMedia || status == QMediaPlayer::BufferedMedia) {
   
   
        if (player->isVideoAvailable()) {
   
   
            qDebug() << "当前媒体包含视频";
        } else {
   
   
            qDebug() << "当前媒体不包含视频";
        }
    }
});

应用场景:

  • 自动切换 UI 显示区域:如果有视频,就显示 QVideoWidget;如果没有视频,只显示音频信息或封面图。
  • 判断是否启用“全屏播放”按钮;
  • 纯音频播放器中可隐藏无用的视频控件。

搭配使用建议:
在这里插入图片描述
UI 控制示例:

QVideoWidget* videoWidget = new QVideoWidget(this);
videoWidget->hide();

connect(player, &QMediaPlayer::mediaStatusChanged, this, [=](QMediaPlayer::MediaStatus status) {
   
   
    if (status == QMediaPlayer::LoadedMedia && player->isVideoAvailable()) {
   
   
        videoWidget->show();
        player->setVideoOutput(videoWidget);
    } else {
   
   
        videoWidget->hide(); // 没有视频就不显示视频控件
    }
});

注意事项:

  • 媒体必须加载完成后再调用 isVideoAvailable() 才有准确结果;
  • 某些网络媒体在初期缓冲阶段也可能暂时返回 false;
  • isVideoAvailable() ≠ 是否正在显示视频,要配合 QVideoWidget 正确使用。

2.12 QMediaContent QMediaPlayer::media() const
作用:用于获取当前播放器中设置的媒体内容对象 QMediaContent(在 Qt 5 中使用)。该函数可以帮助你查询当前正在播放的音视频资源。

功能说明:
media() 返回当前播放器设置的 QMediaContent 对象,它描述了一个媒体资源的信息,如 URL、元数据等。
你可以通过它进一步获取:

  • 媒体的标准 URL(本地或网络);
  • 判断是否为空媒体;
  • 与播放列表结合时获取当前条目。

常用配套函数(Qt 5):
在这里插入图片描述

示例代码(Qt 5):

QMediaPlayer* player = new QMediaPlayer(this);

// 设置本地媒体
player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"
在网上找了一个别人的旧版本的播放器~自己更改了一天,终于可运行了,希望分享下同共学习; 不过出了少少问题:希望有经验的一起指导下: 运行环境:qt creator +windows 1、原计划是可支持视频播放的,现在只能加载间频(mp3),一加载视频就卡死 2.、自定义的进度条不起作用,不知为什么百分比槽连接不成功 connect(wmp, SIGNAL(PositionChange(double, double)),this, SLOT(Slot_onPositionChange(double, double))); 3、我用的是QAxWidget控件,这个是不是只支持windows的呢?或者还有没其实更好的? /******************************************************************************************* 项目名:QT播放器 Qt Mediaplayer 工程师:枫儿 完成时间:2009年12月28日 技术支持:嵌入式家园 www.studyarm.cn www.mcupark.com *******************************************************************************************/ #include "playerwindow.h" #include #include #include #include #include #include #include #include PlayerWindow::PlayerWindow() { //setCaption(tr("Media Player")); fileFilters = tr("Video files (*.mpg *.mpeg *.avi *.wmv)\n" //原来字符串换行也可这样用 "Audio files (*.mp3 *.wav)"); updateTimer = 0; setMouseTracking(true); this->wmp = new QAxWidget(this); wmp->setControl("{22D6F312-B0F6-11D0-94AB-0080C74C7E95}"); // wmp->setProperty("ShowControls", QVariant(false, 0)); wmp->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); connect(wmp, SIGNAL(PlayStateChange(int, int)),this, SLOT(Slot_onPlayStateChange(int, int))); connect(wmp, SIGNAL(ReadyStateChange(ReadyStateConstants)),this, SLOT(Slot_onReadyStateChange(ReadyStateConstants))); connect(wmp, SIGNAL(PositionChange(double, double)),this, SLOT(Slot_onPositionChange(double, double))); this->openButton = new QPushButton(tr("&Open")); connect(openButton, SIGNAL(clicked()), this, SLOT(Slot_openFile())); this->playPauseButton = new QPushButton(tr("&Play")); connect(playPauseButton, SIGNAL(clicked()), wmp, SLOT(Play())); this->stopButton = new QPushButton(tr("&Stop")); connect(stopButton, SIGNAL(clicked()), wmp, SLOT(Stop())); this->seekSlider = new QSlider(Qt::Horizontal, this); seekSlider->setEnabled(false); connect(seekSlider, SIGNAL(valueChanged(int)),this, SLOT(Slot_sliderValueChanged(int))); connect(seekSlider, SIGNAL(sliderPressed()),wmp, SLOT(Pause())); QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addWidget(openButton); buttonLayout->addWidget(playPauseButton); buttonLayout->addWidget(stopButton); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(wmp); mainLayout->addLayout(buttonLayout); mainLayout->addWidget(seekSlider); this->setLayout(mainLayout); }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值