视频播放器
详细可参考正点原子QT教程视频播放器的设计,本人没有做太大改动(更换了退出按钮)。图片资料从正点原子的官方网站中下载。
一、ui界面部分
二、代码实现部分功能
(1)videoplayer.h文件
#ifndef VIDEOPLAYER_H
#define VIDEOPLAYER_H
#include <QMainWindow>
#include <QMainWindow>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QListWidget>
#include <QSpacerItem>
#include <QVideoWidget>
#include <QDebug>
/* 媒体信息结构体 */
struct video_MediaObjectInfo {
/* 用于保存视频文件名 */
QString fileName;
/* 用于保存视频文件路径 */
QString filePath;
};
QT_BEGIN_NAMESPACE
namespace Ui { class VideoPlayer; }
QT_END_NAMESPACE
class VideoPlayer : public QMainWindow
{
Q_OBJECT
public:
VideoPlayer(QMainWindow *parent = nullptr);
~VideoPlayer();
private:
Ui::VideoPlayer *ui;
/* 媒体播放器,用于播放视频 */
QMediaPlayer *videoPlayer;
/* 媒体列表 */
QMediaPlaylist *mediaPlaylist;
/* 视频显示窗口 */
QVideoWidget *videoWidget;
/* 视频列表 */
QListWidget *listWidget;
/* 水平布局 */
QHBoxLayout *hBoxLayout[1];
/* 水平容器 */
QWidget *hWidget[1];
/* 垂直容器 */
QWidget *vWidget[1];
/* 垂直界面 */
QVBoxLayout *vBoxLayout[1];
/* 视频布局函数 */
void videoLayout();
/* 主窗体大小重设大小函数重写 */
void resizeEvent(QResizeEvent *event);
/* 媒体信息存储 */
QVector<video_MediaObjectInfo> mediaObjectInfo;
/* 扫描本地视频文件 */
void scanVideoFiles();
/* 媒体初始化 */
void mediaPlayerInit();
// 判断qss文件是否存在并进行加载
void loadStyle();
private slots:
/* 媒体状态改变 */
void mediaPlayerStateChanged(QMediaPlayer::State);
/* 列表单击 */
void listWidgetCliked(QListWidgetItem*);
/* 媒体列表项改变 */
void mediaPlaylistCurrentIndexChanged(int);
/* 媒体总长度改变 */
void mediaPlayerDurationChanged(qint64);
/* 媒体播放位置改变 */
void mediaPlayerPositionChanged(qint64);
void on_btn_play_clicked();
void on_btn_next_clicked();
void on_btn_volumedown_clicked();
void on_btn_volumeup_clicked();
void on_btn_screen_clicked();
void on_durationSlider_sliderReleased();
void on_volumeSlider_sliderReleased();
void on_btn_previous_clicked();
void on_btn_exit_clicked();
signals:
void video_show_main();
};
#endif // VIDEOPLAYER_H
(2)videoplayer.cpp文件
#include "videoplayer.h"
#include "ui_videoplayer.h"
#include <QCoreApplication>
#include <QFileInfoList>
#include <QDir>
VideoPlayer::VideoPlayer(QMainWindow *parent)
: QMainWindow(parent)
, ui(new Ui::VideoPlayer)
{
ui->setupUi(this);
/* 视频播放器布局初始化 */
videoLayout();
/* 媒体初始化 */
mediaPlayerInit();
/* 扫描本地视频 */
scanVideoFiles();
/* 列表连接信号槽 */
connect(listWidget, SIGNAL(itemClicked(QListWidgetItem*)),
this, SLOT(listWidgetCliked(QListWidgetItem*)));
/* 媒体连接信号槽 */
connect(videoPlayer,
SIGNAL(stateChanged(QMediaPlayer::State)),
this,
SLOT(mediaPlayerStateChanged(QMediaPlayer::State)));
connect(mediaPlaylist,
SIGNAL(currentIndexChanged(int)),
this,
SLOT(mediaPlaylistCurrentIndexChanged(int)));
connect(videoPlayer, SIGNAL(durationChanged(qint64)),
this,
SLOT(mediaPlayerDurationChanged(qint64)));
connect(videoPlayer,
SIGNAL(positionChanged(qint64)),
this,
SLOT(mediaPlayerPositionChanged(qint64)));
// 加载qss文件,设置listWidget的样式表
loadStyle();
}
VideoPlayer::~VideoPlayer()
{
delete ui;
}
// 页面、列表等设计
void VideoPlayer::videoLayout()
{
/* 设置位置与大小,这里固定为800, 480 */
// this->setGeometry(0, 0, 800, 480);
QPalette pal;
pal.setColor(QPalette::WindowText, Qt::white);
/* 水平容器 */
hWidget[0] = new QWidget();
hWidget[0]->setAutoFillBackground(true);
/* 水平布局 */
hBoxLayout[0] = new QHBoxLayout();
/* 垂直容器 */
vWidget[0] = new QWidget();
vWidget[0]->setAutoFillBackground(true);
/* 垂直布局 */
vBoxLayout[0] = new QVBoxLayout();
/* 设置 */
vWidget[0]->setObjectName("vWidget_0");
// label
QFont font;
font.setPixelSize(18);
ui->label->setFont(font);
ui->label_1->setFont(font);
pal.setColor(QPalette::WindowText, Qt::white);
ui->label->setPalette(pal);
ui->label_1->setPalette(pal);
// 音量条
ui->volumeSlider->setRange(0, 100);
ui->volumeSlider->setValue(50);
// 音乐列表
listWidget = new QListWidget();
videoWidget = new QVideoWidget();
listWidget->setObjectName("listWidget");
listWidget->setVerticalScrollBarPolicy(
Qt::ScrollBarAlwaysOff);
listWidget->setHorizontalScrollBarPolicy(
Qt::ScrollBarAlwaysOff);
videoWidget->setStyleSheet("border-image: none;"
"background: transparent;"
"border:none");
/* H0布局 */
vWidget[0]->setMinimumSize(300, 480);
vWidget[0]->setMaximumWidth(300);
videoWidget->setMinimumSize(500, 480);
hBoxLayout[0]->addWidget(videoWidget);
hBoxLayout[0]->addWidget(vWidget[0]);
hWidget[0]->setLayout(hBoxLayout[0]);
hBoxLayout[0]->setContentsMargins(0, 0, 0, 0);
QMainWindow::setCentralWidget(hWidget[0]);
/* V0布局 */
QSpacerItem *vSpacer0 = new
QSpacerItem(0, 80,
QSizePolicy::Minimum,
QSizePolicy::Maximum);
vBoxLayout[0]->addWidget(listWidget);
vBoxLayout[0]->addSpacerItem(vSpacer0);
vBoxLayout[0]->setContentsMargins(0, 0, 0, 0);
vWidget[0]->setLayout(vBoxLayout[0]);
// 设置样式表
vWidget[0]->setStyleSheet("border-image:none;");
hWidget[0]->setStyleSheet("border-image:none;"
"border-image:url(:/images/bg.png)");
/* V1布局 */
/* 底板部件布局 */
ui->vBoxLayout_1->setAlignment(Qt::AlignCenter);
ui->vWidget_1->setLayout(ui->vBoxLayout_1);
ui->vWidget_1->setParent(this); // 用来切换父窗口
ui->vWidget_1->setGeometry(0, this->height() - 80, this->width(), 80);
ui->vBoxLayout_1->setContentsMargins(0, 0, 0, 0);
ui->vBoxLayout_1->setAlignment(Qt::AlignCenter);
/* 位于最上层 */
ui->vWidget_1->raise();
/* H1布局 */
ui->hBoxLayout_1->setContentsMargins(0, 0, 0, 0);
ui->hWidget_1->setLayout(ui->hBoxLayout_1);
/* H2布局 */
ui->hBoxLayout_2->setContentsMargins(0, 0, 0, 0);
ui->hBoxLayout_2->setAlignment(Qt::AlignLeft | Qt::AlignTop);
}
// 初始化
void VideoPlayer::mediaPlayerInit()
{
videoPlayer = new QMediaPlayer(this);
mediaPlaylist = new QMediaPlaylist(this);
/* 确保列表是空的 */
mediaPlaylist->clear();
/* 设置视频播放器的列表为mediaPlaylist */
videoPlayer->setPlaylist(mediaPlaylist);
/* 设置视频输出窗口 */
videoPlayer->setVideoOutput(videoWidget);
/* 设置播放模式,Loop是列循环 */
mediaPlaylist->setPlaybackMode(QMediaPlaylist::Loop);
/* 设置默认软件音量为50% */
videoPlayer->setVolume(50);
}
void VideoPlayer::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
ui->vWidget_1->setGeometry(0, this->height() - 80, this->width(), 80);
}
// 播放按钮设计
void VideoPlayer::mediaPlayerStateChanged(
QMediaPlayer::State
state)
{
switch (state) {
case QMediaPlayer::StoppedState:
ui->btn_play->setChecked(false);
break;
case QMediaPlayer::PlayingState:
ui->btn_play->setChecked(true);
break;
case QMediaPlayer::PausedState:
ui->btn_play->setChecked(false);
break;
}
}
// 播放列表设计,点击某一项后对象项的颜色背景会变化
void VideoPlayer::listWidgetCliked(QListWidgetItem *item)
{
videoPlayer->stop();
mediaPlaylist->setCurrentIndex(listWidget->row(item));
videoPlayer->play();
}
void VideoPlayer::mediaPlaylistCurrentIndexChanged(
int index)
{
if (-1 == index)
return;
/* 设置列表正在播放的项 */
listWidget->setCurrentRow(index);
}
// 视频总时长显示
void VideoPlayer::mediaPlayerDurationChanged(
qint64 duration)
{
ui->durationSlider->setRange(0, duration / 1000);
int second = duration / 1000;
int minute = second / 60;
second %= 60;
QString mediaDuration;
mediaDuration.clear();
if (minute >= 10)
mediaDuration = QString::number(minute, 10);
else
mediaDuration = "0" + QString::number(minute, 10);
if (second >= 10)
mediaDuration = mediaDuration
+ ":" + QString::number(second, 10);
else
mediaDuration = mediaDuration
+ ":0" + QString::number(second, 10);
/* 显示媒体总长度时间 */
ui->label_1->setText("/" + mediaDuration);
}
// 播放时间的进度条设计
void VideoPlayer::mediaPlayerPositionChanged(
qint64 position)
{
if (!ui->durationSlider->isSliderDown())
ui->durationSlider->setValue(position / 1000);
int second = position / 1000;
int minute = second / 60;
second %= 60;
QString mediaPosition;
mediaPosition.clear();
if (minute >= 10)
mediaPosition = QString::number(minute, 10);
else
mediaPosition = "0" + QString::number(minute, 10);
if (second >= 10)
mediaPosition = mediaPosition
+ ":" + QString::number(second, 10);
else
mediaPosition = mediaPosition
+ ":0" + QString::number(second, 10);
/* 显示现在播放的时间 */
ui->label->setText(mediaPosition);
}
// 音频文件过滤
void VideoPlayer::scanVideoFiles()
{
QDir dir(QCoreApplication::applicationDirPath()
+ "/myVideo");
QDir dirbsolutePath(dir.absolutePath());
/* 如果目录存在 */
if (dirbsolutePath.exists()) {
/* 定义过滤器 */
QStringList filter;
/* 包含所有xx后缀的文件 */
filter << "*.mp4" << "*.mkv" << "*.wmv" << "*.avi";
/* 获取该目录下的所有文件 */
QFileInfoList files =
dirbsolutePath.entryInfoList(filter, QDir::Files);
/* 遍历 */
for (int i = 0; i < files.count(); i++) {
video_MediaObjectInfo info;
/* 使用utf-8编码 */
info.fileName = QString::fromUtf8(files.at(i)
.fileName()
.toUtf8()
.data());
info.filePath = QString::fromUtf8(files.at(i)
.filePath()
.toUtf8()
.data());
/* 媒体列表添加视频 */
if (mediaPlaylist->addMedia(QUrl::fromLocalFile(info.filePath)))
{
/* 添加到容器数组里储存 */
mediaObjectInfo.append(info);
/* 添加视频名字至列表 */
listWidget->addItem(info.fileName);
} else {
qDebug()<<
mediaPlaylist->errorString()
.toUtf8().data()
<< endl;
qDebug()<< " Error number:"
<< mediaPlaylist->error()
<< endl;
}
}
}
}
// 播放按钮
void VideoPlayer::on_btn_play_clicked()
{
int state = videoPlayer->state();
switch (state) {
case QMediaPlayer::StoppedState:
/* 媒体播放 */
videoPlayer->play();
break;
case QMediaPlayer::PlayingState:
/* 媒体暂停 */
videoPlayer->pause();
break;
case QMediaPlayer::PausedState:
/* 设置视频输出窗口 */
videoPlayer->play();
break;
}
}
void VideoPlayer::on_btn_next_clicked()
{
videoPlayer->stop();
int count = mediaPlaylist->mediaCount();
if (0 == count)
return;
/* 列表下一个 */
mediaPlaylist->next();
videoPlayer->play();
}
void VideoPlayer::on_btn_volumedown_clicked()
{
/* 点击每次音量-5 */
ui->volumeSlider->setValue(ui->volumeSlider->value() - 5);
videoPlayer->setVolume(ui->volumeSlider->value());
}
void VideoPlayer::on_btn_volumeup_clicked()
{
/* 点击每次音量+5 */
ui->volumeSlider->setValue(ui->volumeSlider->value() + 5);
videoPlayer->setVolume(ui->volumeSlider->value());
}
void VideoPlayer::on_btn_screen_clicked()
{
/* 全屏/非全屏操作 */
vWidget[0]->setVisible(!ui->btn_screen->isChecked());
}
void VideoPlayer::on_durationSlider_sliderReleased()
{
/* 设置媒体播放的位置 */
videoPlayer->setPosition(ui->durationSlider->value() * 1000);
}
void VideoPlayer::on_volumeSlider_sliderReleased()
{
/* 设置音量 */
videoPlayer->setVolume(ui->volumeSlider->value());
}
void VideoPlayer::on_btn_previous_clicked()
{
videoPlayer->stop();
int count = mediaPlaylist->mediaCount();
if (0 == count)
return;
/* 列表上一个 */
mediaPlaylist->previous();
videoPlayer->play();
}
void VideoPlayer::loadStyle()
{
/* 指定文件 */
QFile file(":/style_3.qss");
/* 判断文件是否存在 */
if (file.exists() ) {
/* 以只读的方式打开 */
file.open(QFile::ReadOnly);
/* 以字符串的方式保存读出的结果 */
QString styleSheet = QLatin1String(file.readAll());
/* 设置全局样式 */
this->setStyleSheet(styleSheet);
/* 关闭文件 */
file.close();
}
}
// 视频播放器退出设计,跳转到主界面
void VideoPlayer::on_btn_exit_clicked()
{
this->hide();
videoPlayer->stop();
emit video_show_main();
}