Qt QWidget视频上叠加文字

需求:在调用其它音视频SDK的时候,在windows上一般会传入一个 winId 控件来显示视频,这个winID在Qt中一般是QWidget。目前想在这个视频上 显示一些提示信息,比如视频源的名字。 

一,曾尝试过的几种方案

在视频源上写入:

(1),利用opencv ,将原始yuv数据 转成mat,然后利用opencv的内置函数,绘制文字。不过这样的缺点是,引入了第三方库并且耗费大量cpu资源。

(2),利用opengl 在渲染yuv数据时,绘制文字。经测试,利用openg进行渲染,可直接利用QWidget cpu利用率一样,可能是自己写错了,所以此方案也放弃。

在显示端写入:

(1),利用qml控件,叠加item窗体。qml本身也用了opengl渲染,效果和上述方案2一样,opengl 玩不明白。

(2),利用QWidget 控件叠加,至于上层,背景透明。简单方便 缺点是如果利用采集卡复制视频流,然后利用第三方软件播放,则名字就看不见了,因为数据源本身不含有名字信息。

 

二,代码

#ifndef VWIDGET_H
#define VWIDGET_H
#include 
#include 
class QLabel;

class NameWidget:public QWidget{
     Q_OBJECT
public:
    NameWidget(QWidget*parent =nullptr);

    void setName(const QString &name);

protected:
    void paintEvent(QPaintEvent *);

private:
    QColor m_color;
    QLabel *m_label;

};

class VideoWidget : public QWidget
{
    Q_OBJECT
public:
    VideoWidget(QWidget*paren=nullptr);
    virtual ~VideoWidget() {}

    QWidget* video(){return m_videoWidget;}
    void setMicCameraStatus(bool _mic,bool _cam);
    void setName(const QString &name);

    void setIsMaster(bool isMaster);
    void setShowNameLabel(bool show);


private:
    QLabel* m_mediaStatsLabel;//麦克风和 摄像机状态
    QWidget* m_videoWidget;
    NameWidget *m_nameWidget;
    bool m_isMaster;
    bool m_isShowName;
protected:
    void resizeEvent(QResizeEvent *);

};

#endif // VWIDGET_H

 

#include "videowidget.h"
#include 
#include 
#include 
NameWidget::NameWidget(QWidget *parent):QWidget (parent)
{
    m_color = QColor(100,100,100,100);
    m_label = new QLabel(this);
    QFont ft;
    ft.setPointSize(35);
    m_label->setFont(ft);
    QString styleSheet = QString::fromUtf8("color: rgb(255, 255, 255);");
    m_label->setStyleSheet(styleSheet);

    m_label->setText(QString::fromUtf8("显示自己"));
    QGridLayout *layout = new QGridLayout(this);
    layout->setContentsMargins(9,0,0,0);
    layout->addWidget(m_label);
    this->setLayout(layout);
}

void NameWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.fillRect(this->rect(),m_color);
}

void NameWidget::setName(const QString &name)
{
    m_label->setText(name);
}


VideoWidget::VideoWidget(QWidget*paren):QWidget (paren),
    m_isMaster(false),m_isShowName(false){

    m_mediaStatsLabel = new QLabel(this);
    this->setAttribute(Qt::WA_TranslucentBackground);
    QString styleSheet = QString::fromUtf8("color: rgb(255, 255, 255);\n"
                                           "background-color: rgb(0, 0, 0,100);");
    m_mediaStatsLabel->setStyleSheet(styleSheet);
    QFont ft;
    ft.setPointSize(10);
    m_mediaStatsLabel->setFont(ft);
    m_mediaStatsLabel->raise();
    setMicCameraStatus(true,true);
    m_mediaStatsLabel->hide();

    m_videoWidget = new QWidget(this);
    QGridLayout* layout = new QGridLayout(this);
    layout->setContentsMargins(0,0,0,0);
    layout->addWidget(m_videoWidget);
    this->setLayout(layout);
    m_videoWidget->lower();

    //
    m_nameWidget = new NameWidget(this);
    m_nameWidget->setWindowFlags(Qt::FramelessWindowHint|Qt::Dialog|Qt::WindowStaysOnTopHint|Qt::SubWindow);
    m_nameWidget->setAttribute(Qt::WA_TranslucentBackground, true);
    QPalette pal;
    pal.setColor(QPalette::Background,QColor(90,90,90,90));
    m_nameWidget->setAutoFillBackground(true);
    m_nameWidget->setPalette(pal);
    m_nameWidget->hide();

    setAttribute(Qt::WA_TransparentForMouseEvents, true);
}

void VideoWidget::setMicCameraStatus(bool _mic, bool _cam)
{
    QString mic;
    QString cam;
    if(_mic)
        mic="  Mic:ON";
    else {
        mic="  Mic:OFF";
    }

    if(_cam)
        cam=" Cam:ON";
    else {
        cam=" Cam:OFF";
    }
    m_mediaStatsLabel->setText(cam+mic);
}

void VideoWidget::setName(const QString &name)
{
    m_nameWidget->setName(name);
}

void VideoWidget::setIsMaster(bool isMaster)
{
    m_isMaster = isMaster;
}

void VideoWidget::setShowNameLabel(bool show)
{
    m_isShowName=show;
}

void VideoWidget::resizeEvent(QResizeEvent *e)
{
    if(!m_isMaster)
        m_mediaStatsLabel->show();

    if(m_isShowName)
        m_nameWidget->show();
    else {
        m_nameWidget->hide();
    }

    m_mediaStatsLabel->setGeometry(this->width()-120,0,120,15);//状态信息
    m_nameWidget->setGeometry(this->x(),this->y()+this->height()-53,this->width()/3,50);
    return QWidget::resizeEvent(e);
}

关键代码:

setWindowFlags(Qt::FramelessWindowHint|Qt::Dialog|Qt::WindowStaysOnTopHint|Qt::SubWindow);
    m_nameWidget->setAttribute(Qt::WA_TranslucentBackground, true);
    QPalette pal;
    pal.setColor(QPalette::Background,QColor(90,90,90,90));
    m_nameWidget->setAutoFillBackground(true);
    m_nameWidget->setPalette(pal);
    m_nameWidget->hide();

    setAttribute(Qt::WA_TransparentForMouseEvents, true);

三,效果

Qt QWidget视频上叠加文字_第1张图片

你可能感兴趣的:(音视频)