**

1 QT下视频通话的实现

**
本文使用QT完成了两个不同终端的视频通话,笔记本电脑+Linux开发板。
1.1 硬件资源介绍
带摄像头的电脑 + 正点原子Alpha Linux开发板(由于Linux开发板上没有购买摄像头,所以本次实现仅仅单向的视频通话)
1.2 软件编程实现
1.2.1 电脑端QT编程
电脑端搭建一个TCP服务器,开启一个视频捕获线程,使用QCamera、QCameraViewfinder、QCameraImageCapture、QTimer,定时捕获视频中的图片,并传送给主线程使用TCP发给客户端。下面是核心的代码实现
(1)捕获电脑的视频,这里是捕获视频的核心代码,实现的大致思路是,开启一个QCaerma,通过主线程的信号槽开启,定时VIDEO_SAMPLE_INTERVAL时间截取一张图片,此时会自动触发SIGNAL(imageCaptured(int,QImage))这样一个信号,在主线程中编写槽函数接收捕获到的QImage。这个cpp参考网上一位老哥的编写,将QVideoProbe换成了QCameraImageCapture来实现。https://blog.csdn.net/xiaolong1126626497/article/details/105122636

void VideoReadThread::Camear_Init(void){qDebug() << "Camear_Init";// 初始化定时器ImageCaptureTimer = new QTimer(this);connect(ImageCaptureTimer,SIGNAL(timeout()),this,SLOT(captureImage()));// currentCaerma 为当前选择的摄像头camera = new QCamera(qtUtil.camera);//设置取景器viewfinder = qtUtil.viewfinder;imageCapture = new QCameraImageCapture(camera);camera->setViewfinder(viewfinder);//配置 Camera 为静止帧捕获camera->setCaptureMode(QCamera::CaptureStillImage);//启动摄像头camera->start();//配置摄像头参数QList<QCameraViewfinderSettings > ViewSets = camera->supportedViewfinderSettings();int i = 0;qDebug() << "viewfinderResolutions sizes.len = " << ViewSets.length();foreach (QCameraViewfinderSettings ViewSet, ViewSets) {qDebug() << i++ <<" max rate = " << ViewSet.maximumFrameRate() << "min rate = "<< ViewSet.minimumFrameRate() << "resolution "<<ViewSet.resolution()<<\"Format="<<ViewSet.pixelFormat()<<""<<ViewSet.pixelAspectRatio();}//可以打印出来自己电脑端的settings,进行选择    camera->setViewfinderSettings(ViewSets[9]);//开启定时器ImageCaptureTimer->start(VIDEO_SAMPLE_INTERVAL);connect(imageCapture, SIGNAL(imageCaptured(int,QImage)), this, SLOT(displayImage(int,QImage)));
}
void VideoReadThread::captureImage()
{imageCapture->capture();
}

(2)使用TCP传输图片,参考飞扬青云的帖子https://www.cnblogs.com/feiyangqingyun/p/12041561.html 使用base64编码传输,接收到以后将base64字符串解码出来生成图片。

// 获取图片并转为base64字符串
QByteArray Widget::getImageData2(const QImage &image)
{QByteArray imageData;QBuffer buffer(&imageData);image.save(&buffer, "jpg");imageData = imageData.toBase64();return imageData;
}//base64字符串转图片
QImage Widget::getImage(const QString &data)
{QByteArray imageData = QByteArray::fromBase64(data.toLatin1());QImage image;image.loadFromData(imageData);return image;
}

(3)TCP传输过程中粘包,拆包处理,服务器端规定协议,增加数据包的开头和结尾,观察图片转换正的Base64码中发现没有@ 和 # ,因此使用这两个当做一包数据的头和尾。栽面是服务器端封包的代码。
//封装发送图片的数据包

// startFlag: @  endFlag:#
QByteArray Widget::packageImageData(QImage image)
{QByteArray resultData;imageData = getImageData2(image);resultData.append(startFlag).append(imageData).append(endFlag);qDebug()<<resultData.size();
//    qDebug()<<resultData;return resultData;
}

1.2.2 Linux开发板QT编程
使用正电原子的Linux开发板,使用之前先配置好开发板上QT的运行环境,参考正点原子文档。开发板中主要是实现了数据包的解析,代码如下:


```css
/*解析数据*/
void Widget::parseImageData(QByteArray receiveData)
{QByteArray bufData = receiveData;static QByteArray pastData;static QString resultStr;if(bufData.contains("@")&(!bufData.contains("#"))){pastData.clear();pastData.append(bufData);}//无头无尾中部数据 直接追加if((!bufData.contains("@"))&(!bufData.contains("#"))&(!pastData.isEmpty())){pastData.append(bufData);}//无头有尾 如果数据之前不为空则继续追加 已经读取完成 清空变量if((!bufData.contains("@"))&bufData.contains("#")&(!pastData.isEmpty())){pastData.append(bufData);resultStr = tr(pastData);pastData.clear();}//有头有尾 清空之前数据直接追加if(bufData.contains("@")&bufData.contains("#")){pastData.clear();pastData.append(bufData);resultStr = tr(pastData);pastData.clear();}if(!resultStr.isEmpty()){resultStr.remove("@");resultStr.remove("#");emit sendImageDataBase64(resultStr.toUtf8());//        qDebug()<<resultStr.toUtf8();resultStr.clear();}
}

解析后的数据,通过一个信号传递给处理图片的槽函数,将编码转换为Qimage,显示在Qlabel上。
1.3 实验效果
我设置的定时器间隔为100ms,视频传输感觉较为流畅。电脑端,布局比较乱

Linux 开发板

QT下视频通话的实现相关推荐

  1. Qt下的视频实时传输

    此文用于记录Qt远程采集摄像头画面的办法,以备忘记,Qt远程采集画面可以实现远程监控,视频通话和一些远程识别功能:本次以TCP作为通信手段,实现传输功能,Qt版本使用15.5.2.,实现原理为照片不间 ...

  2. linux+Qt 下利用D-Bus进行进程间高效通信的三种方式

    linux+Qt 下利用D-Bus进行进程间高效通信的三种方式 原文链接: https://www.cnblogs.com/wwang/archive/2010/10/27/1862552.html ...

  3. Qt下一行代码就可以使用的稳定易用的日志log类

    Qt下一行代码就可以使用的稳定易用的日志类 此日志类是基于Qt 自带的 扩展的一个易用的日志类, 使用的是Qt自带的日志输出形式, 已长期运行在许多实际项目中,稳定可靠,而且跨平台, 在windows ...

  4. Qt下使用Shader绘制三角形

    在Qt下使用可编程管线编写OpenGL的流程是怎样的呢? 下面演示了Qt下使用可编程管线的基本代码:(绘制三个不同的三角形,并做些旋转变换) 在Qt中,我们从QGLWidget继承,来实现OpenGL ...

  5. Qt下的OpenGL 编程(3)绘制平面几何体

    一. 提要 之前的一篇教程已经搭建好了Qt下的OpenGL的编程环境,几天要来学习的就是OpenGL的2D绘图. 2D作为绘图的基础,还是很值得去好好学习,比如迪卡尔坐标,透视设置等等,而所谓的3D, ...

  6. Qt下使用OpenCV3打开摄像头并把图像显示到QLabel上

    前言 1.Qt5有自己摄像头的类QCamera,但是图像处理相关还是要使用OpenCV来做,这里我演示在Qt下使用OpenCV打开摄像头. 2.Qt的版本是5.9,Qt Creator 4.4.1,O ...

  7. Qt下Tcp传输文件

    Qt下Tcp传输文件 文章目录 Qt下Tcp传输文件 1.服务端 2.客户端 1.服务端 //ServerWidgets.h #ifndef SERVERWIDGET_H #define SERVER ...

  8. Qt下Undefined reference to 'vtable for xxx'

    QT下遇到这种错误提示时候需要注意以下情况: 一.cpp文件里使用了Q_OBJECT 分析:qmake不会处理.cpp文件里的Q_OBJECT,所以如果在.cpp文件中有它的话将会产生undefine ...

  9. Qt下继承于QObject创建的线程

    Qt线程 线程创建方法 示例 线程创建方法 Qt下创建线程的方法有两种: 一种是通过继承QThread,并重写run()函数,在run()函数中,编写线程所做的事情,在需要线程的文件中,创建线程对象, ...

最新文章

  1. 机器学习系列19:将核函数应用于支持向量机
  2. OpenGL-渲染管线的流程(有图有真相)
  3. 连不上机器判断机器状态_KUKA机器人为什么KPP故障联不上,断电重启hou报RDC连接连接不上...
  4. android sqlite 备份数据库文件,android – 将SQLite数据库备份和还原到sdcard
  5. 用c语言绘制自定义图形,Android使用自定义View绘图
  6. Spark 学习(六) Spark 的线程安全和序列化问题
  7. XML解析技术简介——(一)
  8. java B2B2C 仿淘宝电子商城系统-eureka 基础
  9. 《天天数学》连载25:一月二十五日
  10. Java 算法 学做菜
  11. RabbitMQ-1 Helloword
  12. php 多层 对象,php多层数组和对象的转换
  13. 实验4-1-10 兔子繁衍问题 (15 分)
  14. ElasticSearch学习(四):可视化管理之Kibana
  15. 2021-08-15 Servlet Properties 读取资源
  16. 儿童智能手表方案/案列/APP/小程序/网站
  17. 第五人格显示服务器连接失败,第五人格网络连接失败怎么回事
  18. 异常捕获与自定义迭代器
  19. PS四种扁平化设计风格
  20. HTML5网页设计图片如何,网页设计中优化图片的6个技巧

热门文章

  1. fastjson复杂json转换为java对象
  2. 你想用计算机做什么工作,用四宫格管理你的电脑桌面,工作效率蹭蹭蹭的提高...
  3. 电动汽车感应电动机优化控制与仿真分析
  4. 老伏膏消肚子真的有效吗
  5. WMI Win32_OperatingSystem类
  6. 国内电商物流机器人行业亟待解决问题汇总
  7. python中英文翻译translate模块使用
  8. 红芯官网删除国产、自主创新字样;谷歌面临欧盟又双叒一笔天价罚单
  9. 中软国际实训全记录——第三天
  10. 吉林大学计算机a类学科,吉林大学a类学科有什么?附吉大a类学科名单