Qt下的视频实时传输

此文用于记录Qt远程采集摄像头画面的办法,以备忘记,Qt远程采集画面可以实现远程监控,视频通话和一些远程识别功能;本次以TCP作为通信手段,实现传输功能,Qt版本使用15.5.2。,实现原理为照片不间断地传输和显示,让人眼分辨不出来,即可实现在线视频监控。

一,视频发送端的实现

1.1实现通信界面,界面由如下几部分组成

Qt下的视频实时传输_第1张图片

 最终的界面如下:

 Qt下的视频实时传输_第2张图片

1.2TCP服务器的实现,Qt下TCP服务器的实现很简单,直接调用QTcpServer的方法,进行监听

关联信号的和槽函数,实现监听处理

 槽函数的实现,槽函数中使用一个定时器,定时50ms,每50ms出发一次cap_pic和transfer_pic函数,实现拍照和传输照片

Qt下的视频实时传输_第3张图片

 transfer_pic槽函数的实现,此处使用img.save实现照相机拍照到的图片的压缩,方便TCP一次性的传输,当图片大于70KB左右时,一次传输不过去,所以这里实现和图片的压缩再传输。

Qt下的视频实时传输_第4张图片

 1.3摄像头及拍照的实现,摄像机相关的类及操作和拍照的槽函数如下,正常操作,无注意点,直接实现即可。

Qt下的视频实时传输_第5张图片

 Qt下的视频实时传输_第6张图片

 cap_pic槽函数

Qt下的视频实时传输_第7张图片

 还有一点注意的是开关摄像头的槽函数,关闭摄像头是需要关闭定时器,让TCP不再发送图片过去。

Qt下的视频实时传输_第8张图片

 二,视频接受端的实现

2.1界面的实现,界面无需设计太多,满足功能要求即可,做一个Qlabel即可。

Qt下的视频实时传输_第9张图片

 

Qt下的视频实时传输_第10张图片

2.2TCP客户端的搭建,直接调用Qt相关的类和函数即可

 此处由一个槽函数,当客户端收到消息的时候,执行play_movie函数

play_movie函数如下,每次接受到图片,就覆盖掉上一次接受到的图片,然后重新显示到QLabel上,实现快速更新,使人肉眼分辨不出来是图片,即可实现诗篇的显示。

Qt下的视频实时传输_第11张图片

 三,此上为摄像头在线显示的全过程,最终界面成果如下:

Qt下的视频实时传输_第12张图片

最后,贴出源码,方便以后复制粘贴

//***************************************视频发送端头文件
#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void init_ui();
public:
    QCamera *cam;
    QCameraViewfinder *vf;
    QCameraImageCapture *imc;
    QTextEdit *te;
    QPushButton *but_open_cam;
    QPushButton *but_close_cam;
    QHBoxLayout *hb1;
    QVBoxLayout *vb1;
    QTcpServer *ser;
    QTcpSocket *mycli;
    QTimer *tim;
    QCameraImageCapture *imgcap;
public slots:
    void open_cam();
    void close_cam();
    void cap_pic();
    void connect_success();
    void transfer_pic();
};
#endif // WIDGET_H
//********************************************视频发送端.cpp文件
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->tim=new QTimer();
    this->cam=new QCamera(QCameraInfo::defaultCamera());
    //this->cam->setCaptureMode(QCamera::CaptureStillImage);
    this->imgcap=new QCameraImageCapture(this->cam);
    this->init_ui();
    this->ser=new QTcpServer();
    this->ser->listen(QHostAddress::AnyIPv4,8888);
    connect(this->but_open_cam,&QPushButton::clicked,this,&Widget::open_cam);
    connect(this->but_close_cam,&QPushButton::clicked,this,&Widget::close_cam);
    connect(this->ser,&QTcpServer::newConnection,this,&Widget::connect_success);
}

Widget::~Widget()
{
}

void Widget::init_ui()
{
    this->vf=new QCameraViewfinder();
    this->vf->setFixedSize(400,250);
    this->cam->setViewfinder(this->vf);
    this->vf->show();

    this->te=new QTextEdit();
    this->but_open_cam=new QPushButton(tr("打开摄像头"));
    this->but_close_cam=new QPushButton(tr("关闭摄像头"));
    this->hb1=new QHBoxLayout();
    this->vb1=new QVBoxLayout();
    this->hb1->addWidget(this->but_open_cam);
    this->hb1->addWidget(this->but_close_cam);
    this->vb1->addWidget(this->vf);
    this->vb1->addWidget(this->te);
    this->vb1->addLayout(this->hb1);
    this->setLayout(this->vb1);
}


void Widget::open_cam()
{
    this->cam->start();
}

void Widget::close_cam()
{
    this->tim->stop();
    this->cam->stop();
}

void Widget::connect_success()
{
    this->mycli=this->ser->nextPendingConnection();
    this->te->setText(tr("连接成功"));
    connect(this->tim,&QTimer::timeout,this,&Widget::cap_pic);
    connect(this->tim,&QTimer::timeout,this,&Widget::transfer_pic);
    this->tim->start(50);
}

void Widget::cap_pic()
{
    this->imgcap->capture("D:/QTfile/pic_tranfer/pic/1");
}

void Widget::transfer_pic()
{
    qDebug()<<"--------------";
    QImage img("D:/QTfile/pic_tranfer/pic/1.jpg");
    img.save("D:/QTfile/pic_tranfer/pic/1.jpg","jpg",20);
    QFile file("D:/QTfile/pic_tranfer/pic/1.jpg");
    file.open(QIODevice::ReadOnly);
    QByteArray tem=file.readAll();
    file.close();
    this->mycli->write(tem);
}
//******************************************视频接收端头文件
#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
public:
    QHBoxLayout *hb;
    QLabel *lb;
    QTcpSocket *mysocket;
public slots:
    void play_movie();
};
#endif // WIDGET_H
//*******************************************视频接收端.cpp文件
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->lb=new QLabel();
    this->lb->setFixedSize(400,250);
    this->hb=new QHBoxLayout();
    this->hb->addWidget(this->lb);
    this->setLayout(this->hb);
    this->mysocket=new QTcpSocket();
    this->mysocket->connectToHost("192.168.17.1",8888);
    connect(this->mysocket,&QTcpSocket::readyRead,this,&Widget::play_movie);
}

Widget::~Widget()
{
}

void Widget::play_movie()
{
    QByteArray data=this->mysocket->readAll();
    QFile file("D:/QTfile/pic_tranfer/pic_recv/1.jpg");
    file.open(QIODevice::WriteOnly | QIODevice::Truncate);
    file.write(data);
    file.close();
    QImage image("D:/QTfile/pic_tranfer/pic_recv/1.jpg");
    QPixmap pic=QPixmap::fromImage(image);
    this->lb->setPixmap(pic.scaled(this->lb->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
}



 

 

 

你可能感兴趣的:(qt,音视频,开发语言,视频)