前言

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

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐