esp32cam的udp服务视频传输

esp32cam

/*
下载程序  按住接口板上的IO0 在程序上传的时候 按一下 开发板上的rst按钮  待程序开始上传  在松开 IO0
*/

#include   //wifi功能需要的库
#include 
#include "esp_camera.h"
#include 
WiFiUDP Udp;                             //声明UDP对象
const char* wifi_SSID = "esp32";         //存储AP的名称信息 生成一个wifi 网络  方便客户端连接
const char* wifi_Password = "12345678";  //存储AP的密码信息
uint16_t udp_port = 1122;                //存储需要监听的端口号  eps32cam接收数据 和 往其他客户端 发送数据的端口
#define maxcache 1430  //图片数据分帧发送
bool is_tran_camera = false;  //是否传输视频数据
IPAddress ip_address;  //客户端的ip
const int delay_time = 5000;  //初始化延时时间
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27

#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
static camera_config_t camera_config = {
  .pin_pwdn = PWDN_GPIO_NUM,
  .pin_reset = RESET_GPIO_NUM,
  .pin_xclk = XCLK_GPIO_NUM,
  .pin_sscb_sda = SIOD_GPIO_NUM,
  .pin_sscb_scl = SIOC_GPIO_NUM,

  .pin_d7 = Y9_GPIO_NUM,
  .pin_d6 = Y8_GPIO_NUM,
  .pin_d5 = Y7_GPIO_NUM,
  .pin_d4 = Y6_GPIO_NUM,
  .pin_d3 = Y5_GPIO_NUM,
  .pin_d2 = Y4_GPIO_NUM,
  .pin_d1 = Y3_GPIO_NUM,
  .pin_d0 = Y2_GPIO_NUM,
  .pin_vsync = VSYNC_GPIO_NUM,
  .pin_href = HREF_GPIO_NUM,
  .pin_pclk = PCLK_GPIO_NUM,

  .xclk_freq_hz = 20000000,
  .ledc_timer = LEDC_TIMER_0,
  .ledc_channel = LEDC_CHANNEL_0,

  .pixel_format = PIXFORMAT_JPEG,
  .frame_size = FRAMESIZE_VGA,
  .jpeg_quality = 12,
  .fb_count = 1,
};
//摄像头初始化
esp_err_t camera_init() {
  //initialize the camera
  esp_err_t err = esp_camera_init(&camera_config);
  if (err != ESP_OK) {
    Serial.println("Camera Init Failed!");
    return err;
  }
  sensor_t* s = esp_camera_sensor_get();
  //initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV2640_PID) {
    //        s->set_vflip(s, 1);//flip it back
    //        s->set_brightness(s, 1);//up the blightness just a bit
    //        s->set_contrast(s, 1);
  }
  Serial.print(".");
  Serial.print(".");
  Serial.print(".");
  Serial.print(".");
  Serial.print(".");
  Serial.println(".");
  Serial.println("Camera Init OK!");
  return ESP_OK;
}
//接收数据的处理函数
void recv_data() {
  int packetSize = Udp.parsePacket();  //获取当前队首数据包长度
  if (packetSize)                      //如果有数据可用
  {
    char buf[packetSize];
    Udp.read(buf, packetSize);  //读取当前包数据
    Serial.print("Received: ");
    Serial.print(buf);
    Serial.print("\t From IP: ");
    Serial.print(Udp.remoteIP());
    Serial.print("\t From Port: ");
    Serial.println(Udp.remotePort());
    ip_address = Udp.remoteIP();
    String tmp = String(buf);
    //打开视频数据传输
    if(tmp.substring(0,5) == "camon"){
      is_tran_camera = true;
      Udp.beginPacket(ip_address, udp_port);
      Udp.print("Camera ON!");
      Udp.endPacket();
      Serial.println("Camera ON!");
    }
    // 关闭视频数据传输
    if(tmp.substring(0,6) == "camoff"){
      is_tran_camera = false;
      Udp.beginPacket(ip_address, udp_port);
      Udp.print("Camera OFF");
      Udp.endPacket();
      Serial.println("Camera OFF");
    }
  }
}
// 传输视频数据
void cssp() {
  camera_fb_t* fb = esp_camera_fb_get();
  uint8_t* temp = fb->buf;  //这个是为了保存一个地址,在摄像头数据发送完毕后需要返回,否则会出现板子发送一段时间后自动重启,不断重复
  if (!fb) {
    Serial.print("Camera Capture Failed!");
  } else {
    Udp.beginPacket(ip_address, udp_port);
    Udp.print("FrameBegin");  //视频数据的标志头
    Udp.endPacket();
    // 将图片数据分段发送
    int leng = fb->len;
    int timess = leng / maxcache;
    int extra = leng % maxcache;
    for (int j = 0; j < timess; j++) {
      Udp.beginPacket(ip_address, udp_port);
      Udp.write(fb->buf, maxcache);
      Udp.endPacket();
      for (int i = 0; i < maxcache; i++) {
        fb->buf++;
      }
    }
    // 发送剩余数据
    Udp.beginPacket(ip_address, udp_port);
    Udp.write(fb->buf, extra);
    Udp.endPacket();
    Udp.beginPacket(ip_address, udp_port);
    Udp.print("FrameOverr");  //视频数据的标志尾
    Udp.endPacket();
    Serial.print("This Frame Length:");
    Serial.print(fb->len);
    Serial.println(". \t Succes To Send Image For UDP!");
    //return the frame buffer back to the driver for reuse
    fb->buf = temp;            //将当时保存的指针重新返还
    esp_camera_fb_return(fb);  //这一步在发送完毕后要执行,具体作用还未可知。
  }
  delay(10000);  //不加延时会导致数据发送混乱 稍微延时增加数据传输可靠性
}
// udp服务初始化
void udp_init() {
  WiFi.softAP(wifi_SSID, wifi_Password);  //打开ESP32热点
  Udp.begin(udp_port);                    //启动UDP监听这个端口
  Serial.print(".");
  Serial.print(".");
  Serial.print(".");
  Serial.print(".");
  Serial.print(".");
  Serial.println(".");
  Serial.print("IP:");
  Serial.print(WiFi.softAPIP());  //串口输出模块IP地址
  Serial.print(":");              //串口输出模块IP地址
  Serial.println(udp_port);       //串口输出模块IP地址
}
void setup() {
  Serial.begin(115200);  //开启串口,波特率为115200
  delay(delay_time);
  Serial.println();
  Serial.println("Sys Is Initing!");
  delay(delay_time);
  camera_init();
  delay(delay_time);
  udp_init();
  delay(delay_time);
  Serial.println("Sys Is Running!");
}

void loop() {
  recv_data();
  if (is_tran_camera) {
    cssp();
  }
}

你可能感兴趣的:(ESP32,udp,音视频,单片机)