1、界面展示
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->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);
this->listWidget = new QListWidget(this);
this->listWidget->setMaximumWidth(300);
this->listWidget->setMinimumWidth(300);
this->comboBox = new QComboBox(this);
this->comboBox->addItem("顺序播放");
this->comboBox->addItem("随机播放");
this->comboBox->addItem("循环播放");
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->hbox2->addStretch();
this->hbox2->addLayout(this->vbox1);
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()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::setName(QString name)
{
this->userNameLabel->setText(name);
this->loginBtn->setText("登出");
}
void Widget::updateTime()
{
QString currentTime = QDateTime::currentDateTime().toString("hh:mm:ss");
this->lcdNumber->display(currentTime);
}
#include <QMessageBox>
void Widget::do_loginBtn()
{
if(this->loginBtn->text() == "登录")
{
this->tcpSocket = new QTcpSocket(this);
connect(this->tcpSocket, SIGNAL(connected()), this, SLOT(connectedSlot()));
clientWinManager *p = clientWinManager::getClientWin();
this->close();
p->loginWin->show();
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;
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++)
{
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->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()
{
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"));
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);
}
}
#include <QMessageBox>
void Widget::do_rewindBtn()
{
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()
{
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)
{
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);
int i = this->volumeSlider->value();
this->volumeLabel->setText(QString::number(i));
}
void Widget::do_historyBtn()
{
if(this->userNameLabel->text() == "未登录")
{
QMessageBox::warning(this,"tips","请先登录");
}
else {
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() );
copyGeo.setY(geo.y() + appGeo.y() );
copyGeo.setWidth(geo.width());
copyGeo.setHeight(geo.height());
QPixmap pixmapCopy = pixmap.copy(copyGeo);
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","连接服务器成功");
}