libvlc视频播放器: 在播放界面上叠加自定义窗口

举报
DS小龙哥 发表于 2022/02/28 09:43:18 2022/02/28
【摘要】 libvlc采用窗口ID嵌入方式渲染视频不能使用常规方式直接在窗体上加控件,需要使用子窗口方式附加窗体上去。在播放窗口上叠加窗口可以显示自定义的一些提示内容,以及播放器的控制按钮等等,功能需求很常见。

一、功能需求介绍

libvlc支持两种方式开发,第一种是回调方式开发,第二种是传入窗口ID直接渲染。

回调方式开发可以拿到每一帧图像自己渲染,传入窗口ID的方式是libvlc内部直接控制窗体渲染。 如果采用传入窗口ID方式开发,想要使用常规的方式在播放器的窗口上直接加控件或者覆盖新窗口都行不通(继承关系都不行),因为将窗口ID传入进去之后,窗口的控制权就交给libvlc了。

在播放器窗口上叠加窗口可以显示很多自定义的一些提示内容,或者将播放器的控制按钮放在上面等等效果。

就像下面一样:

将播放器的控制菜单浮动在播放窗口上,全屏播放时操作比较方便,不影响看视频。
image.png

在调整音量、播放状态改变时,可以在窗口上弹出提示。
image.png

要达到这种效果,覆盖新窗口上去,只能使用子窗口形式,设置新窗口为透明属性,在主窗口的状态事件(移动、大小改变、重绘)里,设置覆盖窗口的大小,位置,让覆盖的窗口始终跟随在播放窗口上。

二、实现方式: 完整代码

最终的运行效果

(1). 未播放视频之前的效果
image.png

(2). 播放视频中的效果

image.png

image.png

image.png

2.1 form.cpp :附加上去的窗口

#include "form.h"
#include "ui_form.h"

Form::Form(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);

   //窗口无边框
   setWindowFlags(Qt::FramelessWindowHint|Qt::Window);
   //setAutoFillBackground(true);

   // 窗口透明
   this->setAttribute(Qt::WA_TranslucentBackground);
}

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

void Form::paintEvent(QPaintEvent *pEvent)
{

    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);//绘制样式
}


2.2 form.h :附加上去的窗口

#ifndef FORM_H
#define FORM_H

#include <QWidget>
#include <QStyleOption>
#include <QPainter>
namespace Ui {
class Form;
}

class Form : public QWidget
{
    Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr);
    ~Form();
private:
    void paintEvent(QPaintEvent *pEvent);
private:
    Ui::Form *ui;
};

#endif // FORM_H

2.3 form.ui

附加的窗口上,设计了3个按钮和一个标签–显示一些提示文字。
image.png

image.png

2.4 widget.cpp 主窗口

主窗口代码里只贴出和本文问题相关的代码。

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

Widget* Widget::pThis = nullptr;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    pThis=this;

    ui->setupUi(this);

    //叠加的窗口
    form=new Form(this);
    form->setStyleSheet(QString("background-color: rgba(255, 0, 0, 0%);"));
    form->show();
	
	.....................
}


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


//重载窗口移动事件
void Widget::moveEvent(QMoveEvent *event)
{
    QPoint pos_form=ui->widget->mapToGlobal(ui->widget->pos());
    form->move(pos_form);
    form->setGeometry(pos_form.x(),pos_form.y(),ui->widget->width(),ui->widget->height());
}


void Widget::paintEvent(QPaintEvent *pEvent)
{
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);//绘制样式

    QPoint pos_form=ui->widget->mapToGlobal(ui->widget->pos());
    form->move(pos_form);
    form->setGeometry(pos_form.x(),pos_form.y(),ui->widget->width(),ui->widget->height());
}

2.5 widget.h 主窗口

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <vlc/vlc.h>
#include <QDebug>
#include <QFileDialog>
#include <QMoveEvent>
#include "form.h"
#include <QTime>
#include <QThread>
#include <QTimer>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
     ...................
private slots:
     ...................
protected:
    ...................
    void moveEvent(QMoveEvent *event);
    void paintEvent(QPaintEvent *pEvent);
private:
    ...................

};
#endif // WIDGET_H

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。