esp32cam-rtsp 项目中 rtsp 实时视频流是一个非常重要的功能,但只能使用在 STA 模式(即 ESP32 开发板连接到路由器获取 IP 地址),AP 热点模式下不能使用,下面介绍修订源码,实现 AP 模式支持 RTSP,并且提高访问速度。

一、RTSP 功能概述
1、RTSP 是什么
RTSP(Real-Time Streaming Protocol,实时流传输协议)
- 标准:IETF 标准实时流媒体控制协议,只负责「控制」,不负责传输画面数据;
- 端口:默认 554(你项目里使用的端口);
- 定位:像「视频遥控器」,专门用来控制摄像头、NVR 的播放、暂停、拉流、录像;
- 配套传输:画面码流(JPEG/H.264/H.265)依靠 RTP 协议打包发送。
两个核心配套协议区分
- RTSP:控制信令 客户端 (VLC) ↔ 设备 (ESP32) 之间交互指令:DESCRIBE、SETUP、PLAY、PAUSE、TEARDOWN。
- RTP:媒体数据承载 真正装 JPEG / 视频帧的数据包,走 UDP 或 TCP,负责画面传输。
2、RTSP 标准 5 步交互流程
- DESCRIBE VLC 询问设备:你支持什么分辨率、编码、帧率、通道地址; ESP32 返回媒体描述(SDP 文本),告知路径
/mjpeg/1。 - SETUP 协商传输通道:UDP / TCP,分配端口,建立 RTP 收发通道。
- PLAY VLC 下发播放指令,ESP32 开始持续抓取摄像头帧,打包 RTP 发送。
- 持续传输:RTP 分包推送画面,RTSP 定时保活(OPTIONS)防止断连。
- TEARDOWN 关闭播放器,发送断开指令,ESP32 停止推流、释放缓冲区。
3、两种传输模式
1)UDP(默认)
- 优点:延迟极低、开销小;
- 缺点:无重传,WiFi 弱网丢包 → 花屏、卡顿、掉帧; ESP32 无线环境极易出现丢包,RTSP 帧率暴跌。
2)TCP(推荐Windows 使用)
RTP 媒体数据嵌入 RTSP 554 端口 TCP 通道,可靠传输、不丢包 ,VLC 参数添加 :rtsp_transport=tcp; 代价:多一层封装,轻微增加延迟,但画面稳定。
4、RTSP/HTTP MJPEG对比
1)HTTP MJPEG(网页 http://192.168.4.1/stream)
- 工作逻辑:浏览器循环 GET 请求,每次返回一整张 JPEG;
- 无复杂协议封装、无会话管理、无 RTP 分片;
- 优势:ESP32 负载极低、帧率高、延迟最小;
- 缺点:只能单客户端、不支持录像、无标准流媒体设备兼容。
2) RTSP(rtsp://192.168.4.1:554/mjpeg/1)
- 优势:标准安防协议,支持 VLC、NVR、监控软件、手机播放器;支持多路客户端、录像、回放控制;
- 劣势:多层协议封装(RTSP+RTP),CPU/PSRAM 开销更大,同等硬件下帧率低于 HTTP 流。
5、RTSP 典型应用场景
- 监控摄像头(海康 / 大华 / ESP32-CAM);
- 直播低延迟设备、IP 摄像头;
- NVR 网络硬盘录像机存储录像;
- 专业播放器 VLC、PotPlayer、安防客户端。
6、常用 RTSP 地址格式说明
rtsp://[设备IP]:554/[流路径]
rtsp://192.168.4.1:554/mjpeg/1
192.168.4.1:ESP32 AP 热点 IP;554:RTSP 标准端口;/mjpeg/1:媒体流标识,区分多路摄像头通道。
7、RTSP 常见缺陷
- 防火墙容易拦截 554 端口;
- 原生不支持浏览器直接播放(Chrome/Edge 不解析 RTSP,只能用 VLC);
- 嵌入式 MCU(ESP32)算力有限,RTSP 封装开销会明显降低帧率;
- UDP 模式无线环境丢包严重,必须强制 TCP 传输才能稳定。
二、源码移植
1、platformio.ini 环境配置
确认宏写在对应板子环境内,不要写全局:
[env:esp32cam_s3_wroom_n16r8]
platform = espressif32
board = esp32cam_s3_wroom_n16r8
framework = arduino
build_flags =
-Ofast
-D 'BOARD_NAME="${this.board}"'
-D 'CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE'
-D 'IOTWEBCONF_PASSWORD_LEN=64'
# RTSP核心开关,必须在当前env内
-DENABLE_RTSP
-DBOARD_HAS_PSRAM
-DCONFIG_SPIRAM
-DCONFIG_SPIRAM_MODE_OCT
-DCONFIG_SPIRAM_SPEED_80M
board_build.arduino.memory_type = qio_opi
board_build.psram = 8MB
monitor_speed = 115200
monitor_filters = log2file, time, no_color, esp32_exception_decoder
注:配合 ini 文件最后 2 行的串口配置,在项目的 main.cpp 文件,setup( )中注释 //Serial.setDebugOutput(true);语句,log_i 调试信息才会串口输出。
2、start_rtsp_server 分析
项目源码的 main.cpp 主文件中, setup() 中不能调用启动start_rtsp_server 函数,否则程序运行会崩溃。
assert failed: tcpip_send_msg_wait_sem IDF/components/lwip/lwip/src/api/tcpip.c:455 (Invalid mbox)
崩溃原理
LWIP TCP/IP 内核消息队列(mbox)未初始化,你在 setup() 直接调用 start_rtsp_server() 创建 WiFiServer(RTSP 底层依赖),此时:
- WiFi AP 网络栈、lwip tcpip 任务还未完全初始化完成;
rtsp_server构造函数内部执行WiFiServer::begin(554),底层调用netconn_new操作未就绪的 TCPIP 消息队列,触发断言崩溃、设备自动重启。
堆栈链路印证
setup() -> on_connected() -> start_rtsp_server() -> new rtsp_server()
-> WiFiServer::begin() -> lwip_socket -> netconn_new -> tcpip_send_msg_wait_sem 断言失败
原设计把 start_rtsp_server 放在 on_connected WiFi 连接回调,是为了等待网络栈完全就绪,强行在 setup 提前调用,网络层未就绪直接崩溃。
3、正确启动 RTSP 服务
延时延后启动 RTSP,等待 AP 网络初始化完成(AP 模式专用)
项目源码的 main.cpp,不在 setup 直接调用on_connected(),改用loop( )中 延时延迟启动,给 LWIP/AP 栈充足初始化时间:
全局增加标志位
bool rtsp_started = false;
loop 函数内延时执行
void loop()
{
// 等待8秒,确保AP、tcpip、lwip全部初始化完成
if(!rtsp_started && millis() > 8000 && camera_init_result == ESP_OK)
{
log_i("Delay start RTSP after AP init complete");
start_rtsp_server();
rtsp_started = true;
}
// 原有loop逻辑...
}
优势:不破坏原有回调逻辑,避开网络未就绪时序,不会触发 lwip 断言崩溃。

4、PlatformIO 6.x 命令
# 清理当前环境全部缓存(6.x标准语法)
pio run -t clean -e esp32cam_s3_wroom_n16r8
# 完整编译
pio run -e esp32cam_s3_wroom_n16r8
# 烧录固件
pio run -t upload -e esp32cam_s3_wroom_n16r8
# 重新打开串口监控查看RTSP启动日志
pio device monitor -e esp32cam_s3_wroom_n16r8
5、调试日志分析
RTSP 服务成功启动(核心正常信息)
[ 8001][I][main.cpp:447] loop(): Delay start RTSP after AP init complete
[ 8007][V][main.cpp:305] start_rtsp_server(): start_rtsp_server
[ 8013][I][main.cpp:306] start_rtsp_server(): start_rtsp_server-----------tony
[ 8028][I][rtsp_server.cpp:9] rtsp_server(): Starting RTSP server
[ r::WiFiServer(port=554, ...)
说明:
- 延时方案生效,等待 8 秒后正常执行
start_rtsp_server(); - RTSP 服务实例创建成功,554 端口
WiFiServer正常开启; - 网页后台
RTSP sessions不再显示RTSP server disabled,会显示数字0; - 现在 Windows 连接热点后,VLC 可正常拉流
rtsp://192.168.4.1:554/mjpeg/1。
mDNS 注册失败(不影响 RTSP 核心功能)
[ 8034][E][ESPmDNS.cpp:148] addService(): Failed adding service
设备启动时 mDNS 服务初始化晚于 RTSP 注册调用,注册 rtsp 服务超时失败;
不影响 554 端口 RTSP 拉流,只是无法通过域名 esp32cam.local 访问;
纯 IP 访问完全不受干扰,可忽略该报错。
三、运行测试
1、连接热点
你的 ESP32-S3 当前是AP 热点模式 ,IP 为192.168.4.1,Windows11 电脑必须:
-
无线连接 ESP32-CAM 发射的 WiFi 热点(名称 ESP32-CAM-xxxx);
-
不要连家用路由器 WiFi,否则网段不通(家用路由一般是 192.168.1.x,和 192.168.4.x 隔离);
-
先测试网络连通:按下
Win+R输入cmd,执行 cmdping 192.168.4.1
能收到回复代表网络正常;请求超时 = WiFi 连错。

2、RTSP 使用
VLC 媒体播放器(最推荐,免费开源,完美兼容 MJPEG-RTSP)
-
官网下载安装 VLC Media Player(Windows/Linux)
-
打开 VLC,顶部菜单:媒体 → 打开网络串流 (快捷键
Ctrl+N) -
在「请输入网络 URL」粘贴完整地址: plaintext
rtsp://192.168.4.1:554/mjpeg/1
-
优化低延迟(解决卡顿 / 黑屏): 点击「显示更多选项」,将缓存 改为
100(单位 ms); 编辑选项里添加传输参数:rtsp_transport=tcp -
点击「播放」即可实时显示画面。


VLC打开网络串流
填入RTSP地