前言
本篇文章将使用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即可领取。