问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Qt项目实战:基于QMediaPlayer开发视频播放器

创作时间:
作者:
@小白创作中心

Qt项目实战:基于QMediaPlayer开发视频播放器

引用
1
来源
1.
https://www.cnblogs.com/ybqjymy/p/18020952

本文基于Qt 5.12版本,介绍了如何使用QMediaPlayer开发一个简单的视频播放器。文章详细讲解了从项目配置到代码实现的全过程,并展示了如何在界面上添加QVideoWidget控件以及如何创建右键菜单。需要注意的是,Qt的最新版本已经更新到Qt 6.x,因此在实际开发中可能需要根据具体版本对代码进行适当调整。

QMediaPlayer开发视频播放器

Q: 我们为何不使用QMediaPlayer?

A:QMediaPlayer支持的编解码库太少;QMediaPlayer在Windows中解码调用的是DirectShow,在Linux中调用的是GStreamer;相对Windows而言GStreamer扩展编解码库比较方便,但是Windows中的DirectShow太老了,Demuxer Decoder都比较麻烦。

QtMultimediaDemo 这个例子为老师编写的基于QMediaPlayer的播放器,它可以播放MPEG-4编码方式的视频。

使用QMediaPlayer搭建最简单的播放器

step1: pro文件添加内容

QT += core gui multimedia multimediawidgets

step2: 框架

step3: 测试代码

#include "widget.h"

#include <QApplication>
#include <QMediaPlayer>
#include <QVideoWidget>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 创建一个MediaPlayer
    QMediaPlayer *player = new QMediaPlayer;

    // 创建一个播放器窗口(Widget),用于显示MediaPlayer
    QVideoWidget *vw = new QVideoWidget;

    // 将player绑定到显示的窗口上
    player->setVideoOutput(vw);

    // 打开播放器的位置
    player->setSource(QUrl::fromLocalFile("G:/video_test/video-h265.mkv"));
    vw->setGeometry(100,100,640,480);
    vw->show();
    // Widget w;
    // w.show();
    return a.exec();
}

如何添加不是“非基本图形控件”的派生类

需求:需要在界面上直接拖一个 QVideoWidget,由于基本控件中没有QVideoWidget,所以需要想想办法

新建提升的类

因为QVideoWidget本身就继承于QWidget,所以这里选择QWidget作为基类

控件进行提升

成功播放视频

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QMediaPlayer>
#include <QVideoWidget>
#include <QMenu>
#include <QFileDialog>
#include <QFile>
#include <QDir>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

protected:
    virtual void contextMenuEvent(QContextMenuEvent *event);

private:
    void createRightPopActions();

private slots:
    void openLocalVideoSlot();
    void openUrlVideoSlot();

private:
    Ui::Widget *ui;
    QMenu *popMenu; //右键弹出式菜单
    QAction *openLocalAction; //打开本地文件
    QAction *openUrlAction; //打开网络文件
    QAction *fullScreenAction; //全屏显示
    QAction *normalScreenAction; //普通显示
    QAction *quitAction; //退出

    QMediaPlayer *player;

    //QVideoWidget* vw; //不需要了,界面上已经拖了一个QVideoWidget进去了
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget),
    player(new QMediaPlayer) //创建一个MediaPlayer
{
    ui->setupUi(this);

    createRightPopActions();

    player->setVideoOutput(ui->av_widget); //把player绑定到显示窗口上
}

/* 右键弹出 Menu & Action */
void Widget::createRightPopActions()
{
    popMenu = new QMenu(this);
    popMenu->setStyleSheet("background-color: rgb(100, 100, 100);");

    openLocalAction = new QAction(this);
    openLocalAction->setText(QString("打开本地文件"));

    openUrlAction = new QAction(this);
    openUrlAction->setText(QString("打开本地文件"));

    fullScreenAction = new QAction(this);
    fullScreenAction->setText(QString("全屏"));

    normalScreenAction = new QAction(this);
    normalScreenAction->setText(QString("普通"));

    quitAction = new QAction(this);
    quitAction->setText(QString("退出"));

    connect(openLocalAction, SIGNAL(triggered(bool)), this, SLOT(openLocalVideoSlot()));
    connect(openUrlAction, SIGNAL(triggered(bool)), this, SLOT(openUrlVideoSlot()));
    connect(fullScreenAction, &QAction::triggered, this, &Widget::showFullScreen);
    connect(normalScreenAction, &QAction::triggered, this, &Widget::showNormal);
    connect(quitAction, &QAction::triggered, this, &Widget::close);
}

void Widget::openLocalVideoSlot()
{
    QString file = QFileDialog::getOpenFileName(this, tr("Open file"),
                                               QDir::homePath(),
                                               tr("Multimedia files(*)"));

    if (file.isEmpty())
        return;

    player->setSource(QUrl::fromLocalFile(file)); //设置需要打开的媒体文件

    player->play();
}

void Widget::openUrlVideoSlot()
{

}

/*右键菜单接口*/
void Widget::contextMenuEvent(QContextMenuEvent *event)
{
    Q_UNUSED(event); //未使用不警告
    popMenu->clear();

    popMenu->addAction(openLocalAction);
    popMenu->addAction(openUrlAction);
    popMenu->addAction(fullScreenAction);
    popMenu->addAction(normalScreenAction);
    popMenu->addAction(quitAction);

    popMenu->exec(QCursor::pos());//QAction *exec(const QPoint &pos, QAction *at = Q_NULLPTR);
}

Widget::~Widget()
{
    delete ui;
}

无边框的视屏

布局器边框都设置为zero,设置widget的背景颜色为666

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号