QT获取ESP32-CAM视频流分析
1、前言
使用QT获取ESP32-CAM视频流的原理是在QT模拟浏览器发送http请求,然后ESP32-CAM返回视频流,当QT界面接收到数据后,对数据进行解析,然后合成图片进行显示。
在QT中发送http请求的方法很多,这里使用Qt网络模块中的类QNetworkReply发送http请求。
2、核心代码以及数据分析
①下面是QT的一个构造函数,当程序跑起来后,首先跑这部分代码,在这里模拟发送hhtp请求。其中ESP32-CAM分配到的IP地址是192.168.1.8.
#include <QHostAddress>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QQueue>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request(QUrl("http://192.168.1.8"));
QNetworkReply *reply= manager->get(request);
connect(reply, &QNetworkReply::finished, [reply]() {
if (reply->error())
{
qDebug() << "Error:" << reply->errorString();
}
else
{
qDebug() << "Success:" << reply->readAll();
}
reply->deleteLater();
});
}
这部分代码运行成功后,应该有如下打印:
上面就是返回一个网页,当你把http://192.168.1.8复制到网页去搜索,会返回下面的页面:
②下面是进行视频流http请求代码,调用它,运行后可以打印接收到的原始数据。注意视频流使用的是81端口。
void MainWindow::start()
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request;
request.setUrl(QUrl("http://192.168.1.8:81/stream"));
request.setRawHeader("Connection", "Keep-Alive");
request.setRawHeader("User-Agent", "1601");
Client = manager->get(request); //Client为QNetworkReply类型,在MainWindow类里面定义
connect(Client, &QNetworkReply::readyRead, this, &MainWindow::dataReceived);
}
void MainWindow::dataReceived()
{
// 打印接收内容
QByteArray buffer = Client->readAll();
qDebug() << buffer;
qDebug() << "----------------------";
}
接收到的原始数据如下:
上面接收到的原始数据是不能直接用的。就是每次一次接收到的数据并不是一帧完整的数据。因此需要把每次接收到的数据存储起来,然后进行切割。切割的思路是:先这样这样,然后再这样这样。
在完成数据的存储和切割后,得到如下一帧一帧完整的数据。(在下面的数据中,每一帧数据只打印了前100个字节和后100个字节)。每一帧数据以“Content-Type: image/jpeg\r\nContent-Length: 28912\r\n\r\n\”开头,以“\r\n–123456789000000000000987654321\r\n”结束,中间部分的数据就是图片数据,图片数据的长度是Content-Length后面的数字(28912)。把中间部分数据提取出来即可合成图片。
切割数据的思路是:每次接收到原始数据,都要判断一下是否包含字符串“Content-Type”,如不包含,则当前接收的数据归为上一帧数据,若包含,则在当前接收到的数据里面,将Content-Type前面部分的数据归为上一帧数据,而以Content-Type开始的后半部分数据归为下一帧数据。(其实就是将两帧黏起来的数据进行切割)。
③合成图片的关键代码
void MainWindow::dataProcess( )
{
QString data = QString::fromUtf8(frameBuffer.data(), 50); //截取前面50个字符
// qDebug() <<frameBuffer.left(100)<<"......";
// qDebug() <<frameBuffer.right(100);
// qDebug() <<"------------------------";
const QString lengthKeyword = "Content-Length: ";
int lengthIndex = data.indexOf(lengthKeyword);
if (lengthIndex >= 0) {
int endIndex = data.indexOf("\r\n", lengthIndex);
int length = data.midRef(lengthIndex + 16, endIndex - (lengthIndex + 16 - 1)).toInt(); //取出Content-Length后的数字
QPixmap pixmap;
auto loadStatus = pixmap.loadFromData(frameBuffer.mid(endIndex + 4, length)); //取出图片数据,并合成图片
if (!loadStatus) {
qDebug() << "Video load failed";
frameBuffer.clear();
return;
}
frameBuffer.clear();
QPixmap pps = pixmap.scaled(ui->label_display->width(), ui->label_display->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
ui->label_display->setPixmap(pps);
}
}
3、图片合成效果
跟网页效果差不多,很流畅。
4、源码
ESP32CAM.exe
https://www.aliyundrive.com/s/CwhgTsmggwG
提取码: 9ek4
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。文章来源:https://www.toymoban.com/news/detail-419262.html
5、结束
加油,打工人。文章来源地址https://www.toymoban.com/news/detail-419262.html
到了这里,关于QT获取ESP32-CAM视频流分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!