需求:在调用其它音视频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);
三,效果