SimpleVideoServer
CameraWebServer 的demo使用esp32cam自己提供http服务和视频流,会有较大性能开销。而且需要内网穿透才能外网访问。本项目提供服务端合成视频流的方式,esp32cam只需要不停拍照发送给服务端,服务端处理浏览器查看视频的请求,合成视频流给浏览器。 我们可以把服务端程序部署在公网,便可可以通过这样的方式远程访问。
graph LR
e(esp32cam)
e1(esp32cam1)
e2(合宙esp32S3)
S(SimpleVideoServer)
e -->|帧|S
e1 -->|帧|S
e2 -->|帧|S
B(浏览器)
B2(浏览器2)
S -->|mjpeg视频通道1|B
S -->|mjpeg视频通道2|B
S -->|mjpeg视频通道3|B
S -->|mjpeg视频通道3|B2
本项目提供了,服务端代码与esp32cam(或合宙ESP32S3)的代码。
simpleVideoRecorder
目录下载为esp32cam(或合宙ESP32S3)的代码。
如果支持该项目,请点star
运行服务端
根据自己需要选择以下任意方式运行服务端
-
解压之后,进入对应目录点击run.bat文件启动服务器。
-
需要unzip或p7z等可以解压zip的应用
运行
tar -zxvf linux_release.tar.gz cd linux_release/ sh run.sh
-
发行版内部仅仅是一些java17 版本的class文件和jre以及启动脚本,你也可以使用任意其它的jre17运行这些class文件。并非需要发行版。
比如你希望在macos运行当前服务端时,将macos的jdk17或者jre17复制到linux发行版的目录中,替代其jre目录,参考run.sh中命令调用jre下java运行服务端。
-
访问视频服务
每个摄像头处在不同频道,访问不同的摄像头需要不同的地址。
但这个版本没有测试多频道,只能说理论上没有问题。
如鄙人执行的服务端日志打印含有esp32Cam接入的后的相关打印如下:
D:\Users\immor\idea\SimpleVideoServer\out\win_release>.\jre\bin\java -classpath SimpleVideoServer org.btik.server.video.UDP2Main ----- version:0.0.3 ----- [gitcode page] => https://gitcode.net/qq_26700087/simpleVideoServer snChannelBinderPort:[TCP] 8004 binder stared init buffer pool start dispatchers dispatcherPoolSize: 8 frameDelayTimeout: 3000 streamPort:[UDP] 8004 bufferPoolSize:500 udp channel loaded httpPort:[TCP] 8003 bio video server started Channel /7CDFA1FA0F08 is online http://127.0.0.1:8003/video/7CDFA1FA0F08 http://192.168.0.110:8003/video/7CDFA1FA0F08 http://192.168.137.1:8003/video/7CDFA1FA0F08
每接入一个摄像头会新建一个频道,在
Channel /{mac地址} is online:
的打印后会出现,相关可以访问视频流的地址。video后为通道地址,为设备的mac地址不含分隔符十六进制大写的字符串。
这个时候其实只是获取了设备的通道索引,并非开始传图片。
如果供电不足,还需要等待足够长的时间,特别是合宙ESP32S3,在供电不足情况下,可能需要等待数分钟视频才稳定。
这些地址是获取网卡上的ip拼接成http地址。如果是云服务器,其公网ip并非在网卡上。
部署在云服务器的同学把端口打开(需要开放安全组的端口见后文配置项相关说明)后,需要把内网ip替换成公网ip,或者域名即可。
每次重新启动接入服务器都会打印
Channel /{mac地址} is online:
如果反复打印,可以看看是否接触不良。 -
关于如何把视频界面嵌入其它网页
如果你擅长web开发,或者不喜欢在多个窗口查看多个摄像头可以参考以下方法增加自己的内容。
本视频流是允许跨域的,若希望在自己的网页里面加入本服务端提供esp32Cam视频窗口,
其实不用html的
iframe
标签,img
标签即可。比如以下html代码,新建一个文件比如
a.html
复制以下内容,根据实际情况,替换img
标签src
属性的内容。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>直播间</title> <style> .videoContainer{ display: inline-block; } </style> </head> <body> <div style="padding: 0;margin:30px auto; width: 1300px"> <div class="videoContainer"> <img src="http://127.0.0.1:8003/video/441793EE3C08"> </div> <div class="videoContainer"> <img src="http://127.0.0.1:8003/video/58BF2581F024"> </div> </div> </body> </html>
以上是我的两个esp32Cam的视野,效果如下:
也就是说,你可以把该项目植入任何其它可以用到web前端的项目。通过查询在线设备,可以动态打开每个摄像头的视频。
配置项
light-video.properties
http.port=8003
stream.port=8004
stream.bind.port=8004
frame.delay.skip.timeout=3000
udp.video.buffer.pool.size=500
udp.video.dispatcher.thread.size=8
udp.video.channel.size=128
http.port 为http的端口 TCP端口 公网时需要开放该端口。
stream.port esp32向服务端发送照片的端口 ,一般无需修改,修改则同步修改esp32中对应 的。UDP端口 公网时需要开放该端口。
stream.bind.port esp32 获取通道索引的端口 TCP端口 公网时需要开放该端口。
frame.delay.skip.timeout 接收esp32图片快于发给浏览器速度时,会造成图片积压,延时会逐步累积,当某帧图片接收和处理的延时超过当前阈值之后,丢弃该帧
udp.video.buffer.pool.size udp帧缓存池大小, 会固定占用一部分内存反复使用
udp.video.dispatcher.thread.size 分发线程数量,不是越多越好,目前不建议改大,因为当前mjpeg的带宽负载的压力根本无法在公网接大量摄像头,访问视频用户多也会同样占用带宽。
udp.video.channel.size 视频通道数量,会限制接入的数量,每个通道的索引在esp32接入的时候获取,该值不能超过255。并非同时在线数量,而是总设备数量,即是无其它设备在线,总数量用完,新的摄像头也无法接入。服务器重启后,则会重置,则需要esp32重启,重新获取通道索引。通道号的依据 是设备的MAC地址唯一对应一个索引。
注意事项
-
本代码未考虑安全场景,无鉴权,也无加密。无论是抓包还是发起访问都是毫无阻挡。若需要在公网使用,请自行设计安全机制。
-
src目录为服务端java源代码
没有其他需要可以下载上面的发型版本,已包含64位jre17,也可以使用自定义jre17运行。
-
📁 simpleVideoRecorder目录为esp32cam(或合宙ESP32S3)的代码使用platformio基于ardunio框架开发。
1.使用platformio开发
修改simpleVideoRecorder 目录下的platformio.ini不同env的串口
切换开发板类型 修改以下内容切换开发板环境配置。来确定使用esp32cam配置或者使用合宙S3的配置。
[platformio] default_envs = esp32cam ;default_envs = heZhouS3
若使用命令则可以使用 -e 选项 后接具体env。
设置esp32 的CORE_DEBUG 日志级别,默认为info。
build_flags =XXX -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO ;-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
2.使用ardunio IDE开发
重命名文件 ,新建项目
为了保险起见,你可以把源码中
simpleVideoRecorder.cpp
重命名为simpleVideoRecorder.ino
选择开发板
选择开发板 为esp32cam,需要安装esp32环境 。
使用合宙S3时选择
ESP32S3 Dev Module
,一般默认就好,可以注意看psram需要设置为禁用。若找不到ESP32S3相关开发板,则说明你的ide上的esp32相关环境未安装2.0以上的版本。添加(国内不建议使用以下json可以使用本人提供的json地址)
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json
你的PC可能ping不通这个地址,仅仅因为DNS无法解析,可以使用一些公共DNS服务,如腾讯DNS 阿里DNS等等。
由于包很大也较多失败率也会很高。
所以建议使用我提供的json,虽然后缀看起来是zip,其实只是重命名了一下
https://gitcode.net/qq_26700087/espressif-mirror/uploads/edeb3963916ca38ef014042d7d212cc5/package_esp32_dev_index.json.zip
选择开发板引脚定义
两个宏注释其中一个,二选一
#define CAMERA_MODEL_AI_THINKER #define HE_ZHOU_S3
设置CORE DEBUG 级别
在arduino ide的 工具 -> CORE DEBUG LEVEL 某些打印至少需要 info级别才能打印。
-
如果在局域网也可以使用PC作为服务端,查看充当服务端的PC的ip。
打开命令行,执行ipconfig。找到wifi所在网络的网卡ip.
-
修改simpleVideoRecorder.cpp中的wifi的ssid和密码
-
可以使用linux的同学,自行根据实际组网查看和配置网络