MQTT(Message Queuing Telemetry Transport)是一种基于发布/订阅模式的轻量级通信协议,广泛应用于物联网领域。它允许设备通过极少的代码和有限的带宽实现实时可靠的消息服务。MQTT协议的核心在于其三部分组成的控制报文:固定报头、可变报头和有效载荷。
mqtt中的一些名词解释:https://www.cnblogs.com/bliss-/p/12508774.html
更多mqtt中文规范:https://www.mqtt.cn/mqtt-specification
一、说明
1.1
MQTT协议主要应用物联网设备的数据交互场景,专业的视频传输协议有RTMP、RTSP等。使用MQTT传视频主要是...玩
效果:
1.2 准备工作
- mqttdocker:可以自己在本地搭建,也可以临时使用公共docker,自己搭建可选mosquitto:https://mosquitto.org/或者EMQX:https://www.emqx.cn/
- UI图形库:C++QT
- 视频来源:笔记本摄像头
- qt的mqtt库需要自己编译完之后添加:https://www.cnblogs.com/bliss-/p/12378226.html
二、设计思路
2.1 采集端
- 连接mqtt服务器
- 打开摄像头
- 每隔50ms使用摄像头拍照
- 将拍到的照片转成二进制发送到指定的topic
2.2 接收端
- 连接服务器
- 订阅指定的topic,绑定消息接收的信号与槽
- 接收到topic数据后将二进制数据转成JPG,显示在界面Label控件中
2.3 注意
- 数据发送时考虑到带宽与延时需要将拍照得到的照片等比例缩小
- 消息的服务等级设置为qos0,避免数据传输失败后重传
三、关键代码
- 摄像头打开、显示、拍照、截图、发送
//打开摄像头并显示
camera = new QCamera(this);
cameraViewFinder = new QCameraViewfinder(this);
ui->verticalLayout_2->addWidget(cameraViewFinder);
camera->setViewfinder(cameraViewFinder);
camera->start();
// 摄像头拍照并发送
cameraImageCapture = new QCameraImageCapture(camera);
cameraImageCapture->capture();
connect(cameraImageCapture,SIGNAL(imageCaptured(int,QImage)),this,SLOT(onImageCaptured(int,QImage)));
void MainWindow::onImageCaptured(int idx,QImage img)
{QPixmap pixMap = QPixmap::fromImage(img);pixMap = pixMap.scaled(600, 600, Qt::KeepAspectRatio);QBuffer buffer;buffer.open(QIODevice::ReadWrite);pixMap.save(&buffer,"jpg");m_client->publish(ui->lineEditTopic->text(), buffer.data(),0,0);
}
- mqtt建立连接、订阅主题、消息接收、解码JPG并显示
// mqtt配置
m_client = new QMqttClient(this);
m_client->setHostname(ui->lineEditHost->text());
m_client->setPort(ui->spinBoxPort->value());
m_client->setCleanSession(true);
// mqtt连接
m_client->connectToHost();
// 发布消息
m_client->publish(ui->lineEditTopic->text(), ui->lineEditMessage->text().toUtf8(),0,false);
// 订阅主题
connect(m_client, &QMqttClient::messageReceived, this, &MainWindow::on_msgRecv);
void MainWindow::on_msgRecv(const QByteArray &message, const QMqttTopicName &topic)
{QBuffer buffer((QByteArray *)&message);buffer.open(QIODevice::ReadOnly);QImageReader reader(&buffer,"JPG");QImage img = reader.read();if(!img.isNull()){QPixmap pix = QPixmap::fromImage(img);ui->label->setPixmap(pix.scaled(ui->label->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));}
}
四、后续建议
- mqtt不适合传输视频,不建议使用
- 当前只传输画面,没有音频
- 数据的传输考虑加密、压缩
- mqtt不适合传输视频,不建议使用
- 可以使用UDP作为传输层协议的视频传输应用,tcp太消耗资源