大家好,又见面了,我是你们的朋友全栈君。
本篇博客介绍如何利用qMediaPlayer和qvideowidget实现视频文件(avi,mp4….)的播放,并且提供进度显示,还可以通过拖动进度条来变换播放位置。相关代码可以在我的资源里下载”基于qt的视频播放器”
pro文件:
代码语言:javascript复制#-------------------------------------------------
#
# Project created by QtCreator 2018-11-02T20:03:58
#
#-------------------------------------------------
QT = core gui multimedia multimediawidgets
greaterThan(QT_MAJOR_VERSION, 4): QT = widgets
TARGET = VideoPlayer
TEMPLATE = app
SOURCES = main.cpp
videoplayer.cpp
playerslider.cpp
HEADERS =
videoplayer.h
playerslider.h
FORMS =
videoplayer.ui
main.cpp
代码语言:javascript复制#include "videoplayer.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
VideoPlayer w;
w.show();
return a.exec();
}
VideoPlayer是我定义的播放器窗体类。它包括一个QMediaplayer,一个QVideoWidget,一个播放按钮,一个停止按钮,一个载入按钮,和进度条PlayerSlider。VideoPlayer的ui文件外观如图:
这里面的PlayerSlider继承自QSlider,行为定义如下:
代码语言:javascript复制#ifndef PLAYERSLIDER_H
#define PLAYERSLIDER_H
#include <QSlider>
#include <QMouseEvent>
class PlayerSlider : public QSlider
{
Q_OBJECT
public:
PlayerSlider(QWidget * parent = 0);
void setProgress(qint64);
signals:
void sigProgress(qint64);
private:
bool m_bPressed;
protected:
void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
};
#endif // PLAYERSLIDER_H
代码语言:javascript复制#include "playerslider.h"
PlayerSlider::PlayerSlider(QWidget * parent) : QSlider(parent)
{
m_bPressed = false;
}
void PlayerSlider::mousePressEvent(QMouseEvent *e)
{
m_bPressed = true;
QSlider::mousePressEvent(e);//必须有这句,否则手动不能移动滑块
}
void PlayerSlider::mouseMoveEvent(QMouseEvent *e)
{
QSlider::mouseMoveEvent(e);//必须有这句,否则手动不能移动滑块
}
void PlayerSlider::mouseReleaseEvent(QMouseEvent *e)
{
m_bPressed = false;
qint64 i64Pos = value();
emit sigProgress(i64Pos);
QSlider::mouseReleaseEvent(e);//必须有这句,否则手动不能移动滑块
}
void PlayerSlider::setProgress(qint64 i64Progress)
{
if(!m_bPressed)
setValue(i64Progress);
}
这个类的作用有3个:1)接收QMediaPlaer发来的进度信息,更新进度条;2)当用户操作进度条时,不再让进度条响应QMediaPlaer发来的进度信息;3)当用户完成对进度条的拖动后,向QMediaPlaer发送播放位置更新信息。
另一个类是VideoPlayer,行为定义如下:
代码语言:javascript复制#ifndef VIDEOPLAYER_H
#define VIDEOPLAYER_H
#include <QWidget>
#include <QtMultimedia>
#include <QVideoWidget>
namespace Ui {
class VideoPlayer;
}
class VideoPlayer : public QWidget
{
Q_OBJECT
public:
explicit VideoPlayer(QWidget *parent = 0);
~VideoPlayer();
bool m_bReLoad;
public slots:
void OnSetMediaFile(void);
void OnSlider(qint64);
void OnDurationChanged(qint64);
void OnStateChanged(QMediaPlayer::State);
private:
QVideoWidget * m_pPlayerWidget;
QMediaPlayer * m_pPlayer;
Ui::VideoPlayer *ui;
};
#endif // VIDEOPLAYER_H
代码语言:javascript复制#include "videoplayer.h"
#include "ui_videoplayer.h"
#include <QFileDialog>
VideoPlayer::VideoPlayer(QWidget *parent) :
QWidget(parent),
ui(new Ui::VideoPlayer)
{
ui->setupUi(this);
m_pPlayer = new QMediaPlayer;
m_pPlayerWidget = new QVideoWidget;
m_pPlayer->setVideoOutput(m_pPlayerWidget);
ui->verticalLayout->addWidget(m_pPlayerWidget);
m_pPlayerWidget->setAutoFillBackground(true);
QPalette qplte;
qplte.setColor(QPalette::Window, QColor(0,0,0));
m_pPlayerWidget->setPalette(qplte);
//载入
connect(ui->BtnLoad, SIGNAL(clicked()), this, SLOT(OnSetMediaFile()));
//播放
connect(ui->BtnPlay, SIGNAL(clicked()), m_pPlayer, SLOT(play()));
//停止
connect(ui->BtnStop, SIGNAL(clicked()), m_pPlayer, SLOT(stop()));
connect(m_pPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(OnStateChanged(QMediaPlayer::State)));
ui->BtnStop->setEnabled(false);
//设置滑块行为
m_bReLoad = true;
ui->slider->setEnabled(false);
connect(m_pPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(OnSlider(qint64)));
connect(m_pPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(OnDurationChanged(qint64)));
connect(ui->slider, SIGNAL(sigProgress(qint64)), m_pPlayer, SLOT(setPosition(qint64)));
}
VideoPlayer::~VideoPlayer()
{
delete m_pPlayer;
delete m_pPlayerWidget;
delete ui;
}
void VideoPlayer::OnSetMediaFile(void)
{
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::AnyFile);
QStringList fileNames;
if (dialog.exec())
fileNames = dialog.selectedFiles();
if(!fileNames.empty())
{
m_pPlayer->setMedia(QUrl::fromLocalFile(fileNames[0]));
m_bReLoad = true;
ui->slider->setValue(0);
}
}
void VideoPlayer::OnSlider(qint64 i64Pos)
{
ui->slider->setProgress(i64Pos);
}
void VideoPlayer::OnDurationChanged(qint64 i64Duration)
{
if(i64Duration > 0 && m_bReLoad)
{
ui->slider->setRange(0, i64Duration);
m_bReLoad = false;
}
}
void VideoPlayer::OnStateChanged(QMediaPlayer::State enumState)
{
if(QMediaPlayer::StoppedState == enumState)
{
ui->BtnPlay->setEnabled(true);
ui->BtnStop->setEnabled(false);
ui->slider->setEnabled(false);
}
else if(QMediaPlayer::PlayingState == enumState)
{
ui->BtnPlay->setEnabled(false);
ui->BtnStop->setEnabled(true);
ui->slider->setEnabled(true);
}
}
之所以在他的构造函数里设置QPalette,是因为假如不这样,在程序启动时,m_pPlayer不是黑色,而是与背景同样的颜色,显得不好看。
显示效果:
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/134339.html原文链接:https://javaforall.cn