0


esp32cam 服务端远程视频方案

esp32cam 服务端远程视频方案

说明

#mermaid-svg-p6MVOztAqoknqrsn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-p6MVOztAqoknqrsn .error-icon{fill:#552222;}#mermaid-svg-p6MVOztAqoknqrsn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-p6MVOztAqoknqrsn .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-p6MVOztAqoknqrsn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-p6MVOztAqoknqrsn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-p6MVOztAqoknqrsn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-p6MVOztAqoknqrsn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-p6MVOztAqoknqrsn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-p6MVOztAqoknqrsn .marker.cross{stroke:#333333;}#mermaid-svg-p6MVOztAqoknqrsn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-p6MVOztAqoknqrsn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-p6MVOztAqoknqrsn .cluster-label text{fill:#333;}#mermaid-svg-p6MVOztAqoknqrsn .cluster-label span{color:#333;}#mermaid-svg-p6MVOztAqoknqrsn .label text,#mermaid-svg-p6MVOztAqoknqrsn span{fill:#333;color:#333;}#mermaid-svg-p6MVOztAqoknqrsn .node rect,#mermaid-svg-p6MVOztAqoknqrsn .node circle,#mermaid-svg-p6MVOztAqoknqrsn .node ellipse,#mermaid-svg-p6MVOztAqoknqrsn .node polygon,#mermaid-svg-p6MVOztAqoknqrsn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-p6MVOztAqoknqrsn .node .label{text-align:center;}#mermaid-svg-p6MVOztAqoknqrsn .node.clickable{cursor:pointer;}#mermaid-svg-p6MVOztAqoknqrsn .arrowheadPath{fill:#333333;}#mermaid-svg-p6MVOztAqoknqrsn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-p6MVOztAqoknqrsn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-p6MVOztAqoknqrsn .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-p6MVOztAqoknqrsn .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-p6MVOztAqoknqrsn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-p6MVOztAqoknqrsn .cluster text{fill:#333;}#mermaid-svg-p6MVOztAqoknqrsn .cluster span{color:#333;}#mermaid-svg-p6MVOztAqoknqrsn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-p6MVOztAqoknqrsn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

mjpeg视频流

      esp32cam
     

      SimpleVideoServer
     

      浏览器
     

一种较为流畅的esp32cam远程视频方案

您需要准备

物料说明esp32cam开发板esp32cam,本人是使用其自带摄像头,代码仅仅在其自带摄像头下测试一台装有windows或者linux操作系统的计算机用于运行服务端USB转TTL模块/或底座用于烧录/串口监控杜邦线若干用于io0接地/使用底座烧录不需要

鄙人无MacOs系统PC,未对MacOS进行测试。但服务端由java编写,自行下载macOS版本的jdk17,运行服务端,理论上不会有问题

也可以将java源代码重新编译,甚至移植到安卓App上。

本文以windows系统为例,使用安信可家

esp32cam

模块 和安信可家

USB转TTL CP2012模块

烧录esp32cam

本文以ardunio 框架开发,你可以选择 ardunio ide 编译和烧录

或者platformio(基于vs code/clion)新建项目选择 以ardunio framework新建。

ardunio ide 准备esp32cam环境

1.追加附加板地址

打开菜单 -> 文件 -> 首选项

ardunio IDE 首选项

附加开发板管理器网址中追加一行

https://dl.espressif.com/dl/package_esp32_index.json

最近出现了下面这个地址,这个是esp32 的2.0环境,一些新特性需要,可能不需要上方的那个json。

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json

2.安装esp32环境

在 工具 -> 开发板 -> 开发板管理器里 搜索

esp32

点击进行安装。

此处可能需要把dns修改为腾讯或者阿里公共dns,才容易成功。

ardunio ide安装esp32

3.新建项目

选择esp32cam

ardunio ide选择esp32cam

platformio 准备esp32cam环境

新建项目找到

AI Thinker ESP32-CAM

,则选择了开发板。框架选择 ardunio。若没有初始化esp32环境,会自动下载,同样建议修改dns。

新建后生成的ini文件如下(串口相关设置需要手动添加)

[env:esp32cam]
platform = espressif32
board = esp32cam
framework = arduino
upload_speed= 115200
upload_port = COM3
monitor_speed= 115200
monitor_port = COM3

代码

存在多个文件和服务端相关代码,点此跳转

引导方面本文更加详细。可先参考本文。

esp32cam代码共两个文件。也可以合成一个。

文件 ai_thinker_esp32_cam_meta.h

表示esp32cam相关GPIO引脚定义

#ifndefAI_THINKER_32_CAM_META#defineAI_THINKER_32_CAM_META#definePWDN_GPIO_NUM32#defineRESET_GPIO_NUM-1#defineXCLK_GPIO_NUM0#defineSIOD_GPIO_NUM26#defineSIOC_GPIO_NUM27#defineY9_GPIO_NUM35#defineY8_GPIO_NUM34#defineY7_GPIO_NUM39#defineY6_GPIO_NUM36#defineY5_GPIO_NUM21#defineY4_GPIO_NUM19#defineY3_GPIO_NUM18#defineY2_GPIO_NUM5#defineVSYNC_GPIO_NUM25#defineHREF_GPIO_NUM23#definePCLK_GPIO_NUM22#endif
文件main.cpp

ardunio ide里无需考虑该文件名,而只是把该文件内容复制到你的

.ino

文件中。

请按照具体情况修改wifi的ssid和密码,一般可以使用你pc运行服务端,可以将PC的ip填写到以下源文件

host

变量的值中。

#include<Arduino.h>#include<WiFi.h>#include"esp_camera.h"#defineCAMERA_MODEL_AI_THINKER#include"ai_thinker_esp32_cam_meta.h"char* ssid ="test0";constchar* passwd ="12345687";constchar* host ="192.168.137.1";

WiFiClient streamSender;voidconnectWifi(constchar* ssid,constchar* passphrase){
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, passphrase);

    Serial.println("connecting to router... ");//等待wifi连接成功while(WiFi.status()!= WL_CONNECTED){
        Serial.print(".");delay(500);}
    Serial.print("\nWiFi connected, local IP address:");
    Serial.println(WiFi.localIP());}voidsetup(){
    Serial.begin(115200);
    Serial.setDebugOutput(true);while(!Serial){/* code */}
    camera_config_t config;
    config.ledc_channel = LEDC_CHANNEL_0;
    config.ledc_timer = LEDC_TIMER_0;
    config.pin_d0 = Y2_GPIO_NUM;
    config.pin_d1 = Y3_GPIO_NUM;
    config.pin_d2 = Y4_GPIO_NUM;
    config.pin_d3 = Y5_GPIO_NUM;
    config.pin_d4 = Y6_GPIO_NUM;
    config.pin_d5 = Y7_GPIO_NUM;
    config.pin_d6 = Y8_GPIO_NUM;
    config.pin_d7 = Y9_GPIO_NUM;
    config.pin_xclk = XCLK_GPIO_NUM;
    config.pin_pclk = PCLK_GPIO_NUM;
    config.pin_vsync = VSYNC_GPIO_NUM;
    config.pin_href = HREF_GPIO_NUM;
    config.pin_sscb_sda = SIOD_GPIO_NUM;
    config.pin_sscb_scl = SIOC_GPIO_NUM;
    config.pin_pwdn = PWDN_GPIO_NUM;
    config.pin_reset = RESET_GPIO_NUM;
    config.xclk_freq_hz =20000000;
    config.pixel_format = PIXFORMAT_JPEG;// if PSRAM IC present, init with UXGA resolution and higher JPEG quality//                      for larger pre-allocated frame buffer.if(psramFound()){
        config.frame_size = FRAMESIZE_UXGA;
        config.jpeg_quality =10;
        config.fb_count =2;}else{
        config.frame_size = FRAMESIZE_SVGA;
        config.jpeg_quality =12;
        config.fb_count =1;}// camera init
    esp_err_t err =esp_camera_init(&config);if(err != ESP_OK){
        Serial.printf("Camera init failed with error 0x%x", err);return;}
    Serial.println("get sensor ");
    sensor_t* s =esp_camera_sensor_get();// drop down frame size for higher initial frame rate
    s->set_framesize(s, FRAMESIZE_VGA);connectWifi(ssid, passwd);
    Serial.println("connect stream channel");if(!streamSender.connect(host,8004)){
        Serial.println("connect stream channel failed");}
    streamSender.setNoDelay(true);// 发送mac地址作为设备序列号,用于摄像头频道号uint8_t mac[6];
    WiFi.macAddress(mac);char macStr[12]={0};sprintf(macStr,"%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3],
            mac[4], mac[5]);
    Serial.println("sprint mac ");
    streamSender.print(String(macStr));
    streamSender.flush();}voidloop(){
    camera_fb_t* fb =NULL;
    size_t len =0;
    Serial.println("do loop");uint8_t end[5]={'j','p','e','g','\n'};while(true){
        fb =esp_camera_fb_get();if(!fb){
            Serial.println("Camera capture failed");return;}
        len = fb->len;
        streamSender.write(fb->buf, len);
        streamSender.write(end,5);
        streamSender.flush();esp_camera_fb_return(fb);}}

查看PC的ip的办法

按win + R 输入

cmd

按enter打开控制台

输入

ipconfig

回车,找到有ipv4地址的那一行。如果有多个适配器,大概率需要自己确定和无线路由器所在同一网络的ip。

一般wifi连接则是网卡名带 无线适配器,而路由器网线直连则自己抉择。

烧录

使用USB转TTL模块时接线

USB转TTL模块引脚esp32cam引脚5V5VGNDGNDTXDU0RRXDU0T
当上载控制台出现连接某某com口,请尽快连接IO0和GND,再按RST。

使用烧录底座将esp32cam安上底座,则无需考虑针脚连接具体如何。

串口监控

鄙人不知烧录底座是否可以串口监控,使用USB转TTL模块时,在烧录完成后,断开IO0与GND的连接,再按RST重启esp32cam则可以查看串口打印,但此时没有运行服务端SimpleVideoServer。

下载和运行服务端

根据自己需要选择以下任意方式运行服务端

  • 下载 windows服务端发行版解压之后,进入对应目录点击run.bat文件启动服务器。
  • 下载linux服务端发行版需要unzip或p7zip等可以解压zip的应用运行unzip SimpleVideoSever_linux.zipcd linux_release/sh run.sh
  • 发行版内部仅仅是一些java17 版本的class文件和jre以及启动脚本,你可以使用任意其它的jre17运行这些class文件。并非需要发行版。
  • 访问视频服务新增了频道功能,也就是说每个摄像头处在不同频道,访问不同的摄像头需要不同的地址。如鄙人执行的服务端日志打印含有esp32Cam接入的后的相关打印如下:D:\Users\immor\idea\SimpleVideoServer\out\win_release>.\jre\bin\java -classpath SimpleVideoServer org.btik.server.video.Mainbio video server startedbio Device Channel startednew channel:http://127.0.0.1:8003/video/441793EE3C08http://192.168.0.116:8003/video/441793EE3C08http://192.168.137.1:8003/video/441793EE3C08start /192.168.137.234:53051每接入一个esp32Cam会新建一个频道,在new channel:的打印后会出现,相关可以访问视频流的地址。你可以在本机,或者局域网的其他设备访问。部署在云服务器的同学把端口打开后,把内网ip替换成公网ip,或者域名即可。
  • 关于如何把视频节目嵌入其它网页如果你擅长web开发,或者不喜欢在多个窗口查看多个摄像头可以参考以下方法增加自己的内容。本视频http请求是允许跨域的,若希望在自己的网页里面加入本服务端提供esp32Cam视频窗口,其实不用html的 iframe标签,img标签即可。比如以下html代码,新建一个文件比如a.html 复制以下内容,根据实际情况,替换img标签src属性的内容。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>直播间</title><style>.videoContainer{display: inline-block;}</style></head><body><divstyle="padding: 0;margin:30px auto;width: 1300px"><divclass="videoContainer"><imgsrc="http://127.0.0.1:8003/video/441793EE3C08"></div><divclass="videoContainer"><imgsrc="http://127.0.0.1:8003/video/58BF2581F024"></div></div></body></html>以上是我的两个esp32Cam的视野,效果如下:esp32Cam双摄像头也就是说,你可以把该项目植入任何其它可以用到web前端的项目。通过查询在线设备,可以动态打开每个摄像头的视频。

配置项

一般无需修改,但提供改法。后续此处可能会有变化,可以跟随该开源项目SimpleVideoSever具体描述。

light-video.properties

里面含有三个配置

http.port=8003
http.clients.limit=10
stream.port=8004

http.port 为http的端口。

http.clients.limit 摄像头在线接入限制数。本意是想限制客户端参与的数量故名为http.clients.limit,实际的实现是限制了摄像头的数量

stream.port esp32cam像服务端发送照片的端口,在本项目中使用该默认端口,如果需要修改,一并修改esp32cam代码中连接的端口。一般无需修改。

使用远程服务器如云服务器同学则无需额外指导。注意本服务端毫不安全,没有任何安全机制,在公网使用不宜长久暴露服务端口。

标签: 音视频 ide mcu

本文转载自: https://blog.csdn.net/qq_26700087/article/details/125435597
版权归原作者 云逸之 所有, 如有侵权,请联系我们删除。

“esp32cam 服务端远程视频方案”的评论:

还没有评论