1、界面展示
文章来源地址https://www.toymoban.com/news/detail-506380.html
2、功能简介
视频播放器的功能主要有打开文件添加视频、暂停/播放,上一个/下一页,改变音量、进度条等
3、实现思路
1、打开视频(QFielDialog)
一下选择多个视频,用QFileDialog::getOpenFileNames实现,将文件放到一个数据成员QStringlist中,使用QFileInfo info获取详细信息,filename()获取名字,再将之添加到listWidget中
2、视频列表(QlistWidget)
使用QFileInfo info获取详细信息,filename()获取名字,再将之添加到listWidget中。
3、暂停/继续(QMediaPlayer)
mediaPlayer play/[pause进行播放/暂停,记得修改图标
4、上一个/下一个(QFileInfo)
将下标修改,然后重新播放,需要重新设置媒体源
5、快退快进(QSlider)
修改进度条的value
6、截图
QScreen
9、播放顺序(QComboBox)
根据播放模式的不同。对下标进行对应的处理
10、进度条(QSlider)
时间/声音,可以滑动,修改value值
11、显示名字(QLineEdit)
滚动显示视频名字
做的时候是做了一个服务器端(Linux),一个客户端(QT),用到服务器的地方主要是登录注册以及查看历史观看的地方,只实现视频播放器的话不需要用到服务器端。
4、部分代码
#include "widget.h"
#include "ui_widget.h"
#include "clientwinmanager.h"
#include <QHostAddress>
static int socket_flag = 0;
QTcpSocket *Widget::tcpSocket = nullptr;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("ZZH视频播放器");
this->setWindowIcon(QIcon(":/image/太空兔.png"));
//创建定时器对象
this->timer = new QTimer(this);
this->timer2 = new QTimer(this);
this->timer2->start(1000);
this->resize(1280,720);
//实例化媒体播放器及视频播放
this->mediaPlayer = new QMediaPlayer(this);
this->videoWidget = new QVideoWidget(this);
//实例化布局
this->vbox = new QVBoxLayout(this);
this->vbox1 = new QVBoxLayout(this);
this->setLayout(this->vbox);//设置整个窗口为垂直布局
this->hbox1 = new QHBoxLayout(this);
this->hbox2 = new QHBoxLayout(this);
this->hbox3 = new QHBoxLayout(this);
this->hbox4 = new QHBoxLayout(this);
this->hbox5 = new QHBoxLayout(this);
//实例化按钮
this->openBtn = new QPushButton("打开",this);
this->preBtn = new QPushButton("上一个",this);
this->rewindBtn = new QPushButton("快退",this);
this->playBtn = new QPushButton("播放",this);
this->playBtn->setIcon(this->style()->standardIcon(QStyle::SP_MediaPlay));
this->forwardBtn = new QPushButton("快进",this);
this->nextBtn = new QPushButton("下一个",this);
this->shotBtn = new QPushButton("截图",this);
this->loginBtn = new QPushButton("登录",this);
this->loginBtn->setMaximumWidth(100);
this->historyBtn = new QPushButton("历史",this);
this->historyBtn->setMaximumWidth(100);
//实例化标签
this->timeLable = new QLabel("00:00:00/00:00:00",this);
this->volumeLabel = new QLabel("50",this);
this->volumeLabel->setMaximumWidth(200);
this->videoNameLabel = new QLabel("未播放",this);
this->userNameLabel = new QLabel("未登录",this);
//this->playLabel = new QLabel("无视频",this);
//实例化进度条
this->timeSlider = new QSlider(this);
this->volumeSlider = new QSlider(this);
this->volumeSlider->setOrientation(Qt::Horizontal);
this->timeSlider->setOrientation(Qt::Horizontal);
this->volumeSlider->setMaximumWidth(200);
this->volumeSlider->setRange(-1,101);
this->volumeSlider->setValue(50);
//实例化listWidget
this->listWidget = new QListWidget(this);
this->listWidget->setMaximumWidth(300);
this->listWidget->setMinimumWidth(300);
// this->playWidget = new QListWidget(this);
//this->videoWidget->setGeometry(50,50,720,480);
//this->playWidget->setGeometry(50,40,720,480);
// this->videoWidget->setMinimumSize(this->playWidget->width(),this->playWidget->height());
//实例化下拉框
this->comboBox = new QComboBox(this);
this->comboBox->addItem("顺序播放");
this->comboBox->addItem("随机播放");
this->comboBox->addItem("循环播放");
//实例化lcd
this->lcdNumber = new QLCDNumber(this);
this->lcdNumber->setDigitCount(8);
this->lcdNumber->setStyleSheet("background-color: green");//修改背景
connect(this->timer2,SIGNAL(timeout()),this,SLOT(updateTime()));
this->inde = 0;
this->n = 0;
this->dis_flag = 0;
this->his_flag = 0;
//进行布局
this->hbox1->addWidget(this->videoNameLabel);
this->hbox1->addWidget(this->lcdNumber);
this->hbox1->addWidget(this->userNameLabel);
this->hbox1->addWidget(this->historyBtn);
this->hbox1->addWidget(this->loginBtn);
//this->hbox1->addWidget(this->testBtn);
this->hbox2->addStretch();
this->hbox2->addLayout(this->vbox1);
//this->hbox2->addWidget(this->playWidget);
this->hbox2->addWidget(this->listWidget);
this->hbox3->addWidget(this->timeLable);
this->hbox3->addWidget(this->volumeLabel);
this->hbox4->addWidget(this->timeSlider);
this->hbox4->addWidget(this->volumeSlider);
this->hbox5->addWidget(this->openBtn);
this->hbox5->addWidget(this->preBtn);
this->hbox5->addWidget(this->rewindBtn);
this->hbox5->addWidget(this->playBtn);
this->hbox5->addWidget(this->forwardBtn);
this->hbox5->addWidget(this->nextBtn);
this->hbox5->addWidget(this->shotBtn);
this->hbox5->addWidget(this->comboBox);
//垂直布局
this->vbox->addLayout(this->hbox1);
this->vbox->addLayout(this->hbox2);
this->vbox->addLayout(this->hbox3);
this->vbox->addLayout(this->hbox4);
this->vbox->addLayout(this->hbox5);
//关联
connect(this->loginBtn,SIGNAL(clicked()),this,SLOT(do_loginBtn())); //登录
connect(this->openBtn,SIGNAL(clicked()),this,SLOT(do_openBtn())); //打开文件
connect(this->playBtn,SIGNAL(clicked()),this,SLOT(do_playBtn())); //播放/暂停
connect(this->preBtn,SIGNAL(clicked()),this,SLOT(do_preBtn())); //上一首
connect(this->nextBtn,SIGNAL(clicked()),this,SLOT(do_nextBtn())); //下一首
connect(this->mediaPlayer,SIGNAL(positionChanged(qint64)),this,SLOT(updateTimeSlider(qint64))); //进度条变化
connect(this->mediaPlayer,SIGNAL(durationChanged(qint64)),this,SLOT(setTimeSlider(qint64)));
connect(this->timer,SIGNAL(timeout()),this,SLOT(updateTime_NameShow())); //滚动显示名字、显示歌曲已播放时间/总时间
connect(this->rewindBtn,SIGNAL(clicked()),this,SLOT( do_rewindBtn())); //快退
connect(this->forwardBtn,SIGNAL(clicked()),this,SLOT( do_forwardBtn()));//快进
connect(this->listWidget,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(doubleClickPlay(QListWidgetItem*)));//双击播放
connect(this->volumeSlider,SIGNAL(sliderMoved(int)),this,SLOT(updateVolume(int))); //音量调节
connect(this->historyBtn,SIGNAL(clicked()),this,SLOT(do_historyBtn())); //查看历史
connect(this->shotBtn,SIGNAL(clicked()),this,SLOT(do_shotBtn())); //截图
//connect(this->testBtn,SIGNAL(clicked()),this,SLOT(do_testBtn()));
//通信
}
Widget::~Widget()
{
delete ui;
}
void Widget::setName(QString name)
{
this->userNameLabel->setText(name);
this->loginBtn->setText("登出");
}
void Widget::updateTime()
{
//获取当前时间并转换成Qstring
QString currentTime = QDateTime::currentDateTime().toString("hh:mm:ss");
//更新lcd时间
this->lcdNumber->display(currentTime);
}
//登录
#include <QMessageBox>
void Widget::do_loginBtn()
{
if(this->loginBtn->text() == "登录")
{
//1、切换到登录界面
this->tcpSocket = new QTcpSocket(this);//每次登录得时候实例化套接字
connect(this->tcpSocket, SIGNAL(connected()), this, SLOT(connectedSlot()));
clientWinManager *p = clientWinManager::getClientWin();
this->close();
p->loginWin->show();
//2、连接服务器并提示
if(socket_flag == 0)
{
this->tcpSocket->connectToHost(QHostAddress("192.168.206.212"), 9999);
socket_flag = 1;
}
}
else if (this->loginBtn->text() == "登出") {
socket_flag = 0;
this->loginBtn->setText("登录");
this->userNameLabel->setText("未登录");
//断开,拼接字符串,发给服务器
char str[100] = {'\0'};
sprintf(str,"dis");
Widget::tcpSocket->write(str);
this->tcpSocket->disconnectFromHost();
this->tcpSocket = nullptr;//bug,断开之后不能重新连接
QMessageBox::information(this,"tips","退出,断开服务器");
}
}
//打开视频文件
#include <QFileDialog>
void Widget::do_openBtn()
{
this->nameList.clear();
this->listWidget->clear();//清空表单
this->nameList = QFileDialog::getOpenFileNames(this,"select",".","MKV(*.mkv)");
if(nameList.size() == 0)
{
return;
}
for(int i = 0;i < nameList.size();i++) //循环的将选中的文件加入到listWidget
{
QFileInfo info(nameList.at(i));
QListWidgetItem *item = new QListWidgetItem(info.fileName(),this->listWidget);
this->listWidget->addItem(item);
item->setToolTip(nameList.at(i));//----------
}
QString fileName = nameList.at(0);//默认播放打开的第一个视频
this->mediaPlayer->setMedia(QUrl(fileName));//设置媒体源
QFileInfo info(fileName);//获取文件全部信息
this->videoName = info.fileName() + " ";
this->videoNameLabel->setText(this->videoName);
this->mediaPlayer->setVolume(50);//设置音量
this->vbox1->addWidget(this->videoWidget);
this->mediaPlayer->setVideoOutput(this->videoWidget);
//this->mediaPlayer->setVideoOutput(this->videoWidget);
this->mediaPlayer->play();
this->timer->start(1000);
this->playBtn->setIcon(this->style()->standardIcon(QStyle::SP_MediaPause));
if(this->userNameLabel->text() != "未登录")
{
//有用户登录,将该用户看过的视频存放到数据库
//先转换类型
char str[100] = {'\0'};
QByteArray userName = this->userNameLabel->text().toLatin1();//用户名
QByteArray vidName = this->videoName.toLatin1(); //视频名字
sprintf(str,"His#%s#%s",userName.data(),vidName.data()); //拼接字符串
qDebug() << videoName.data();
Widget::tcpSocket->write(str);
}
}
//播放/暂停
void Widget::do_playBtn()
{
int state = this->mediaPlayer->state();
if(state == QMediaPlayer::PlayingState)
{
//正在播放,暂停播放,图标修改成播放
this->mediaPlayer->pause();
this->playBtn->setText("播放");
this->playBtn->setIcon(this->style()->standardIcon(QStyle::SP_MediaPlay));
}
else if (state == QMediaPlayer::PausedState) {
//暂停,继续播放,图标修改为暂停
this->mediaPlayer->play();
this->playBtn->setText("暂停");
this->playBtn->setIcon(this->style()->standardIcon(QStyle::SP_MediaPause));
}
}
//上一个
void Widget::do_preBtn()
{
this->inde--;
if(this->inde < 0)
{
this->inde = this->nameList.size() - 1;
}
this->mediaPlayer->stop();
QFileInfo fileName(this->nameList.at(this->inde));//获取文件信息
this->mediaPlayer->setMedia(QUrl(this->nameList.at(this->inde)));//设置媒体源
this->videoNameLabel->setText(fileName.fileName());//修改标题
this->mediaPlayer->setVideoOutput(this->videoWidget);
this->videoName = fileName.fileName();
this->mediaPlayer->play();
this->timer->start(1000);
if(this->userNameLabel->text() != "未登录")
{
//有用户登录,将该用户看过的视频存放到数据库
//先转换类型
char str[100] = {'\0'};
QByteArray userName = this->userNameLabel->text().toLatin1();//用户名
QByteArray vidName = fileName.fileName().toLatin1(); //视频名字
sprintf(str,"His#%s#%s",userName.data(),vidName.data()); //拼接字符串
Widget::tcpSocket->write(str);
}
}
//下一个
void Widget::do_nextBtn()
{
this->inde++;
if(this->inde > this->nameList.size() - 1)
{
this->inde = 0;
}
this->mediaPlayer->stop();
QFileInfo fileName(this->nameList.at(this->inde));//获取文件信息
this->mediaPlayer->setMedia(QUrl(this->nameList.at(this->inde)));//设置媒体源
this->videoNameLabel->setText(fileName.fileName());//修改标题
this->mediaPlayer->setVideoOutput(this->videoWidget);
this->videoName = fileName.fileName();
this->mediaPlayer->play();
this->timer->start(1000);
if(this->userNameLabel->text() != "未登录")
{
//有用户登录,将该用户看过的视频存放到数据库
//先转换类型
char str[100] = {'\0'};
QByteArray userName = this->userNameLabel->text().toLatin1();//用户名
QByteArray vidName = fileName.fileName().toLatin1(); //视频名字
sprintf(str,"His#%s#%s",userName.data(),vidName.data()); //拼接字符串
Widget::tcpSocket->write(str);
}
}
//给进度条设置范围
void Widget::setTimeSlider(qint64 duration)
{
this->timeSlider->setRange(0,int(duration));
}
//根据视频播放的位置修改进度条
void Widget::updateTimeSlider(qint64 position)
{
this->timeSlider->setValue(int(position));
}
//滚动显示名字、修改文本时间
//实现播放模式
#include <QFileInfo>
void Widget::updateTime_NameShow()
{
/*
根据n的值显示内容
*/
this->n++;
if(this->n == this->videoName.size())
{
this->n = 0;
}
this->videoNameLabel->setText(this->videoName.mid(this->n));//滚动显示
//获取总时间跟当前播放时长
qint64 dur = this->mediaPlayer->duration();
qint64 pos = this->mediaPlayer->position();
//实例化两个对象,用来显示
QTime durTime(0,0,0);
QTime posTime(0,0,0);
this->timeLable->setText(posTime.addMSecs(int(pos)).toString("mm:ss") + "/" + durTime.addMSecs(int(dur)).toString("mm:ss"));
//根据播放模式进行播放
/*
* 1、顺序播放,下标++,最后一首的时候,下标置为0(dur == pos的时候结束)
* 2、随机播放,qrand()给下标一个随机值
* 3、循环播放,下表不变
*/
if(dur == pos)
{
if(this->comboBox->currentText() == "顺序播放")
{
this->inde++;
if(this->inde > this->nameList.size() - 1)
{
this->inde = 0;
}
}
else if (this->comboBox->currentText() == "随机播放") {
this->inde = qrand() % this->nameList.size();
}
else if (this->comboBox->currentText() == "循环播放"){
this->inde = this->inde+0;
}
// 开始播放()
QFileInfo fileName(this->nameList.at(this->inde));//获取文件信息
this->mediaPlayer->setMedia(QUrl(this->nameList.at(this->inde)));//设置媒体源
this->videoNameLabel->setText(fileName.fileName());//修改标题
this->mediaPlayer->setVideoOutput(this->videoWidget);
this->mediaPlayer->play();
this->timer->start(1000);
}
}
//快退,播放时间减少5s
#include <QMessageBox>
void Widget::do_rewindBtn()
{
//判断当前播放时间是否小于5s
//判断完之后要修改文本、滑动块,
//获取总时间跟当前播放时长
qint64 dur = this->mediaPlayer->duration();
qint64 pos = this->mediaPlayer->position();
//实例化两个对象,用来显示
qDebug() << int(pos);
QTime durTime(0,0,0);
QTime posTime(0,0,0);
if(int(pos) <= 5000)
{
this->timeSlider->setValue(0);
this->mediaPlayer->setPosition(0);
this->timeLable->setText(posTime.addMSecs(0).toString("mm:ss") + "/" + durTime.addMSecs(int(dur)).toString("mm:ss"));
}
else {
this->timeSlider->setValue(int(pos) - 5000);
this->mediaPlayer->setPosition(int(pos) - 5000);
this->timeLable->setText(posTime.addMSecs(int(pos)-5000).toString("mm:ss") + "/" + durTime.addMSecs(int(dur)).toString("mm:ss"));
}
}
//快进
void Widget::do_forwardBtn()
{
//判断剩余播放时间是否小于5s
//获取总时间跟当前播放时长
qint64 dur = this->mediaPlayer->duration();
qint64 pos = this->mediaPlayer->position();
//实例化两个对象,用来显示
QTime durTime(0,0,0);
QTime posTime(0,0,0);
if(int(dur)-int(pos) <=5000)
{
this->timeSlider->setValue(int(dur));
this->mediaPlayer->setPosition(int(dur));
this->timeLable->setText(posTime.addMSecs(int(dur)).toString("mm:ss") + "/" + durTime.addMSecs(int(dur)).toString("mm:ss"));
}
else {
this->timeSlider->setValue(int(pos) + 5000);
this->mediaPlayer->setPosition(int(pos) + 5000);
this->timeLable->setText(posTime.addMSecs(int(pos)+5000).toString("mm:ss") + "/" + durTime.addMSecs(int(dur)).toString("mm:ss"));
}
}
void Widget::doubleClickPlay(QListWidgetItem *item)//参数为双击的目标信息
{
/*
* 1、获取listWidget中下标位置
2、设置媒体源、播放选中的歌曲
3、修改名字
4、修改图标
5、定时器启动
*/
this->inde = this->listWidget->currentRow(); //获取当前下标
this->mediaPlayer->setMedia(QUrl(item->toolTip()));
this->videoNameLabel->setText(item->text());
this->videoName = item->text();
qDebug() << videoName;
this->mediaPlayer->play();
this->timer->start(1000);
this->playBtn->setIcon(this->style()->standardIcon(QStyle::SP_MediaPause));
if(this->userNameLabel->text() != "未登录")
{
//有用户登录,将该用户看过的视频存放到数据库
//先转换类型
char str[100] = {'\0'};
QByteArray userName = this->userNameLabel->text().toLatin1();//用户名
QByteArray vidName = item->text().toLatin1(); //视频名字
sprintf(str,"His#%s#%s",userName.data(),vidName.data()); //拼接字符串
qDebug() << userName.data();
Widget::tcpSocket->write(str);
}
}
//修改音量
#include <string.h>
void Widget::updateVolume(int positoin)
{
this->mediaPlayer->setVolume(positoin); //修改媒体音量
// strcat("音量:",this->volumeSlider->value());
int i = this->volumeSlider->value();
this->volumeLabel->setText(QString::number(i)); //将int转换成对应的类型,修改文本
}
void Widget::do_historyBtn()
{
//用户只有才能查看观看历史,没登录提示用户登录
if(this->userNameLabel->text() == "未登录")
{
QMessageBox::warning(this,"tips","请先登录");
}
else {
//获取历史记录,存放到listWidget中
//先获取有几条记录,再循环的获取具体信息,先清空,通过addItem加
//先给服务器端发送要接收历史记录的消息
if(this->his_flag == 0)
{
this->his_flag = 1;
char str[100] = {'\0'};
QByteArray userName = this->userNameLabel->text().toLatin1();//用户名
sprintf(str,"Get#%s",userName.data());
connect(Widget::tcpSocket,SIGNAL(readyRead()),this,SLOT(readData()));
Widget::tcpSocket->write(str);
}
}
}
//截图
#include <QScreen>
void Widget::do_shotBtn()
{
qDebug()<<"shot";
QScreen *screen = QGuiApplication::primaryScreen();
//拼接图片的名字
QString filePathName = "cut-";
filePathName += QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss-zzz");
filePathName += ".png";
QPixmap pixmap = screen->grabWindow(0);
if(!pixmap.save(filePathName,"png"))
{
qDebug()<<"cut save png failed"<<endl;
}
QRect geo = this->geometry();
QRect appGeo = geo; // 整个应用程序在图片中的位置。
geo = this->videoWidget->geometry(); // 播放视频在图片中的位置。
QRect copyGeo;
copyGeo.setX(geo.x() + appGeo.x() ); // x=三个x相加
copyGeo.setY(geo.y() + appGeo.y() );
copyGeo.setWidth(geo.width());
copyGeo.setHeight(geo.height());
QPixmap pixmapCopy = pixmap.copy(copyGeo); // copy图片
filePathName.prepend("Copy+");
if(pixmapCopy.save(filePathName,"png"))
{
QMessageBox::information(this,"tips","截取成功");
}
}
//接收消息
void Widget::readData()
{
//接收历史观看,一行一行显示,以#分割
if(this->his_flag == 1)
{
QByteArray recv = Widget::tcpSocket->read(128); //读取数据
QString str = QString(recv);//格式转换,重新走下构造
qDebug()<< recv;
//先获取数据的数量
QStringList list = str.split('#');
int size = str.split("#").at(0).toInt();
this->listWidget->clear();//清空之前显示的内容
//以#分割开
for(int i = 1;i <= size;i++)
{
QString chr = list[i];
this->listWidget->addItem(chr);
}
this->his_flag = 0;
}
}
//连接服务器端
void Widget::connectedSlot(){
QMessageBox::information(this,"tips","连接服务器成功");
}
文章来源:https://www.toymoban.com/news/detail-506380.html
到了这里,关于qt实现简单的视频播放器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!