文章目录
1.移植到《esp32-web-camera》 2. jpeg2avi使用方法 2.1 何处调用jpeg2avi_start 2.2 何处调用jpeg2avi_add_frame 2.3何处调用jpeg2avi_end
3.编译运行工程 4.源代码
昨天测试了保存图片到sd卡,我就想,视频就是一帧帧图片构成的,现在离保存视频只差一步之遥。网络上使用ESP32保存视频,最多是python+openCV的方法。我想使用esp-idf原生态应该也可以做到。
于是百度到下面的文章:
1.作者:原野追逐,《
JPEG流封装AVI视频》。这篇文章将原理结合代码,讲得非常详细。
这个没有语音数据的 。
立马把源代码拷贝过来,几乎不用修改,直接就可以使用。非常感谢作者原野追逐的贡献。
1.移植到《esp32-web-camera》
在上一篇文章《VScode+esp-idf:安信可esp32-cam开发板测试sd卡》的工程里增加文件 “Jpeg2AVI.c” “list.c”,其他不变:
set( COMPONENT_SRCS "app_main.c" "app_wifi.c" "app_camera.c" "app_httpd.c"
"app_mdns.c" "app_sd.c" "Jpeg2AVI.c" "list.c" )
2. jpeg2avi使用方法
准备开始
重复写入
准备结束
fopen
jpeg2avi_start
jpeg2avi_add_frame
jpeg2avi_end
fclose
2.1 何处调用jpeg2avi_start
在我们这个工程中,在SdCard_init函数最后面调用jpeg2avi_start(这里的avi文件名应该有实时时间戳):
void SdCard_init ( void )
{
. . . . . .
sdmmc_card_print_info ( stdout , card) ;
fp_avi = fopen ( "/sdcard/sample.avi" , "wb" ) ;
if ( fp_avi == NULL ) {
ESP_LOGE ( TAG, "Failed to open file for writing" ) ;
return ;
}
jpeg2avi_start ( fp_avi) ;
}
2.2 何处调用jpeg2avi_add_frame
这个 StartStream 按键会启动实时视频读取和传输到网页,在这里面把读取的图片写入avi文件,保存到sd卡。 StartStream 按键触发的函数是 stream_handler :
2.3何处调用jpeg2avi_end
这里对函数进行简单的介绍:
void jpeg2avi_end ( FILE * fp, int width, int height, int fps) ;
照片的宽度和高度就是像素,最高像素是由摄像头的物理参数决定的,小于最高像素就可以由软件设定。网页中也可以修改: 出于各种原因,我选了800(宽) x 600(高)的像素。这里说一下如何在初始化时设置像素: 宏定义 FRAMESIZE_SVGA (800x600)在 《$ENV{IDF_PATH}/examples/esp32-web-camera-master/components/esp32-camera/driver/include/sensor.h》中:
typedef enum {
FRAMESIZE_96X96,
FRAMESIZE_QQVGA,
FRAMESIZE_QCIF,
FRAMESIZE_HQVGA,
FRAMESIZE_240X240,
FRAMESIZE_QVGA,
FRAMESIZE_CIF,
FRAMESIZE_HVGA,
FRAMESIZE_VGA,
FRAMESIZE_SVGA,
FRAMESIZE_XGA,
FRAMESIZE_HD,
FRAMESIZE_SXGA,
FRAMESIZE_UXGA,
FRAMESIZE_FHD,
FRAMESIZE_P_HD,
FRAMESIZE_P_3MP,
FRAMESIZE_QXGA,
FRAMESIZE_QHD,
FRAMESIZE_WQXGA,
FRAMESIZE_P_FHD,
FRAMESIZE_QSXGA,
FRAMESIZE_INVALID
} framesize_t ;
调用 jpeg2avi_end 函数,首先要停止写入,就是先停止实时视频。我借用调整LED亮度的命令调用这个函数。 有这个命令的前提是配置LED闪光灯使能: 在函数 cmd_handle 中调用:
3.编译运行工程
编译,写入,运行: 1.第一次点击StartStream 按键开始录制; 2.第二次点击StartStream 按键停止录制; 3.点击 LED Intensity 完成收尾工作。
I ( 706575 ) camera_httpd: MJPG: 21235B 76ms ( 13 .2fps) , AVG: 69ms ( 14 .5fps) , 0 +0+0+0= 0 0
I ( 706655 ) camera_httpd: MJPG: 23257B 79ms ( 12 .7fps) , AVG: 69ms ( 14 .5fps) , 0 +0+0+0= 0 0
I ( 706715 ) camera_httpd: MJPG: 20800B 63ms ( 15 .9fps) , AVG: 69ms ( 14 .5fps) , 0 +0+0+0= 0 0
I ( 706785 ) camera_httpd: MJPG: 23200B 68ms ( 14 .7fps) , AVG: 69ms ( 14 .5fps) , 0 +0+0+0= 0 0
I ( 706855 ) camera_httpd: MJPG: 23911B 74ms ( 13 .5fps) , AVG: 69ms ( 14 .5fps) , 0 +0+0+0= 0 0
I ( 706925 ) camera_httpd: MJPG: 23817B 71ms ( 14 .1fps) , AVG: 70ms ( 14 .3fps) , 0 +0+0+0= 0 0
I ( 706995 ) camera_httpd: MJPG: 23163B 66ms ( 15 .2fps) , AVG: 70ms ( 14 .3fps) , 0 +0+0+0= 0 0
I ( 707075 ) camera_httpd: MJPG: 22794B 74ms ( 13 .5fps) , AVG: 70ms ( 14 .3fps) , 0 +0+0+0= 0 0
I ( 707145 ) camera_httpd: MJPG: 23467B 72ms ( 13 .9fps) , AVG: 70ms ( 14 .3fps) , 0 +0+0+0= 0 0
W ( 707215 ) httpd_txrx: httpd_sock_err: error in send : 104
I ( 707215 ) camera_httpd: Set LED intensity to 0
W ( 707215 ) httpd_uri: httpd_uri: uri handler execution failed
I ( 709555 ) camera_httpd: led_intensity = 64
I ( 709585 ) camera_httpd: close AVI file
从打印出来的信息,写入的视频流,1秒才13-15帧,视频不是很流畅;可见要同时完成读取摄像头数据、传输到网页、写入sd卡这3个功能,对esp32来说很吃力。
4.源代码
本文为了测试保存avi视频,几乎没有什么逻辑可言,纯粹为了测试功能而实现。读者可以在这个的基础上去完善。 比如我就想做一个延时拍摄的摄像机,可以设置1秒-60秒拍一张,然后以1秒24帧的速度播放,这个esp32就能轻松胜任。用按键启动和停止拍摄。 https://gitee.com/huangweide001/esp32_test/tree/master/camera_web_server_avi
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)