QT项目实战(视频播放器)
@TOC
前言
本篇文章将使用QT6.4来实现一个简单视频播放器,在QT中使用一个视频播放器还是非常简单的。那么下面就让我们一起来实现这个视频播放器吧。
一、QMediaPlayer
QMediaPlayer是Qt多媒体框架中的一个组件,它可以用于播放音频和视频文件。它使用了跨平台的Qt音频和视频后端,并兼容多种音频和视频格式,包括:MP3、WAV、OGG、AAC等音频格式,以及MPEG、AVI等视频格式。
使用QMediaPlayer需要先创建一个QMediaPlayer对象,然后调用setSource()函数来指定要播放的媒体文件。在调用play()函数后,QMediaPlayer对象会自动开始播放所指定的媒体文件。您还可以使用pause()函数和stop()函数来暂停和停止媒体播放。
QMediaPlayer还提供了一系列的信号和槽函数,使得用户可以在媒体播放期间捕获和处理多种事件,例如:播放出错、播放结束、媒体信息更新、媒体状态改变等等。使用这些信号和槽函数可以实现一些有趣和有用的功能,例如:精确控制播放进度、动态显示媒体元数据、同时播放多个媒体文件等等。
在使用这个类时需要在.pro文件中加上QT += multimedia
二、QVideoWidget
QVideoWidget是Qt框架中的组件之一,它提供了一个用于显示视频的自定义窗口。您可以将QVideoWidget添加到应用程序的用户界面中,然后使用QMediaPlayer或其他支持Qt视频框架的组件将视频播放到该窗口中。
使用QVideoWidget,您可以轻松实现视频播放器的自定义UI,例如:显示视频标题和长度、调整播放音量、显示屏幕截图和元数据等。QVideoWidget还可以处理一些常见的视频操作,例如全屏模式、视频缩放和窗口大小更改。
三、QAudioOutput
QAudioOutput是Qt框架中的一个组件,可用于播放音频数据。它使用了跨平台的Qt音频后端,并兼容多种音频格式,包括:WAV、MP3、AAC和OGG等。可以使用QAudioOutput将音频数据播放到扬声器或其他音频设备中,并可以控制播放进度、音量和状态等属性。
四、播放器代码实现
注释已经将重点部分都写出来了,这里我就不多介绍了。
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMediaPlayer>
#include <QVideoWidget>
#include <QAudioOutput>
#include <QPushButton>
#include <QSlider>
#include <QHBoxLayout>
#include <QLabel>
#include <QTime>
class Widget : public QWidget
{
Q_OBJECT
QMediaPlayer* player;
QVideoWidget* videoWidget;
QAudioOutput* audiooutput;
QPushButton* m_voicebutton;
QSlider* m_voiceslider;
QPushButton* m_speedbutton;
QLabel* m_speedlabel;
QSlider* m_speedslider;
QSlider* m_Progressslider;
QPushButton* m_palybutton;
QPushButton* m_stopbutton;
QPushButton* m_backbutton;
QPushButton* m_aheadbutton;
QPushButton* m_selectbutton;
QPushButton* m_fullscreen;
QLabel* m_timelabel;
QHBoxLayout* hlayout;
QString m_resource;
int m_voice;
QString totalFormattedTime;
QString currentFormattedTime;
void Init();
void ButtonStyleSet(QPushButton* button, QString IconPath);
public:
Widget(QWidget *parent = nullptr);
~Widget();
protected slots:
void voiceclick();
void voicechange(int voice);
void playclick();
void stopclick();
void getduration(qint64 duration);
void VideoPosChange(qint64 position);
void ProgressChange(int pos);
void aheadclick();
void backclick();
void GetPlayResource();
void SpeedChange(int value);
};
#endif // WIDGET_H
widget.cpp:
#include "widget.h"
#include <QVBoxLayout>
#include <QIcon>
#include <QDebug>
#include <QHBoxLayout>
#include <QPalette>
Widget::Widget(QWidget *parent): QWidget(parent), m_voice(50),
currentFormattedTime("00:00")
{
audiooutput = new QAudioOutput();
QVBoxLayout* vlayout = new QVBoxLayout(this);
hlayout = new QHBoxLayout();
player = new QMediaPlayer;
player->setPlaybackRate(1.0);//默认1倍速播放
videoWidget = new QVideoWidget(this);
videoWidget->setAspectRatioMode(Qt::IgnoreAspectRatio);//缩放适应videoWidget的大小
player->setVideoOutput(videoWidget);//设置播放窗口
player->setAudioOutput(audiooutput);//设置声音
audiooutput->setVolume(m_voice);//初始音量为50
Init();//UI控件初始化
vlayout->addWidget(videoWidget, 8);
vlayout->addWidget(m_Progressslider, 1);
vlayout->addLayout(hlayout, 0);
connect(player, SIGNAL(durationChanged(qint64)), this, SLOT(getduration(qint64)));
connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(VideoPosChange(qint64)));
videoWidget->show();//显示视频界面
setFixedSize(1024, 600);
}
void Widget::ButtonStyleSet(QPushButton* button, QString IconPath)
{
// 设置图像
button->setIcon(QIcon(IconPath));
button->setFlat(true);//去除边框
button->setStyleSheet("QPushButton:hover {background-color: grey;} QPushButton:pressed {background-color: darkGrey;}");
}
void Widget::Init()
{
/*声音控件*/
m_voicebutton = new QPushButton();
ButtonStyleSet(m_voicebutton, ":/voice.png");
m_voiceslider = new QSlider(Qt::Horizontal);
m_voiceslider->setValue(50);
m_voiceslider->setRange(0, 100);
/*倍速控件*/
m_speedbutton = new QPushButton();
ButtonStyleSet(m_speedbutton, ":/speed.png");
m_speedlabel = new QLabel();
m_speedslider = new QSlider(Qt::Horizontal);
m_speedslider->setRange(0, 8);//0-4倍速
m_speedslider->setTickInterval(1);
m_speedslider->setValue(4);
m_speedlabel->setText(QString::number(4.0 * 2.0 / 8.0, 'g', 3) + QString("倍速"));
/*控制视频播放按键*/
m_palybutton = new QPushButton();
ButtonStyleSet(m_palybutton, ":/play.png");
m_stopbutton = new QPushButton();
ButtonStyleSet(m_stopbutton, ":/stop.png");
m_backbutton = new QPushButton();
ButtonStyleSet(m_backbutton, ":/back.png");
m_aheadbutton = new QPushButton();
ButtonStyleSet(m_aheadbutton, ":/ahead.png");
m_fullscreen = new QPushButton();
ButtonStyleSet(m_fullscreen, ":/Fullscreen.png");
m_selectbutton = new QPushButton();
ButtonStyleSet(m_selectbutton, ":/select.png");
/*视频进度条*/
m_Progressslider = new QSlider(Qt::Horizontal);
m_Progressslider->setRange(0, 100);//设置进度条范围
m_Progressslider->setValue(0);//初始值为0
/*显示时间label*/
m_timelabel = new QLabel();
hlayout->addWidget(m_voicebutton);
hlayout->addWidget(m_voiceslider);
hlayout->addStretch();
hlayout->addWidget(m_speedbutton);
hlayout->addWidget(m_speedslider);
hlayout->addWidget(m_speedlabel);
hlayout->addStretch();
hlayout->addWidget(m_palybutton);
hlayout->addWidget(m_stopbutton);
hlayout->addWidget(m_backbutton);
hlayout->addWidget(m_aheadbutton);
hlayout->addWidget(m_selectbutton);
hlayout->addWidget(m_fullscreen);
hlayout->addWidget(m_timelabel);
connect(m_voicebutton, SIGNAL(clicked()), this, SLOT(voiceclick()));
connect(m_voiceslider, SIGNAL(valueChanged(int)), this, SLOT(voicechange(int)));
connect(m_palybutton, SIGNAL(clicked()), this, SLOT(playclick()));
connect(m_stopbutton, SIGNAL(clicked()), this, SLOT(stopclick()));
connect(m_Progressslider, SIGNAL(valueChanged(int)), this, SLOT(ProgressChange(int)));
connect(m_aheadbutton, SIGNAL(clicked()), this, SLOT(aheadclick()));
connect(m_backbutton, SIGNAL(clicked()), this, SLOT(backclick()));
connect(m_selectbutton, SIGNAL(clicked()), this, SLOT(GetPlayResource()));
connect(m_speedslider, SIGNAL(valueChanged(int)), this, SLOT(SpeedChange(int)));
}
Widget::~Widget()
{
}
videoslot.cpp:
#include "widget.h"
#include <QDebug>
#include <QIcon>
#include <QFile>
#include <QFileDialog>
void Widget::voiceclick()
{
static int i = 0;
i = !i;
if(i == 1)
{
audiooutput->setVolume(0);//静音
ButtonStyleSet(m_voicebutton, ":/novoice.png");
}
else if(i == 0)
{
audiooutput->setVolume(m_voice);//设置回到之前的音量
ButtonStyleSet(m_voicebutton, ":/voice.png");
}
}
void Widget::voicechange(int voice)
{
audiooutput->setVolume(voice);
if(voice == 0)
{
ButtonStyleSet(m_voicebutton, ":/novoice.png");
}
else
{
ButtonStyleSet(m_voicebutton, ":/voice.png");
}
}
/*继续播放*/
void Widget::playclick()
{
player->play();
}
/*暂停视频播放*/
void Widget::stopclick()
{
player->pause();
}
void Widget::ProgressChange(int pos)
{
if(m_Progressslider->isSliderDown())
{
player->setPosition(pos * player->duration() / 100);
}
}
/*获得视频播放总时间*/
void Widget::getduration(qint64 duration)
{
QTime totalTime = QTime(0, 0, 0, 0);
totalTime = totalTime.addMSecs(duration); // 将视频的总时长(毫秒)添加到 QTime 对象中
totalFormattedTime = totalTime.toString("mm:ss"); // 转换 QTime 对象到分:秒格式字符串
m_timelabel->setText(currentFormattedTime + " / " + totalFormattedTime);
}
/*按下按键在当前的基础上前进10s*/
void Widget::aheadclick()
{
qint64 currentpos = player->position();
player->setPosition(currentpos + 10000);//在原来的基础上前进10s
}
/*按下按键在当前的基础上后退10s*/
void Widget::backclick()
{
qint64 currentpos = player->position();
player->setPosition(currentpos - 10000);//在原来的基础上前进10s
}
/*当视频播放时进度条改变调用此函数*/
void Widget::VideoPosChange(qint64 position)
{
if(m_Progressslider->isSliderDown())
{
// 如果正在手动滑动条,则直接退出
return;
}
m_Progressslider->setSliderPosition(100 * position / player->duration());
QTime currentTime(0, 0, 0, 0); // 初始化一个时间为0的QTime对象
currentTime = currentTime.addMSecs(player->position()); // 将当前播放时间(毫秒)添加到 QTime 对象中
currentFormattedTime = currentTime.toString("mm:ss"); // 转换 QTime 对象到分:秒格式字符串
m_timelabel->setText(currentFormattedTime + " / " + totalFormattedTime);
}
/*获得选择的播放源路径并播放*/
void Widget::GetPlayResource()
{
m_resource = QFileDialog::getOpenFileName(this, tr("选择播放源"), "D:/VIdeo", tr("MP4 Files(*.mp4)"));
player->setSource(QUrl::fromLocalFile(m_resource));//设置播放资源
player->play();//播放视频
}
/*倍速设置*/
void Widget::SpeedChange(int value)
{
m_speedlabel->setText(QString::number(value * 2.0 / 8.0, 'g', 3) + QString("倍速"));
player->setPlaybackRate(value * 2.0 / 8.0);//设置倍速播放
}
五、最终效果
总结
源代码整理好后将放入微信公众号中,回复9即可领取。
- 点赞
- 收藏
- 关注作者
评论(0)