当前位置: 首页 > news >正文

基于Qt和FFmpeg的安卓监控模拟器/手机摄像头模拟成onvif和28181设备

一、前言说明

这个功能是之前写的监控设备模拟器的衍生,同时集成在该项目中,就是单独写个竖版的app样式的界面,然后编译成安卓版本即可,默认就模拟一路设备,从设备地址下拉框中选择安卓摄像头即可,所有的底层功能使用的就是设备模拟器的,为何会有这个需求?之前的模拟器已经可以将任意的视频文件视频流,以及本地USB摄像头或者桌面采集,转成监控设备,通过onvif协议或者28181协议,和服务端平台端进行交互,当时设计的时候就已经考虑到了跨平台的场景,所以其实这些底层组件代码是完全支持安卓的,为了使得ffmpeg能够正常采集到安卓摄像头,当时还特意搞了很久,编译带avdevice的ffmpeg安卓库,网上几乎都是不带avdevice的,搞得之前还以为代码有问题,原来是对应的库没有带。

目前在手机上只是采集了摄像头的实时视频画面,音频这块还没有实现,在win上使用dshow采集麦克风,在linux上使用alsa采集麦克风,到安卓上目前没有发现有对应的实现,所以也挺鸡肋的,后期估计先采用Qt的麦克风采集,相当于单独音频交互,如果是ffmpeg推流rtsp的话,还要涉及到混流,也就是之前的视频流需要加上采集的音频流,混合后再一起推流。

二、效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、相关地址

  1. 国内站点:https://gitee.com/feiyangqingyun
  2. 国际站点:https://github.com/feiyangqingyun
  3. 个人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652
  4. 文件地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取码:01jf 文件名:bin_video_simulate。

四、功能特点

  1. 标准onvif协议,支持设备搜索、获取参数、快照抓图等。
  2. 支持264/265/aac等标准视音频协议传输。
  3. 支持多路批量onvif设备模拟,每一路都独立的端口。
  4. 支持本地摄像头采集转成onvif,可选择不同的设备、分辨率、帧率等参数。
  5. 支持本地桌面采集转成onvif,可选择不同的屏幕、分辨率、帧率等参数。
  6. 支持各种视频文件和视频流转成onvif,可重新设置编码转换以及分辨率转换。
  7. 支持4K、8K等高清分辨率,不限制分辨率,非264/265会自动转码推流。
  8. 每一路都可以设置统一或者独立的用户验证信息,为空则表示不验证。
  9. 可以把任意内容接入到NVR以及视频监控系统,方便保存录像文件,以便回放可查。
  10. 也可作为压力测试工具,比如模拟几千路onvif设备,让集成平台软件做接入压力测试。
  11. 推出去的流不仅有rtsp格式,还支持rtmp、http、flv、ws-flv、webrtc等方式访问,可以直接网页查看。
  12. 在管理工具上可以看到每一路的推流状况以及分辨率信息,非常直观。
  13. 支持自动重连拉流,重连推流,保证7乘以24小时稳定运行。
  14. 可设置开机自启动运行和后台运行,不显示在任务栏,作为后台服务运行。
  15. 可批量添加文件、添加目录,自动将目录下的所有文件添加到模拟器。
  16. 多功能添加地址面板,可以选择本地设备和监控设备,本地设备会自动识别摄像头设备和桌面设备,监控设备可以选择不同厂家,自动填充对应rtsp格式,填入用户信息即可,可以批量递增添加监控设备。
  17. 可无缝上传到市面上所有的onvif协议设备,包括海康、大华、宇视、华为、天地伟业等,也支持ONVIF Device Manager国际onvif工具。
  18. 支持gb28181设备模拟,具备设备注册、设备注销、设备心跳、设备信息、设备配置、设备状态应答等。
  19. 支持模拟报警和位置上报等,方便平台侧显示对应设备的实时位置。
  20. 支持一键添加批量模拟28181设备,实时显示已注册和已注销状态。
  21. 支持将本地桌面、本地摄像头、任意视频文件、视频流文件、手机摄像头等转换成28181设备,添加到NVR或者国标软件平台。
  22. sip协议同时支持udp和tcp两种通信方式,视频点播同时支持udp/tcp主动/tcp被动三种方式,涵盖所有可能的场景需求。
  23. 无论是onvif设备模拟组件还是28181设备模拟组件,全部原创底层协议解析,纯Qt实现,跨任意平台。
  24. 代码结构框架非常清晰,注释详细,代码精简不繁琐,非常易于学习和移植,可以很容易拓展其他接口需求。
  25. 支持Qt4/Qt5/Qt6以及后续所有版本、所有编译器、所有开发环境。
  26. 支持windows、linux、mac、国产OS、嵌入式linux、RK3588、树莓派、香橙派等系统。

五、相关代码

#include "frmonvifapp.h"
#include "ui_frmonvifapp.h"
#include "qthelper.h"
#include "videoutil.h"
#include "urlutil.h"
#include "onvifdevicepush.h"
#include "onvifdeviceserver.h"frmOnvifApp::frmOnvifApp(QWidget *parent) : QWidget(parent), ui(new Ui::frmOnvifApp)
{ui->setupUi(this);this->initForm();this->initConfig();
}frmOnvifApp::~frmOnvifApp()
{server->stop();delete ui;
}void frmOnvifApp::initForm()
{//设置开启解码/需要解码后在这里显示OnvifDevicePush::disableDecode = false;//实例化设备服务类并关联信号槽server = new OnvifDeviceServer(this);connect(server, SIGNAL(pushImage(QString, QImage)), this, SLOT(pushImage(QString, QImage)));server->start();QStringList ips;ips << QtHelper::getLocalIPs();ui->cboxServerIp->addItems(ips);//不存在则取第一个int index = ui->cboxServerIp->findText(AppConfig::OnvifServerIp);if (index < 0) {QString ip = ips.first();AppConfig::OnvifServerIp = ip;AppConfig::OnvifServerHost = ip;AppConfig::OnvifPushHost = ip;}
}void frmOnvifApp::initConfig()
{VideoUtil::loadMediaUrl(ui->cboxMediaUrl, AppConfig::OnvifMediaUrl, UrlUtil::Simple);connect(ui->cboxMediaUrl->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->cboxServerIp->lineEdit()->setText(AppConfig::OnvifServerIp);connect(ui->cboxServerIp->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));connect(ui->cboxServerIp->lineEdit(), SIGNAL(textChanged(QString)), ui->txtServerHost, SLOT(setText(QString)));connect(ui->cboxServerIp->lineEdit(), SIGNAL(textChanged(QString)), ui->txtPushHost, SLOT(setText(QString)));ui->txtServerHost->setText(AppConfig::OnvifServerHost);connect(ui->txtServerHost, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtUserName->setText(AppConfig::OnvifUserName);connect(ui->txtUserName, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtUserPwd->setText(AppConfig::OnvifUserPwd);connect(ui->txtUserPwd, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtPushFlag->setText(AppConfig::OnvifPushFlag);connect(ui->txtPushFlag, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtPushHost->setText(AppConfig::OnvifPushHost);connect(ui->txtPushHost, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtPushPort->setText(QString::number(AppConfig::OnvifPushPort));connect(ui->txtPushPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtListenPort->setText(QString::number(AppConfig::OnvifListenPort));connect(ui->txtListenPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
}void frmOnvifApp::saveConfig()
{AppConfig::OnvifMediaUrl = ui->cboxMediaUrl->lineEdit()->text().trimmed();AppConfig::OnvifServerHost = ui->txtServerHost->text().trimmed();AppConfig::OnvifServerIp = ui->cboxServerIp->lineEdit()->text().trimmed();AppConfig::OnvifUserName = ui->txtUserName->text().trimmed();AppConfig::OnvifUserPwd = ui->txtUserPwd->text().trimmed();AppConfig::OnvifPushFlag = ui->txtPushFlag->text().trimmed();AppConfig::OnvifPushHost = ui->txtPushHost->text().trimmed();AppConfig::OnvifPushPort = ui->txtPushPort->text().toInt();AppConfig::OnvifListenPort = ui->txtListenPort->text().toInt();AppConfig::writeConfig();
}void frmOnvifApp::pushImage(const QString &, const QImage &image)
{if (ui->btnStart->text() == "停止服务") {ui->labImage->setImage(image, true);} else {ui->labImage->clear();}
}void frmOnvifApp::on_btnStart_clicked()
{if (ui->btnStart->text() == "启动服务") {        QString rtspUrl = QString("rtsp://%1:%2/stream/%3").arg(AppConfig::OnvifPushHost).arg(AppConfig::OnvifPushPort).arg(AppConfig::OnvifPushFlag);server->setPara(AppConfig::OnvifServerHost, AppConfig::OnvifServerIp, AppConfig::OnvifUserName, AppConfig::OnvifUserPwd);bool ok = server->append(AppConfig::OnvifPushFlag, AppConfig::OnvifListenPort, AppConfig::OnvifMediaUrl, rtspUrl);if (ok) {ui->txtPushUrl->setText(rtspUrl);ui->frame->setEnabled(false);ui->btnStart->setText("停止服务");}} else {server->clear();ui->labImage->clear();ui->txtPushUrl->clear();ui->frame->setEnabled(true);ui->btnStart->setText("启动服务");}
}#include "frmgb28181app.h"
#include "ui_frmgb28181app.h"
#include "qthelper.h"
#include "videoutil.h"
#include "urlutil.h"
#include "gb28181deviceserver.h"
#include "gb28181devicepush.h"frmGB28181App::frmGB28181App(QWidget *parent) : QWidget(parent), ui(new Ui::frmGB28181App)
{ui->setupUi(this);this->initForm();this->initConfig();
}frmGB28181App::~frmGB28181App()
{server->stop();delete ui;
}void frmGB28181App::initForm()
{//设置开启解码/需要解码后在这里显示GB28181DevicePush::disableDecode = false;//实例化设备服务类并关联信号槽server = new GB28181DeviceServer(this);connect(server, SIGNAL(statusChanged(QString, int)), this, SLOT(statusChanged(QString, int)));connect(server, SIGNAL(pushImage(QString, QImage)), this, SLOT(pushImage(QString, QImage)));server->start();QStringList ips;ips << QtHelper::getLocalIPs();ui->cboxDeviceIp->addItems(ips);//不存在则取第一个int index = ui->cboxDeviceIp->findText(AppConfig::GB28181DeviceIp);if (index < 0) {AppConfig::GB28181DeviceIp = ips.first();}
}void frmGB28181App::initConfig()
{VideoUtil::loadMediaUrl(ui->cboxMediaUrl, AppConfig::GB28181MediaUrl, UrlUtil::Simple);connect(ui->cboxMediaUrl->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->cboxSipProtocol->setCurrentIndex(ui->cboxSipProtocol->findText(AppConfig::GB28181SipProtocol));connect(ui->cboxSipProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));ui->txtServerId->setText(AppConfig::GB28181ServerId);connect(ui->txtServerId, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtServerRealm->setText(AppConfig::GB28181ServerRealm);connect(ui->txtServerRealm, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtServerIp->setText(AppConfig::GB28181ServerIp);connect(ui->txtServerIp, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtServerPort->setText(QString::number(AppConfig::GB28181ServerPort));connect(ui->txtServerPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtServerPwd->setText(AppConfig::GB28181ServerPwd);connect(ui->txtServerPwd, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->cboxDeviceIp->lineEdit()->setText(AppConfig::GB28181DeviceIp);connect(ui->cboxDeviceIp->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtDevicePort->setText(QString::number(AppConfig::GB28181DevicePort));connect(ui->txtDevicePort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtDeviceId->setText(AppConfig::GB28181DeviceId);connect(ui->txtDeviceId, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtChannelId->setText(AppConfig::GB28181ChannelId);connect(ui->txtChannelId, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtRegistInterval->setText(QString::number(AppConfig::GB28181RegistInterval));connect(ui->txtRegistInterval, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtHeartInterval->setText(QString::number(AppConfig::GB28181HeartInterval));connect(ui->txtHeartInterval, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));ui->txtHeartTimeout->setText(QString::number(AppConfig::GB28181HeartTimeout));connect(ui->txtHeartTimeout, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
}void frmGB28181App::saveConfig()
{AppConfig::GB28181MediaUrl = ui->cboxMediaUrl->lineEdit()->text().trimmed();AppConfig::GB28181SipProtocol = ui->cboxSipProtocol->currentText();AppConfig::GB28181ServerId = ui->txtServerId->text().trimmed();AppConfig::GB28181ServerRealm = ui->txtServerRealm->text().trimmed();AppConfig::GB28181ServerIp = ui->txtServerIp->text().trimmed();AppConfig::GB28181ServerPort = ui->txtServerPort->text().toInt();AppConfig::GB28181ServerPwd = ui->txtServerPwd->text().trimmed();AppConfig::GB28181DeviceIp = ui->cboxDeviceIp->lineEdit()->text().trimmed();AppConfig::GB28181DevicePort = ui->txtDevicePort->text().toInt();AppConfig::GB28181DeviceId = ui->txtDeviceId->text().trimmed();AppConfig::GB28181ChannelId = ui->txtChannelId->text().trimmed();AppConfig::GB28181RegistInterval = ui->txtRegistInterval->text().toInt();AppConfig::GB28181HeartInterval = ui->txtHeartInterval->text().toInt();AppConfig::GB28181HeartTimeout = ui->txtHeartTimeout->text().toInt();AppConfig::writeConfig();
}void frmGB28181App::statusChanged(const QString &id, int status)
{QString text = (status == 1 ? "已注册" : "已注销");ui->labImage->setText(text);
}void frmGB28181App::pushImage(const QString &, const QImage &image)
{if (ui->btnStart->text() == "停止服务") {ui->labImage->setImage(image, true);} else {ui->labImage->clear();}
}void frmGB28181App::on_btnStart_clicked()
{if (ui->btnStart->text() == "启动服务") {server->setPara(AppConfig::GB28181ServerId, AppConfig::GB28181ServerRealm, AppConfig::GB28181ServerIp, AppConfig::GB28181ServerPort, AppConfig::GB28181ServerPwd, AppConfig::GB28181RegistInterval, AppConfig::GB28181HeartInterval, AppConfig::GB28181HeartTimeout);bool ok = server->append(AppConfig::GB28181SipProtocol, AppConfig::GB28181DeviceIp, AppConfig::GB28181DevicePort, AppConfig::GB28181DeviceId, AppConfig::GB28181ChannelId, AppConfig::GB28181MediaUrl);if (ok) {ui->frame->setEnabled(false);ui->btnStart->setText("停止服务");}} else {server->clear();ui->labImage->clear();ui->frame->setEnabled(true);ui->btnStart->setText("启动服务");}
}void frmGB28181App::on_btnUpdate_clicked()
{server->update();server->catalog();
}
http://www.dtcms.com/a/405765.html

相关文章:

  • 01MemoryOS环境搭建 python3.10
  • 建设部网站职责划定html精美登录界面源码
  • 网站建设基本步骤顺序网站的整体风格
  • Leetcode 146. LRU 缓存 哈希表 + 双向链表
  • VideollaMA 3论文阅读
  • Android 14 系统 ANR (Application Not Responding) 深度分析与解决指南
  • 《红色脉络:一部PLMN在中国的演进史诗 (1G-6G)》 第11篇 | 核心网演进终局:从EPC到5GC——微服务与“云原生”
  • k8s中的NetworkPolicy
  • 【大语言模型】大模型后训练入门指南
  • 【初学】使用 node 编写 MCP Server
  • 阿里云云原生挑战官方用例SPL
  • 销售管理软件免费版什么叫seo优化
  • Apache POI 在 Linux 无图形界面环境下因字体配置问题导致Excel导出失败的解决方案
  • 咨询顾问进阶——146页PPT详解麦肯锡-企业管理整合咨询-组织设计方案【附全文阅读】
  • 力扣995. K 连续位的最小翻转次数
  • Resources$NotFoundException
  • pg下使用 TimescaleDB并创建1亿数据
  • 自动化脚本的操作逻辑与实现
  • UVa12418 Game of 999
  • 基于51单片机的音乐弹奏系统
  • 负载均衡式的在线OJ项目编写(二)
  • 美篇在哪个网站做的外链代发工具
  • Linux高级技巧之集群部署(七)
  • 外贸做那种网站wordpress获取图片的绝对地址
  • 【自然语言处理与大模型】RAFT(Retrieval Augmented Fine Tuning)方法
  • 湖南网站建设公司 找磐石网络一流跨境电商平台app排名
  • 动态IP使用中 报错407 怎么办???
  • 手机百度建设网站台州企业网站建设
  • 鞍山网站建设制作新潮远网站建设
  • 网站友情链接的好处东莞专业微网站建设