Qt开发:QMediaPlayer的介绍和使用

Qt开发:QMediaPlayer的介绍和使用

文章目录

一、QMediaPlayer 功能介绍二、QMediaPlayer 的常用函数三、QMediaPlayer 的常用槽函数四、QMediaPlayer 的常用信号函数

一、QMediaPlayer 功能介绍

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

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

#include

#include

#include

在 .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

#include

#include

返回值说明:返回一个 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"));

player->play();

// 获取当前媒体信息

QMediaContent media = player->media();

QUrl url = media.canonicalUrl();

qDebug() << "当前播放媒体路径:" << url.toString();

示例:媒体为空的判断:

if (player->media().isNull()) {

qDebug() << "当前没有设置媒体";

} else {

qDebug() << "当前媒体是:" << player->media().canonicalUrl();

}

配合播放列表使用(QMediaPlaylist)

QMediaPlaylist* playlist = new QMediaPlaylist();

playlist->addMedia(QUrl("http://example.com/1.mp3"));

playlist->addMedia(QUrl("http://example.com/2.mp3"));

playlist->setCurrentIndex(0);

QMediaPlayer* player = new QMediaPlayer(this);

player->setPlaylist(playlist);

player->play();

// 获取当前播放条目的媒体

QMediaContent media = player->media();

qDebug() << "当前播放:" << media.canonicalUrl();

2.13 QMediaPlayer::MediaStatus QMediaPlayer::mediaStatus() const 作用:用于获取当前媒体播放器状态的函数,返回一个枚举值,表示播放器当前加载和播放媒体的状态。

功能说明:

返回播放器的当前媒体状态,可用来判断媒体的加载、缓冲、播放准备等情况;结合信号 mediaStatusChanged() 监听状态变化,适合根据状态做不同处理(如显示加载动画、错误提示、自动播放等)。

MediaStatus 枚举说明: 使用示例:

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/music/test.mp3"));

player->play();

connect(player, &QMediaPlayer::mediaStatusChanged, this, [=](QMediaPlayer::MediaStatus status){

switch (status) {

case QMediaPlayer::NoMedia:

qDebug() << "没有媒体";

break;

case QMediaPlayer::LoadingMedia:

qDebug() << "正在加载媒体...";

break;

case QMediaPlayer::LoadedMedia:

qDebug() << "媒体加载完成";

break;

case QMediaPlayer::BufferingMedia:

qDebug() << "正在缓冲...";

break;

case QMediaPlayer::BufferedMedia:

qDebug() << "缓冲完成";

break;

case QMediaPlayer::StalledMedia:

qDebug() << "缓冲暂停,等待更多数据";

break;

case QMediaPlayer::EndOfMedia:

qDebug() << "播放结束";

break;

case QMediaPlayer::InvalidMedia:

qDebug() << "媒体无效";

break;

default:

qDebug() << "其他状态";

break;

}

});

2.14 const QIODevice * QMediaPlayer::mediaStream() const 作用:用于获取当前播放器使用的底层媒体数据流设备(QIODevice 指针)。

功能说明:

返回指向当前播放的媒体数据流的 QIODevice 指针;主要用于从自定义数据源(如内存中的数据、加密流、网络流)播放媒体时,获取底层数据设备;如果媒体不是从 QIODevice 播放(如直接从文件或 URL),通常返回 nullptr;该接口是只读指针,不能修改设备。

典型应用场景:

你使用 QMediaPlayer::setMedia(const QMediaContent &, QIODevice *) 方式从自定义 QIODevice 播放数据时,可以通过该函数获取数据流;方便调试或对流做额外处理(如统计、调试);配合自定义媒体数据源实现特殊功能。

示例代码:

QFile* file = new QFile("C:/music/song.mp3");

if (file->open(QIODevice::ReadOnly)) {

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QMediaContent(), file); // 通过 QIODevice 播放

player->play();

const QIODevice* stream = player->mediaStream();

if (stream) {

qDebug() << "媒体流设备打开,字节数:" << stream->size();

} else {

qDebug() << "当前没有使用 QIODevice 作为媒体流";

}

}

注意事项:

只有在媒体是通过 QIODevice 设置时,mediaStream() 才非空;该函数适合高级用例,普通文件或 URL 播放不需要使用;QIODevice 生命周期需自己管理,确保在播放器使用期间不被销毁。

2.15 qreal QMediaPlayer::playbackRate() const 作用:用于获取当前媒体播放器的播放速率。

功能说明:

返回当前播放的速率(倍速),类型为 qreal(通常是浮点数);1.0 表示正常速度播放;小于 1.0 表示慢速播放(如 0.5 是半速);大于 1.0 表示加速播放(如 2.0 是两倍速);0 表示暂停(暂停时通常是 pause() 触发,不一定是 0,但某些情况下也可用)。

配套设置函数:

void QMediaPlayer::setPlaybackRate(qreal rate);

用来设置播放速率。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"));

player->play();

// 设置两倍速播放

player->setPlaybackRate(2.0);

qreal rate = player->playbackRate();

qDebug() << "当前播放速率:" << rate; // 输出 2.0

2.16 QMediaPlaylist QMediaPlayer::playlist() const* 作用:于获取当前播放器绑定的播放列表对象 QMediaPlaylist 指针。

功能说明:

返回当前绑定到播放器的 QMediaPlaylist 对象指针;如果播放器没有绑定播放列表,返回 nullptr;通过该指针可以操作播放列表(如添加、删除、切换媒体);方便在播放器和播放列表间联动,实现列表播放功能。

常见配套函数: 示例代码:

// 创建播放器和播放列表

QMediaPlayer* player = new QMediaPlayer(this);

QMediaPlaylist* playlist = new QMediaPlaylist(this);

// 添加媒体

playlist->addMedia(QUrl::fromLocalFile("C:/music/song1.mp3"));

playlist->addMedia(QUrl::fromLocalFile("C:/music/song2.mp3"));

// 绑定播放列表

player->setPlaylist(playlist);

// 播放

player->play();

// 获取绑定的播放列表

QMediaPlaylist* pl = player->playlist();

if (pl) {

qDebug() << "播放列表长度:" << pl->mediaCount();

}

2.17 qint64 QMediaPlayer::position() const 作用:用于获取当前媒体播放的位置(播放进度),单位是毫秒(ms)。

功能说明:

返回当前播放进度,单位为毫秒(ms);当播放停止或未开始时,返回通常为 0;配合 setPosition(qint64) 可实现跳转播放功能;适用于进度条同步显示、定时器更新等。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"));

player->play();

// 查询当前播放进度

qint64 currentPos = player->position();

qDebug() << "当前播放位置(毫秒):" << currentPos;

进度条同步示例:

QSlider* slider = new QSlider(Qt::Horizontal, this);

slider->setRange(0, 1000);

connect(player, &QMediaPlayer::positionChanged, this, [=](qint64 pos){

slider->setValue(static_cast(pos));

});

结合媒体时长:

qint64 duration = player->duration();

qint64 pos = player->position();

qDebug() << "进度:" << pos << "/" << duration << "毫秒";

2.18 void QMediaPlayer::setAudioRole(QAudio::Role audioRole) 作用:用于设置音频播放的角色类型,从而影响系统对该音频的处理方式(如路由、优先级、音效管理等)。

配套函数:

QAudio::Role QMediaPlayer::audioRole() const;

QAudio::Role 枚举列表(部分): 示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

// 设置为“音乐播放”角色

player->setAudioRole(QAudio::MusicRole);

qDebug() << "当前音频角色:" << player->audioRole(); // 输出 1(MusicRole)

实际应用场景:

2.19 void QMediaPlayer::setCustomAudioRole(const QString &audioRole) 作用:用于为音频输出设置一个自定义的音频角色(audio role),通常用于与操作系统或平台特定的音频管理系统集成。

功能说明:

用于设置一个平台特定的自定义音频角色名,作为音频流的用途描述;与 QAudio::CustomRole 配合使用;如果你调用了 setCustomAudioRole(“my_role”),那么应当先将 audio role 设置为 QAudio::CustomRole,否则无效;该角色可能会被系统用来判断音频路由、优先级、音量控制等;

配套使用示例:

QMediaPlayer* player = new QMediaPlayer(this);

// 设置为自定义音频角色

player->setAudioRole(QAudio::CustomRole);

player->setCustomAudioRole("my_voice_alert");

// 播放音频

player->setMedia(QUrl::fromLocalFile("C:/alert.wav"));

player->play();

自定义 audioRole 常见应用: 搭配获取函数:

QString QMediaPlayer::customAudioRole() const;

注意事项:

2.20 void QMediaPlayer::setVideoOutput(QVideoWidget *output) 作用:用于设置视频输出目标,也就是将视频画面渲染到指定的 QVideoWidget 上。

功能说明:

设置视频播放的显示区域;QVideoWidget 是一个专门用于视频显示的控件;设置后,QMediaPlayer 播放的视频将会显示在该控件上;如果未设置视频输出,播放视频时将不会显示画面(即使音频有声);也可以多次调用来切换显示目标(如窗口内 → 全屏)。

示例代码:

#include

#include

#include

QMediaPlayer* player = new QMediaPlayer(this);

QVideoWidget* videoWidget = new QVideoWidget(this);

// 设置视频输出

player->setVideoOutput(videoWidget);

// 加入布局并播放

QVBoxLayout* layout = new QVBoxLayout(this);

layout->addWidget(videoWidget);

setLayout(layout);

player->setMedia(QUrl::fromLocalFile("C:/videos/sample.mp4"));

player->play();

应用场景: 注意事项:

必须在调用 play() 之前设置 setVideoOutput();如果你设置了 QMediaPlaylist,也同样适用;QVideoWidget 必须是已经创建的有效控件;支持的格式取决于平台的多媒体后端(GStreamer、FFmpeg、AVFoundation、DirectShow 等);

小贴士:判断视频是否存在 搭配 isVideoAvailable() 来控制 QVideoWidget 的显示与隐藏:

connect(player, &QMediaPlayer::mediaStatusChanged, this, [=](QMediaPlayer::MediaStatus status){

if (player->isVideoAvailable()) {

videoWidget->show();

} else {

videoWidget->hide(); // 没有视频内容就隐藏控件

}

});

2.21 void QMediaPlayer::setVideoOutput(QGraphicsVideoItem *output) 作用:用于将视频画面输出到 QGraphicsVideoItem,从而可以在 QGraphicsScene 中以图形项的方式显示和操作视频内容(例如旋转、缩放、加特效等)。

功能说明:

QGraphicsVideoItem 是一种可在 QGraphicsScene 中显示的视频项;setVideoOutput() 会将视频画面渲染到这个 QGraphicsVideoItem 上;适用于需要将视频与其他图形元素(如动画、图形对象)组合的场景;和 QVideoWidget 相比,QGraphicsVideoItem 提供了更强的图形变换能力。

应用场景: 示例代码:

#include

#include

#include

#include

QGraphicsScene* scene = new QGraphicsScene(this);

QGraphicsVideoItem* videoItem = new QGraphicsVideoItem();

scene->addItem(videoItem);

// 设置大小和变换

videoItem->setSize(QSizeF(640, 360));

videoItem->setRotation(15); // 旋转 15 度

videoItem->setOpacity(0.9); // 半透明

QGraphicsView* view = new QGraphicsView(scene, this);

view->setFixedSize(660, 400);

view->show();

QMediaPlayer* player = new QMediaPlayer(this);

player->setVideoOutput(videoItem); // 关键步骤

player->setMedia(QUrl::fromLocalFile("C:/videos/movie.mp4"));

player->play();

常用接口搭配(QGraphicsVideoItem) 注意事项:

QGraphicsVideoItem 必须添加到一个 QGraphicsScene 中才能显示;QGraphicsView 要适当设置视图区域,确保完整显示视频;不能同时设置多个输出设备(如 QVideoWidget 和 QGraphicsVideoItem 只能选一个);

一个带多个视频项同时播放、拖动、缩放的 QGraphicsScene 示例: 功能效果:

两个视频并排播放;每个视频可以:被鼠标拖动;用滚轮放大/缩小;使用 QGraphicsVideoItem 显示视频;所有视频共享一个 QGraphicsView 和 QGraphicsScene。

MyVideoItem.h

#ifndef MYVIDEOITEM_H

#define MYVIDEOITEM_H

#include

#include

#include

class MyVideoItem : public QGraphicsVideoItem

{

public:

MyVideoItem();

protected:

void mousePressEvent(QGraphicsSceneMouseEvent *event) override;

void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;

void wheelEvent(QGraphicsSceneWheelEvent *event) override;

private:

QPointF m_lastPos;

};

#endif // MYVIDEOITEM_H

MyVideoItem.cpp

#include "MyVideoItem.h"

#include

MyVideoItem::MyVideoItem()

{

setFlag(QGraphicsItem::ItemIsMovable, true);

setFlag(QGraphicsItem::ItemIsFocusable, true);

setFlag(QGraphicsItem::ItemIsSelectable, true);

setAcceptHoverEvents(true);

setAcceptDrops(true);

setAcceptedMouseButtons(Qt::LeftButton);

}

void MyVideoItem::mousePressEvent(QGraphicsSceneMouseEvent *event)

{

m_lastPos = event->scenePos();

QGraphicsVideoItem::mousePressEvent(event);

}

void MyVideoItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)

{

QPointF delta = event->scenePos() - m_lastPos;

moveBy(delta.x(), delta.y());

m_lastPos = event->scenePos();

QGraphicsVideoItem::mouseMoveEvent(event);

}

void MyVideoItem::wheelEvent(QGraphicsSceneWheelEvent *event)

{

qreal factor = (event->delta() > 0) ? 1.1 : 0.9;

setScale(scale() * factor);

event->accept();

}

main.cpp

#include

#include

#include

#include

#include

#include "MyVideoItem.h"

int main(int argc, char *argv[])

{

QApplication app(argc, argv);

QGraphicsScene* scene = new QGraphicsScene();

// 创建两个视频项

MyVideoItem* videoItem1 = new MyVideoItem();

videoItem1->setSize(QSizeF(320, 240));

videoItem1->setPos(0, 0);

scene->addItem(videoItem1);

MyVideoItem* videoItem2 = new MyVideoItem();

videoItem2->setSize(QSizeF(320, 240));

videoItem2->setPos(350, 0);

scene->addItem(videoItem2);

// 播放器 1

QMediaPlayer* player1 = new QMediaPlayer();

player1->setVideoOutput(videoItem1);

player1->setMedia(QUrl::fromLocalFile("video1.mp4")); // 替换成你的视频路径

player1->play();

// 播放器 2

QMediaPlayer* player2 = new QMediaPlayer();

player2->setVideoOutput(videoItem2);

player2->setMedia(QUrl::fromLocalFile("video2.mp4")); // 替换成你的视频路径

player2->play();

// 显示视图

QGraphicsView* view = new QGraphicsView(scene);

view->setRenderHint(QPainter::Antialiasing);

view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

view->setWindowTitle("多个视频项播放 - 支持拖动和缩放");

view->resize(800, 600);

view->show();

return app.exec();

}

2.22 void QMediaPlayer::setVideoOutput(QAbstractVideoSurface *surface) 作用:用于将视频帧输出到你自定义的 视频渲染器(surface)。相比 QVideoWidget 或 QGraphicsVideoItem,它提供了更灵活和底层的视频处理能力。

功能说明:

设置一个自定义的视频输出设备(QAbstractVideoSurface 的子类);可以捕获、处理、转换每一帧视频(如叠加图层、特效、转格式等);适用于高级用途,比如图像识别、OpenGL 渲染、帧处理、视频录制等;在你创建的子类中重写 present(const QVideoFrame &frame),处理每一帧数据。

示例代码:视频帧捕获并绘制到 QWidget 创建自定义 Surface 类

#include

#include

#include

#include

#include

class MyVideoSurface : public QAbstractVideoSurface {

Q_OBJECT

public:

MyVideoSurface(QWidget* widget, QObject* parent = nullptr)

: QAbstractVideoSurface(parent), m_widget(widget) {}

QList supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const override {

Q_UNUSED(type);

return { QVideoFrame::Format_RGB32, QVideoFrame::Format_ARGB32 };

}

bool present(const QVideoFrame &frame) override {

if (!frame.isValid())

return false;

QVideoFrame copyFrame(frame);

copyFrame.map(QAbstractVideoBuffer::ReadOnly);

QImage image(

copyFrame.bits(),

copyFrame.width(),

copyFrame.height(),

copyFrame.bytesPerLine(),

QVideoFrame::imageFormatFromPixelFormat(copyFrame.pixelFormat())

);

m_lastFrame = image.copy();

copyFrame.unmap();

m_widget->update(); // 触发 widget 重绘

return true;

}

QImage currentFrame() const {

return m_lastFrame;

}

private:

QWidget* m_widget;

QImage m_lastFrame;

};

自定义显示 Widget

class VideoWidget : public QWidget {

Q_OBJECT

public:

VideoWidget(QWidget* parent = nullptr)

: QWidget(parent), surface(new MyVideoSurface(this)) {

setMinimumSize(640, 480);

}

MyVideoSurface* videoSurface() const {

return surface;

}

protected:

void paintEvent(QPaintEvent*) override {

QPainter painter(this);

if (!surface->currentFrame().isNull())

painter.drawImage(rect(), surface->currentFrame());

}

private:

MyVideoSurface* surface;

};

main.cpp 中使用

#include

#include

#include "VideoWidget.h"

int main(int argc, char *argv[])

{

QApplication app(argc, argv);

VideoWidget* widget = new VideoWidget();

widget->show();

QMediaPlayer* player = new QMediaPlayer();

player->setVideoOutput(widget->videoSurface());

player->setMedia(QUrl::fromLocalFile("C:/videos/demo.mp4"));

player->play();

return app.exec();

}

2.23 QMediaPlayer::State QMediaPlayer::state() const 作用:用于获取当前媒体播放器的播放状态,如正在播放、暂停中、或已停止。

返回值类型:QMediaPlayer::State 枚举 功能说明:

你可以调用该函数来查询当前播放器的播放状态;通常结合 stateChanged(QMediaPlayer::State) 信号使用;用于 UI 状态控制(如显示播放/暂停按钮切换);也可以用于判断是否允许继续播放、重播等。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"));

player->play();

// 获取当前状态

QMediaPlayer::State currentState = player->state();

switch (currentState) {

case QMediaPlayer::PlayingState:

qDebug() << "播放器正在播放";

break;

case QMediaPlayer::PausedState:

qDebug() << "播放器已暂停";

break;

case QMediaPlayer::StoppedState:

qDebug() << "播放器已停止";

break;

}

信号连接:监听状态变化

connect(player, &QMediaPlayer::stateChanged, this, [](QMediaPlayer::State state){

if (state == QMediaPlayer::PlayingState)

qDebug() << "播放开始";

else if (state == QMediaPlayer::PausedState)

qDebug() << "播放暂停";

else if (state == QMediaPlayer::StoppedState)

qDebug() << "播放停止";

});

应用场景:

2.24 QList QMediaPlayer::supportedAudioRoles() const 作用:用于获取当前系统或平台下,媒体播放器所支持的音频角色(QAudio::Role)列表。

功能说明:

功能说明用于判断平台是否支持 setAudioRole() 中指定的角色;对于不同平台(如 Windows、Android、Linux、iOS),支持的角色可能不同;通常搭配 QMediaPlayer::setAudioRole() 使用,避免设置无效或不被识别的角色。

常见的 QAudio::Role 枚举值:

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

QList roles = player->supportedAudioRoles();

qDebug() << "当前平台支持的音频角色有:";

for (QAudio::Role role : roles) {

qDebug() << " - Role ID:" << role;

}

判断是否支持某个角色:

if (roles.contains(QAudio::GameRole)) {

player->setAudioRole(QAudio::GameRole);

} else {

qDebug() << "平台不支持 GameRole,使用默认 MusicRole";

player->setAudioRole(QAudio::MusicRole);

}

2.25 QStringList QMediaPlayer::supportedCustomAudioRoles() const 作用:用于返回当前平台所支持的自定义音频角色名称列表(仅在某些平台有效,如 Android、PulseAudio 环境下的 Linux 系统)。

功能说明:

返回系统可识别的自定义音频角色名称列表;仅当 QAudio::CustomRole 有效时,此函数才有意义;返回的字符串可用于 setCustomAudioRole(const QString &audioRole) 设置;通常用于让用户从合法的自定义角色中选择一个,而不是手动输入;

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

QStringList customRoles = player->supportedCustomAudioRoles();

if (customRoles.isEmpty()) {

qDebug() << "此平台不支持任何自定义音频角色";

} else {

qDebug() << "支持的自定义音频角色有:";

for (const QString& role : customRoles) {

qDebug() << " - " << role;

}

}

示例:设置自定义音频角色(配合 QAudio::CustomRole)

if (!customRoles.isEmpty()) {

player->setAudioRole(QAudio::CustomRole);

player->setCustomAudioRole(customRoles.first());

}

2.26 int QMediaPlayer::volume() const 作用:用于获取当前媒体播放器的音量大小。

功能说明:

返回当前音量值;范围是 0 到 100(0 表示静音,100 表示最大音量);可配合 setVolume(int) 使用实现音量控制功能;通常用于获取当前音量状态、同步音量滑块 UI 等。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"));

player->setVolume(75);

player->play();

int currentVolume = player->volume();

qDebug() << "当前音量:" << currentVolume; // 输出:75

与音量滑块同步:

QSlider* volumeSlider = new QSlider(Qt::Horizontal, this);

volumeSlider->setRange(0, 100);

volumeSlider->setValue(player->volume());

connect(volumeSlider, &QSlider::valueChanged, player, &QMediaPlayer::setVolume);

connect(player, &QMediaPlayer::volumeChanged, volumeSlider, &QSlider::setValue);

常用搭配函数: 注意事项:

三、QMediaPlayer 的常用槽函数

3.1 void QMediaPlayer::pause() 作用:用于暂停媒体播放。

功能说明:

暂停当前正在播放的媒体(音频或视频);暂停后,播放位置会被保留,下次调用 play() 会从当前位置继续播放;如果当前未播放(例如处于停止状态),调用 pause() 不会有任何效果;不会清除媒体内容。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"));

player->setVolume(80);

player->play();

// 稍后暂停播放

player->pause();

搭配使用的函数: 状态判断示例:

if (player->state() == QMediaPlayer::PlayingState) {

player->pause(); // 正在播放 → 暂停

}

信号配合使用:

connect(player, &QMediaPlayer::stateChanged, this, [](QMediaPlayer::State state){

if (state == QMediaPlayer::PausedState)

qDebug() << "媒体已暂停";

});

3.2 void QMediaPlayer::play() 作用:用于开始或恢复播放当前设置的媒体文件(音频或视频)。

功能说明:

如果播放器当前处于 StoppedState 或 PausedState,调用 play() 会开始或继续播放;如果没有设置媒体内容,调用 play() 不会有任何效果;如果播放器已在播放(PlayingState),调用 play() 不会造成中断;适用于首次播放、暂停后的恢复播放、播放新媒体。

简单示例:

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"));

player->setVolume(80);

player->play(); // 开始播放

播放器状态信号(推荐使用):

connect(player, &QMediaPlayer::stateChanged, this, [](QMediaPlayer::State state){

if (state == QMediaPlayer::PlayingState)

qDebug() << "媒体开始播放";

});

3.3 void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream = nullptr) 作用:用于设置要播放的媒体内容,并可选地从一个自定义的 QIODevice 数据流中读取媒体数据。

参数说明: 示例 1:播放本地文件(最常用)

QMediaPlayer* player = new QMediaPlayer(this);

QUrl url = QUrl::fromLocalFile("C:/music/song.mp3");

QMediaContent content(url);

player->setMedia(content); // 也可简写为 player->setMedia(QUrl::fromLocalFile(...));

player->play();

示例 2:播放网络视频

QUrl url("http://www.example.com/video.mp4");

player->setMedia(QMediaContent(url));

player->play();

示例 3:从内存缓冲区播放(使用 QBuffer)

QByteArray audioData = ...; // 假设你已经加载了音频数据

QBuffer* buffer = new QBuffer(this);

buffer->setData(audioData);

buffer->open(QIODevice::ReadOnly);

player->setMedia(QMediaContent(), buffer); // 使用流设备代替 URL

player->play();

示例 4:播放资源文件(:qrc)

QUrl resourceUrl("qrc:/sounds/beep.wav");

player->setMedia(QMediaContent(resourceUrl));

player->play();

3.4 void QMediaPlayer::setMuted(bool muted) 作用:用于设置媒体播放器是否静音(关闭声音输出)。

参数说明:

功能说明:

调用此函数可以控制播放器是否输出声音;设置为 true 时,播放器将不输出音频,但 volume() 音量值仍然保留;常与 isMuted() 和 volume() 一起使用,方便构建完整音量控制 UI。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"));

player->setVolume(80);

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

player->play();

切换静音状态示例

bool isMuted = player->isMuted();

player->setMuted(!isMuted); // 切换静音状态

与 UI 控件配合示例(静音按钮)

QPushButton* muteButton = new QPushButton("Mute", this);

connect(muteButton, &QPushButton::clicked, this, [=]() {

bool muted = player->isMuted();

player->setMuted(!muted);

muteButton->setText(muted ? "Mute" : "Unmute");

});

信号监听(状态同步 UI)

connect(player, &QMediaPlayer::mutedChanged, this, [](bool muted){

qDebug() << (muted ? "已静音" : "声音已开启");

});

3.5 void QMediaPlayer::setNetworkConfigurations(const QList &configurations) 作用:用于为媒体播放器设置可使用的网络配置列表,以便在播放网络媒体内容时选择合适的网络连接(如 Wi-Fi、蜂窝数据、代理等)。

参数说明: 功能说明:

适用于播放网络媒体内容(如 HTTP 视频流、网络音频);可通过此函数指定媒体播放器在访问媒体 URL 时使用的网络设置;例如:为播放器手动指定只使用 Wi-Fi 网络,避免使用蜂窝数据;也可用于设置代理、限定网络访问策略;通常配合 QNetworkConfigurationManager 获取系统可用网络配置。

示例代码 步骤:获取系统默认网络配置并设置

#include

#include

#include

QMediaPlayer* player = new QMediaPlayer(this);

// 获取默认网络配置(通常是当前有效的网络连接)

QNetworkConfigurationManager manager;

QNetworkConfiguration config = manager.defaultConfiguration();

if (config.isValid()) {

QList configList;

configList.append(config);

player->setNetworkConfigurations(configList);

}

示例:列出所有可用网络配置并设置

QList allConfigs = manager.allConfigurations(QNetworkConfiguration::Active);

player->setNetworkConfigurations(allConfigs);

3.6 void QMediaPlayer::setPlaybackRate(qreal rate) 作用:用于设置媒体播放的速率(倍速),可以加快或减慢音视频的播放速度。

参数说明:

功能说明:

设置当前媒体播放的速度;支持浮点数倍速(如 1.25, 1.5, 0.75);正常速率为 1.0;适用于音频和视频播放;实际支持的范围与平台、编解码器有关(部分平台不支持非标准速率)。

示例代码:

QMediaPlayer* player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/videos/sample.mp4"));

player->setPlaybackRate(1.5); // 设置为1.5倍速播放

player->play();

获取当前倍速:

qreal rate = player->playbackRate();

qDebug() << "当前播放速率为:" << rate;

示例:UI 控件控制倍速

QComboBox* speedBox = new QComboBox(this);

speedBox->addItem("0.5x", 0.5);

speedBox->addItem("1.0x", 1.0);

speedBox->addItem("1.5x", 1.5);

speedBox->addItem("2.0x", 2.0);

connect(speedBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) {

qreal rate = speedBox->itemData(index).toReal();

player->setPlaybackRate(rate);

});

3.7 void QMediaPlayer::setPlaylist(QMediaPlaylist *playlist) 作用:用于将一个 播放列表对象 (QMediaPlaylist) 设置为媒体播放器的播放源,实现自动顺序播放、循环、随机播放等功能。

功能说明:

设置播放器使用一个播放列表 (QMediaPlaylist) 作为媒体源;播放器会自动根据播放列表的内容进行媒体切换(下一首、上一首);可支持顺序播放、循环播放、随机播放等模式;播放器通过播放列表管理多个媒体项。

示例:创建播放列表并设置到播放器

QMediaPlayer* player = new QMediaPlayer(this);

QMediaPlaylist* playlist = new QMediaPlaylist(this);

// 添加多个媒体项

playlist->addMedia(QUrl::fromLocalFile("C:/music/song1.mp3"));

playlist->addMedia(QUrl::fromLocalFile("C:/music/song2.mp3"));

playlist->addMedia(QUrl::fromLocalFile("C:/music/song3.mp3"));

// 设置播放模式(例如循环播放)

playlist->setPlaybackMode(QMediaPlaylist::Loop);

// 设置播放列表到播放器

player->setPlaylist(playlist);

// 播放

player->play();

常见播放模式(QMediaPlaylist::PlaybackMode) 控制播放列表

playlist->next(); // 播放下一首

playlist->previous(); // 播放上一首

playlist->setCurrentIndex(0); // 指定播放第1首

获取当前播放信息

int index = playlist->currentIndex(); // 当前播放项索引

QMediaContent media = playlist->currentMedia(); // 当前播放的媒体项

3.8 void QMediaPlayer::setPosition(qint64 position) 作用:用于设置媒体播放位置,实现跳转播放(快进/快退/拖动进度条)的功能。

参数说明: 功能说明:

调用该函数可以让播放器跳转到指定时间点开始播放;通常用于实现拖动播放条、跳转指定时间、快进/快退等;需要媒体已经加载好(mediaStatus() 为 LoadedMedia 或 BufferedMedia);搭配 position() 和 duration() 可实现进度同步。

示例代码:快进 10 秒

qint64 currentPos = player->position();

player->setPosition(currentPos + 10000); // 快进10秒

示例:跳转到进度条位置

QSlider* slider = new QSlider(Qt::Horizontal);

slider->setRange(0, player->duration()); // 设置总时长范围(单位:ms)

connect(slider, &QSlider::sliderMoved, player, &QMediaPlayer::setPosition);

// 播放器进度变化 → 更新滑块

connect(player, &QMediaPlayer::positionChanged, slider, &QSlider::setValue);

下面实现一个用 Qt Widgets 编写的简单视频播放器示例,支持:

播放/暂停按钮显示当前播放时间和总时长进度条可拖动跳转音量调节(可选)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

class VideoPlayer : public QWidget {

Q_OBJECT

public:

VideoPlayer(QWidget *parent = nullptr) : QWidget(parent) {

// 初始化播放器和视频显示控件

player = new QMediaPlayer(this);

videoWidget = new QVideoWidget(this);

player->setVideoOutput(videoWidget);

// 播放/暂停按钮

playBtn = new QPushButton("▶", this);

playBtn->setFixedWidth(40);

// 进度条

positionSlider = new QSlider(Qt::Horizontal, this);

positionSlider->setRange(0, 0);

// 当前时间和总时长标签

timeLabel = new QLabel("00:00 / 00:00", this);

// 音量滑块(可选)

volumeSlider = new QSlider(Qt::Horizontal, this);

volumeSlider->setRange(0, 100);

volumeSlider->setValue(50);

player->setVolume(50);

// 布局

QHBoxLayout *controlLayout = new QHBoxLayout;

controlLayout->addWidget(playBtn);

controlLayout->addWidget(positionSlider);

controlLayout->addWidget(timeLabel);

controlLayout->addWidget(new QLabel("Vol:", this));

controlLayout->addWidget(volumeSlider);

QVBoxLayout *mainLayout = new QVBoxLayout(this);

mainLayout->addWidget(videoWidget);

mainLayout->addLayout(controlLayout);

setLayout(mainLayout);

setWindowTitle("Qt 视频播放器示例");

resize(800, 600);

// 连接信号槽

connect(playBtn, &QPushButton::clicked, this, &VideoPlayer::togglePlayPause);

connect(positionSlider, &QSlider::sliderMoved, this, &VideoPlayer::setPosition);

connect(player, &QMediaPlayer::positionChanged, this, &VideoPlayer::updatePosition);

connect(player, &QMediaPlayer::durationChanged, this, &VideoPlayer::updateDuration);

connect(volumeSlider, &QSlider::valueChanged, player, &QMediaPlayer::setVolume);

connect(player, &QMediaPlayer::stateChanged, this, &VideoPlayer::updatePlayButton);

// 打开文件(可改为菜单等)

QString fileName = QFileDialog::getOpenFileName(this, "打开视频文件", QString(), "视频文件 (*.mp4 *.avi *.mkv *.mov)");

if (!fileName.isEmpty()) {

player->setMedia(QUrl::fromLocalFile(fileName));

player->play();

}

}

private slots:

void togglePlayPause() {

if (player->state() == QMediaPlayer::PlayingState) {

player->pause();

} else {

player->play();

}

}

void setPosition(int position) {

player->setPosition(position);

}

void updatePosition(qint64 position) {

if (!positionSlider->isSliderDown()) {

positionSlider->setValue(static_cast(position));

}

updateTimeLabel(position, player->duration());

}

void updateDuration(qint64 duration) {

positionSlider->setRange(0, static_cast(duration));

updateTimeLabel(player->position(), duration);

}

void updatePlayButton(QMediaPlayer::State state) {

if (state == QMediaPlayer::PlayingState) {

playBtn->setText("⏸");

} else {

playBtn->setText("▶");

}

}

private:

void updateTimeLabel(qint64 position, qint64 duration) {

QString posStr = formatTime(position);

QString durStr = formatTime(duration);

timeLabel->setText(posStr + " / " + durStr);

}

QString formatTime(qint64 ms) {

int seconds = static_cast(ms / 1000);

int mins = seconds / 60;

int secs = seconds % 60;

return QString::asprintf("%02d:%02d", mins, secs);

}

private:

QMediaPlayer *player;

QVideoWidget *videoWidget;

QPushButton *playBtn;

QSlider *positionSlider;

QLabel *timeLabel;

QSlider *volumeSlider;

};

int main(int argc, char *argv[]) {

QApplication app(argc, argv);

VideoPlayer player;

player.show();

return app.exec();

}

输出示例:

3.9 void QMediaPlayer::stop() 作用:用于停止当前媒体的播放,并将播放位置重置为起点(0 毫秒)。

功能说明:

停止播放当前媒体;将播放位置重置为开头(position() == 0);不会清除媒体内容;若播放器处于暂停状态,也会重置到起点;下一次调用 play() 将从头开始播放。

示例代码:

QMediaPlayer *player = new QMediaPlayer(this);

player->setMedia(QUrl::fromLocalFile("C:/music/song.mp3"));

player->play();

// 稍后停止播放

player->stop(); // 播放停止,并回到开头

搭配播放状态判断使用

if (player->state() != QMediaPlayer::StoppedState) {

player->stop();

}

信号配合使用

connect(player, &QMediaPlayer::stateChanged, this, [](QMediaPlayer::State state){

if (state == QMediaPlayer::StoppedState)

qDebug() << "播放已停止,已重置到起点";

});

四、QMediaPlayer 的常用信号函数

4.1 void QMediaPlayer::audioAvailableChanged(bool available) 作用:用于在音频输出是否可用时发出通知。

功能说明:

当当前播放的媒体是否具有可用音频轨道发生变化时,该信号会被发出。参数 available:

true:当前媒体有可用的音频;false:当前媒体没有音频或无法播放音频。

使用场景:

动态 UI 控件启用/禁用,例如禁用“音量”或“静音”按钮;检测音频播放是否中断;切换媒体时判断是否需要音频播放功能。

示例代码:

QMediaPlayer *player = new QMediaPlayer(this);

connect(player, &QMediaPlayer::audioAvailableChanged, this, [](bool available){

if (available) {

qDebug() << "音频可用,启用音量控制";

} else {

qDebug() << "音频不可用,禁用音量控制";

}

});

示例场景:切换媒体时判断音频

player->setMedia(QUrl::fromLocalFile("C:/video/no_audio.mp4"));

// 触发 audioAvailableChanged(false)

player->setMedia(QUrl::fromLocalFile("C:/video/with_audio.mp4"));

// 触发 audioAvailableChanged(true)

搭配使用的函数:

4.2 void QMediaPlayer::audioRoleChanged(QAudio::Role role) 作用:用于通知音频角色(Audio Role)发生变化。

参数说明:

role:表示新的音频角色,类型为 QAudio::Role。QAudio::Role 是 Qt 定义的枚举,表示音频的逻辑用途,例如媒体播放、通话、闹钟等。

常见值包括: 该信号在音频角色发生变化时发出,通常是因为你调用了:

void QMediaPlayer::setAudioRole(QAudio::Role role);

使用示例:

QMediaPlayer *player = new QMediaPlayer(this);

connect(player, &QMediaPlayer::audioRoleChanged, this, [](QAudio::Role role) {

qDebug() << "音频角色发生变化,当前角色为:" << role;

});

设置音频角色:

player->setAudioRole(QAudio::MusicRole); // 会触发 audioRoleChanged

4.3 void QMediaPlayer::bufferStatusChanged(int percentFilled) 作用:用于通知缓冲区的填充状态发生变化,适用于流媒体播放(如在线播放视频/音频)等场景。

参数说明:

信号说明: 当媒体播放器缓冲数据时,Qt 会自动发出此信号,指示当前缓冲状态的百分比。

0 表示未缓冲;100 表示已完全缓冲;对于本地文件,该信号可能不会发出或始终为 100;对于 网络流媒体,播放前/播放过程中会频繁触发。

使用示例:

QMediaPlayer *player = new QMediaPlayer(this);

// 连接信号

connect(player, &QMediaPlayer::bufferStatusChanged, this, [](int percent){

qDebug() << "当前缓冲进度:" << percent << "%";

if (percent < 100) {

qDebug() << "缓冲中...";

} else {

qDebug() << "缓冲完成,准备播放";

}

});

应用场景:

在 UI 中显示缓冲进度条;播放器处于“缓冲中”状态时显示提示信息;网络不佳时动态反馈当前播放卡顿状况。

示例 UI 场景:

if (percent < 100) {

ui->labelStatus->setText("缓冲中... " + QString::number(percent) + "%");

} else {

ui->labelStatus->setText("播放中");

}

4.4 void QMediaPlayer::customAudioRoleChanged(const QString &role) 作用:用于在播放器的 自定义音频角色(Custom Audio Role) 发生更改时发出通知。

参数说明: 背景概念: 在 Qt 中,音频角色(Audio Role) 主要用于指定音频的用途类型,如音乐、通话、提示音等。 除了 Qt 提供的标准 QAudio::Role 枚举项外,你也可以设置自定义音频角色(例如特定于设备或系统的角色名称),通过如下函数:

void QMediaPlayer::setCustomAudioRole(const QString &role);

当 setCustomAudioRole() 成功设置新的音频角色后,系统会自动发出 customAudioRoleChanged() 信号,通知外部系统或 UI 作出响应。

示例代码:

QMediaPlayer *player = new QMediaPlayer(this);

// 设置自定义音频角色

player->setCustomAudioRole("my_custom_audio_role");

// 监听角色变更

connect(player, &QMediaPlayer::customAudioRoleChanged, this, [](const QString &role){

qDebug() << "自定义音频角色变更为:" << role;

});

4.5 void durationChanged(qint64 duration) 作用:用于在媒体时长发生变化时发出通知。

参数说明:

此信号会在以下情况之一发生时被触发:

设置新媒体(setMedia())并成功加载后;播放器状态更新,媒体信息加载完成;媒体源发生变化,导致时长更新;流式媒体或某些格式在播放一段时间后才确定总时长时。

常见用途:

更新 UI 显示的总时长(例如:00:02:15);设置进度条最大值(以支持拖动播放);初始化与时长相关的动画、计时器、逻辑。

示例代码:

connect(player, &QMediaPlayer::durationChanged, this, [=](qint64 duration){

QTime totalTime(0, (duration / 60000) % 60, (duration / 1000) % 60);

ui->labelTotalTime->setText(totalTime.toString("mm:ss"));

ui->slider->setMaximum(duration); // 设置进度条最大值

});

4.6 void error(QMediaPlayer::Error error) 作用:用于在播放器遇到错误时触发。

参数说明: 错误枚举值(QMediaPlayer::Error) 使用示例:

connect(player, &QMediaPlayer::error, this, [=](QMediaPlayer::Error err){

QString errorMsg;

switch (err) {

case QMediaPlayer::ResourceError:

errorMsg = "资源错误:无法找到媒体文件。";

break;

case QMediaPlayer::FormatError:

errorMsg = "格式错误:媒体格式不受支持。";

break;

case QMediaPlayer::NetworkError:

errorMsg = "网络错误:连接失败或超时。";

break;

case QMediaPlayer::AccessDeniedError:

errorMsg = "访问错误:权限不足。";

break;

case QMediaPlayer::ServiceMissingError:

errorMsg = "服务缺失:请检查多媒体支持。";

break;

default:

errorMsg = "未知错误。";

}

QMessageBox::critical(this, "播放错误", errorMsg);

});

4.7 void currentMediaChanged(const QMediaContent &media) 作用:用于在当前播放的媒体内容发生改变时触发。

信号触发时机:当播放列表切换到下一首、调用 setCurrentIndex() 或 next()、或 removeMedia() 导致当前媒体变化时,该信号会被触发。

示例:播放列表中媒体变化时更新标签

QMediaPlaylist *playlist = new QMediaPlaylist(this);

playlist->addMedia(QUrl::fromLocalFile("/path/to/video1.mp4"));

playlist->addMedia(QUrl::fromLocalFile("/path/to/video2.mp4"));

connect(playlist, &QMediaPlaylist::currentMediaChanged, this, [=](const QMediaContent &media) {

QString name = media.canonicalUrl().fileName();

ui->labelCurrentMedia->setText("正在播放: " + name);

});

获取更多媒体信息:

QUrl url = media.canonicalUrl();

QString path = url.toLocalFile(); // 本地路径

QString fileName = url.fileName(); // 文件名

结合 QMediaPlayer 使用

player->setPlaylist(playlist);

connect(playlist, &QMediaPlaylist::currentMediaChanged, this, [=](const QMediaContent &media){

qDebug() << "当前媒体变更:" << media.canonicalUrl().toString();

});

4.8 void QMediaPlayer::mediaChanged(const QMediaContent &media) 作用:用于在媒体内容发生变化时自动触发。

参数说明: 触发时机:

调用 setMedia() 更换了媒体内容;播放列表改变了当前媒体(如 QMediaPlaylist::next());媒体播放完成后切换到下一条;QMediaPlayer 状态重置或加载新的媒体。

示例代码: 基础用法

QMediaPlayer *player = new QMediaPlayer(this);

connect(player, &QMediaPlayer::mediaChanged, this, [](const QMediaContent &media) {

QString path = media.canonicalUrl().toString();

qDebug() << "媒体已更换:" << path;

});

显示媒体文件名到 QLabel

connect(player, &QMediaPlayer::mediaChanged, this, [=](const QMediaContent &media) {

QString fileName = media.canonicalUrl().fileName();

ui->labelFileName->setText("当前媒体: " + fileName);

});

4.9 void QMediaPlayer::mediaStatusChanged(QMediaPlayer::MediaStatus status) 作用:用于 通知媒体状态(mediaStatus)发生变化,可以用来监控媒体的加载、缓冲、播放准备等过程。

参数说明: MediaStatus 枚举值说明:

示例代码: 输出状态到控制台

connect(player, &QMediaPlayer::mediaStatusChanged, this, [](QMediaPlayer::MediaStatus status) {

switch (status) {

case QMediaPlayer::LoadingMedia:

qDebug() << "正在加载媒体...";

break;

case QMediaPlayer::LoadedMedia:

qDebug() << "媒体加载完成,可以播放。";

break;

case QMediaPlayer::EndOfMedia:

qDebug() << "播放结束。";

break;

case QMediaPlayer::InvalidMedia:

qDebug() << "媒体加载失败。";

break;

default:

qDebug() << "其他状态:" << status;

}

});

显示加载进度动画

connect(player, &QMediaPlayer::mediaStatusChanged, this, [=](QMediaPlayer::MediaStatus status) {

ui->loadingLabel->setVisible(status == QMediaPlayer::LoadingMedia);

});

4.10 void QMediaPlayer::mutedChanged(bool muted) 作用:用于在播放器的静音状态改变时自动发出通知。你可以利用这个信号来同步 UI(例如按钮状态)或记录用户操作。

参数说明: 典型使用场景:

示例代码 示例:连接信号槽并更新按钮图标

connect(player, &QMediaPlayer::mutedChanged, this, [=](bool muted) {

if (muted) {

ui->muteButton->setIcon(QIcon(":/icons/mute.png"));

qDebug() << "播放器已静音";

} else {

ui->muteButton->setIcon(QIcon(":/icons/volume.png"));

qDebug() << "播放器取消静音";

}

});

示例:点击按钮切换静音状态

connect(ui->muteButton, &QPushButton::clicked, this, [=]() {

player->setMuted(!player->isMuted());

});

4.11 void QMediaPlayer::networkConfigurationChanged(const QNetworkConfiguration &configuration) 作用:它在媒体播放器的网络配置发生改变时发出,用于通知应用更新网络相关状态。

参数说明: 使用背景:此信号用于监听播放器在网络状态切换时(如从 WiFi 切换到移动网络)是否需要重新加载流媒体、适配网络变化等。常用于在线播放视频或音频时。

示例:打印当前网络类型名称

connect(player, &QMediaPlayer::networkConfigurationChanged,

this, [](const QNetworkConfiguration &config) {

qDebug() << "网络配置已改变,当前配置名称为:" << config.name();

});

高级用法示例

QNetworkConfigurationManager netManager;

QList configs = netManager.allConfigurations();

player->setNetworkConfigurations(configs);

connect(player, &QMediaPlayer::networkConfigurationChanged, this, [](const QNetworkConfiguration &config){

if (config.bearerType() == QNetworkConfiguration::BearerWLAN) {

qDebug() << "切换到 WiFi 网络:" << config.name();

} else {

qDebug() << "切换到非 WiFi 网络:" << config.name();

}

});

4.12 void QMediaPlayer::playbackRateChanged(qreal rate) 作用:当媒体播放速率发生改变时,playbackRateChanged() 信号会被自动发出。你可以通过连接这个信号来执行例如 UI 更新、提示用户或记录日志等操作。

参数说明:

示例代码:连接信号并打印速率

connect(player, &QMediaPlayer::playbackRateChanged,

this, [](qreal rate){

qDebug() << "播放速率已改变:" << rate;

});

示例:切换播放速率并响应

// 设置为 1.5 倍速播放

player->setPlaybackRate(1.5);

// 响应速率变化

connect(player, &QMediaPlayer::playbackRateChanged,

this, [](qreal rate){

QString msg = QString("当前播放速度:%1x").arg(rate);

QMessageBox::information(nullptr, "播放速率变化", msg);

});

4.13 void QMediaPlayer::positionChanged(qint64 position) 作用:在媒体播放过程中,每当当前播放位置发生变化时发出。

参数说明: 发射时机(什么时候会触发?)

播放过程中,每当播放位置更新(通常每隔几十毫秒);调用 setPosition(qint64) 手动跳转时;媒体播放重新开始(seek);播放暂停或恢复之后;媒体加载时恢复上次进度。

示例:更新进度条和时间标签

connect(player, &QMediaPlayer::positionChanged, this, [=](qint64 pos) {

ui->sliderPosition->setValue(pos);

QTime currentTime((pos / 3600000) % 60, (pos / 60000) % 60, (pos / 1000) % 60);

ui->labelCurrentTime->setText(currentTime.toString("hh:mm:ss"));

});

示例:拖动进度条跳转播放位置

connect(ui->sliderPosition, &QSlider::sliderMoved, this, [=](int value){

player->setPosition(value);

});

4.14 void QMediaPlayer::seekableChanged(bool seekable) 作用:用于通知应用程序媒体是否支持“跳转播放(seek)”功能状态的变化。

参数说明:

发射时机:

媒体加载完成后;媒体源发生变化;播放器状态改变时(如从无效变为有效媒体);重新加载或设置媒体内容。

作用与用途:

通知 UI 是否启用进度条拖动;当媒体不支持 seek 时,可以禁用拖动功能;用于动态更新播放器界面交互行为。

示例:根据 seekable 状态启用或禁用进度条

connect(player, &QMediaPlayer::seekableChanged, this, [=](bool seekable) {

ui->sliderPosition->setEnabled(seekable);

});

4.15 void QMediaPlayer::stateChanged(QMediaPlayer::State state) 作用:用于通知播放器状态发生了变化,例如从播放到暂停、从暂停到停止等。

参数说明: 枚举值 QMediaPlayer::State:

使用场景 监听播放器状态变化,用于更新 UI(如按钮图标、状态提示等):

connect(player, &QMediaPlayer::stateChanged, this, [=](QMediaPlayer::State state) {

switch (state) {

case QMediaPlayer::PlayingState:

qDebug() << "正在播放";

ui->btnPlay->setText("暂停");

break;

case QMediaPlayer::PausedState:

qDebug() << "已暂停";

ui->btnPlay->setText("播放");

break;

case QMediaPlayer::StoppedState:

qDebug() << "已停止";

ui->btnPlay->setText("播放");

break;

}

});

示例:播放/暂停按钮联动

void MainWindow::on_btnPlay_clicked()

{

if (player->state() == QMediaPlayer::PlayingState) {

player->pause();

} else {

player->play();

}

}

4.16 void QMediaPlayer::videoAvailableChanged(bool videoAvailable) 作用:用于通知视频是否可用(例如,是否成功加载了一个包含视频流的媒体文件)。

参数说明: 示例用法

connect(player, &QMediaPlayer::videoAvailableChanged, this, [=](bool available) {

if (available) {

qDebug() << "视频流可用,开始播放视频";

ui->videoWidget->show();

} else {

qDebug() << "当前媒体没有可播放的视频流";

ui->videoWidget->hide();

}

});

4.17 void QMediaPlayer::volumeChanged(int volume) 作用:用于在音量发生变化时通知监听者当前音量值。

参数说明: 触发时机:

主动调用 player->setVolume(int) 修改音量时;系统或其他控件内部修改了 QMediaPlayer 的音量;播放器初始化后加载默认音量。

常见用途:

实时更新 UI 中的音量滑块位置(如 QSlider);在界面上显示当前音量百分比;保存音量值以便下次启动恢复;音量变化时播放提示音或显示提示气泡。

示例用法:

connect(player, &QMediaPlayer::volumeChanged, this, [=](int volume){

qDebug() << "当前音量:" << volume;

ui->volumeSlider->setValue(volume); // 同步更新 UI 滑块

ui->labelVolume->setText(QString("%1%").arg(volume));

});

📌 相关推荐