当前位置: 首页 > news >正文

(十)在50块钱的芯片上做视频推流:H.264硬件编码+RTSP实战

在50块钱的芯片上做视频推流:H.264硬件编码+RTSP实战

文章目录

  • 在50块钱的芯片上做视频推流:H.264硬件编码+RTSP实战
    • 一、ESP32-P4凭什么值那多出来的几十块?
    • 二、ESP-VISION的输出方式全景
    • 三、静态图像编码:JPEG vs PNG
      • 3.1 JPEG编码
      • 3.2 PNG编码
      • 3.3 编码器对比
    • 四、ImageIO:帧序列录制
    • 五、H.264硬件编码:视频压缩的核心
      • 5.1 为什么不用逐帧JPEG?
      • 5.2 H.264编码器配置
      • 5.3 关键参数详解
    • 六、RTSP推流:让VLC看到你的摄像头
      • 6.1 完整RTSP推流示例
      • 6.2 客户端播放
      • 6.3 RTSP服务器的队列机制
    • 七、USB CDC预览:开发调试最快的方式
    • 八、一个完整的监控摄像头方案
    • 参考链接
    • 总结与下篇预告

一、ESP32-P4凭什么值那多出来的几十块?

如果你看了本系列第二篇的芯片对比,你一定记得:H.264硬件编码和RTSP推流是ESP32-P4的独占功能

但这到底意味着什么?简单说——你可以在ESP32-P4X-EYE(不到200元)上实现一个完整的网络摄像头,VLC播放器直接打开rtsp://192.168.1.100:8554/就能看到实时画面。

今天这篇文章,我把编解码和推流的完整链路讲清楚。

二、ESP-VISION的输出方式全景

开发调试

静态图像

静态图像

帧序列

实时视频

LCD显示

📷 sensor.snapshot()

输出方式

USB CDC预览
img.flush()

JPEG编码
img.to_jpeg()

PNG编码
img.to_png()

ImageIO录制
imageio.ImageIO

H.264编码
h264.H264Encoder

display.write()

RTSP推流
rtsp.RTSPServer

保存到SD卡
.h264文件

三、静态图像编码:JPEG vs PNG

3.1 JPEG编码

importsensor,image sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.VGA)sensor.skip_frames(time=2000)img=sensor.snapshot()# 编码为JPEGjpeg_data=img.to_jpeg(quality=85)# quality: 1-100# 或者用别名jpeg_data=img.compress(quality=85)# 保存到SD卡withopen("/sdcard/capture.jpg","wb")asf:f.write(jpeg_data)# 调整质量与大小small_jpeg=img.to_jpeg(quality=50)# 更小,画质更低hq_jpeg=img.to_jpeg(quality=95)# 更大,画质更高# 色度子采样控制img.to_jpeg(quality=85,subsampling=image.JPEG_SUBSAMPLING_420)# 最小文件img.to_jpeg(quality=85,subsampling=image.JPEG_SUBSAMPLING_444)# 最佳画质

3.2 PNG编码

# 无损PNG,适合保存参考帧png_data=img.to_png()withopen("/sdcard/reference.png","wb")asf:f.write(png_data)

3.3 编码器对比

编码方式文件大小(VGA)画质编码速度硬件加速
JPEG(quality=85)~30KB优秀✅ P4硬件
JPEG(quality=50)~10KB一般✅ P4硬件
PNG~200KB无损❌ 纯软件

四、ImageIO:帧序列录制

不止能拍单张,还能录制帧序列:

importsensor,image,imageio,time sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.QVGA)sensor.skip_frames(time=2000)# 录制5秒recorder=imageio.ImageIO("/sdcard/sequence.imgio","w")start=time.ticks_ms()whiletime.ticks_diff(time.ticks_ms(),start)<5000:img=sensor.snapshot()recorder.write(img)# 保留帧间时间戳recorder.close()# 回放player=imageio.ImageIO("/sdcard/sequence.imgio","r")whileTrue:img=player.read()ifimgisNone:break# 处理/显示帧player.close()

五、H.264硬件编码:视频压缩的核心

5.1 为什么不用逐帧JPEG?

逐帧JPEG做视频的问题:每帧都是独立压缩的,无法利用帧间相似性

一帧VGA JPEG约30KB,30fps就是900KB/s。而H.264利用帧间预测,同样的画质可能只需要200KB/s——压缩率提升4倍以上

5.2 H.264编码器配置

importsensor,h264 sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.VGA)sensor.skip_frames(time=2000)# 创建编码器encoder=h264.H264Encoder(gop=30,# 关键帧间隔(每30帧一个I帧)bitrate=2000000,# 目标码率 2Mbpsqp_min=10,# 最小量化参数(画质上限)qp_max=40,# 最大量化参数(画质下限))# 编码一帧img=sensor.snapshot()nal_units=encoder.encode(img)# 返回NAL单元

5.3 关键参数详解

参数含义低延迟高质量低带宽
gop关键帧间隔1560120
bitrate目标码率4Mbps8Mbps1Mbps
qp_min画质上限15520
qp_max画质下限352545

⚠️注意:丢失一个P帧会导致画面损坏,直到下一个I帧(关键帧)为止。gop越小,恢复越快,但文件越大。

六、RTSP推流:让VLC看到你的摄像头

6.1 完整RTSP推流示例

importsensor,h264,rtsp,network,time# 1. 连接WiFiwlan=network.WLAN(network.STA_IF)wlan.active(True)wlan.connect("YOUR_SSID","YOUR_PASSWORD")whilenotwlan.isconnected():time.sleep_ms(100)print(f"IP:{wlan.ifconfig()[0]}")# 2. 初始化摄像头sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.VGA)sensor.skip_frames(time=2000)# 3. 创建H.264编码器encoder=h264.H264Encoder(gop=30,bitrate=2000000)# 4. 创建RTSP服务器server=rtsp.RTSPServer(port=8554)print(f"RTSP: rtsp://{wlan.ifconfig()[0]}:8554/")# 5. 采集-编码-推流循环clock=time.clock()whileTrue:clock.tick()img=sensor.snapshot()nal_units=encoder.encode(img)server.send(nal_units)# 发送编码后的数据print(f"FPS:{clock.fps():.1f}")

6.2 客户端播放

# VLCvlc rtsp://192.168.1.100:8554/# ffplayffplay rtsp://192.168.1.100:8554/# OpenCVimportcv2 cap=cv2.VideoCapture("rtsp://192.168.1.100:8554/")whileTrue: ret, frame=cap.read()cv2.imshow("ESP32", frame)

6.3 RTSP服务器的队列机制

RTSP服务器维护一个短小且有序的帧队列。如果客户端缓慢或缺席:

  • 服务器会整帧丢弃,而不是阻塞采集循环
  • 不会发送会破坏码流的半帧
  • 采集循环不受影响,保持稳定帧率

七、USB CDC预览:开发调试最快的方式

开发期间,最快看到摄像头画面的方式不是RTSP,而是USB CDC:

importsensor,image,time sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.QVGA)sensor.skip_frames(time=2000)whileTrue:img=sensor.snapshot()img.flush()# 通过USB CDC发送JPEG预览到主机time.sleep_ms(50)

不需要WiFi、不需要SD卡、不需要网络配置。USB线插上就能看,VSCode扩展和Web IDE都能直接显示。

八、一个完整的监控摄像头方案

""" ESP32-P4 网络监控摄像头 功能:H.264编码 + RTSP推流 + 定时截图保存 """importsensor,h264,rtsp,network,time,os# === WiFi连接 ===wlan=network.WLAN(network.STA_IF)wlan.active(True)wlan.connect("MyWiFi","password")whilenotwlan.isconnected():time.sleep_ms(100)# === 摄像头初始化 ===sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.VGA)sensor.skip_frames(time=2000)# === 编码器与推流 ===encoder=h264.H264Encoder(gop=30,bitrate=2000000)server=rtsp.RTSPServer(port=8554)print(f"📡 RTSP: rtsp://{wlan.ifconfig()[0]}:8554/")# === 主循环 ===clock=time.clock()last_snapshot=0snapshot_interval=60# 每60秒截图一次whileTrue:clock.tick()img=sensor.snapshot()# H.264编码 + RTSP推流nal_units=encoder.encode(img)server.send(nal_units)# 定时保存截图now=time.time()ifnow-last_snapshot>snapshot_interval:withopen(f"/sdcard/snapshot_{int(now)}.jpg","wb")asf:f.write(img.to_jpeg(quality=85))last_snapshot=nowprint(f"FPS:{clock.fps():.1f}")

参考链接

  • ESP-VISION 编解码与推流
  • ESP-VISION API - h264
  • ESP-VISION API - rtsp

总结与下篇预告

ESP32-P4的H.264硬件编码和RTSP推流,让200块的开发板具备了完整的网络摄像头能力。核心参数调优记住三个:gop控制恢复速度,bitrate控制码率,qp控制画质。开发调试用USB CDC预览(最快),产品部署走RTSP推流。

下篇我们聊聊软件包管理和部署——你的Python代码怎么组织、怎么分发、怎么更新。


作者:码农阿虎

关键词:H.264、RTSP、视频推流、硬件编码、ESP32-P4、网络摄像头


http://www.jsqmd.com/news/1219545/

相关文章:

  • 分立器件搭建三相电机驱动电路:从原理到实践完整指南
  • 如何快速安装REPENTOGON:面向新手的《以撒的结合》脚本扩展器终极配置指南
  • 湖北正规医护中专推荐:武汉助产学校 2026 更新招生电话,护理助产专业实力过硬 - Luckyone王
  • 可灵AI互动投票系统:实时剧情分支生成与观众决策技术解析
  • ARM实验箱捕鱼游戏开发全流程解析
  • 首批入板!探码科技入选四川省专精特新专板规范层企业
  • Axure RP中文界面终极指南:快速免费汉化完整攻略
  • 嵌入式自学指南:从基础到实战的系统学习路径与避坑技巧
  • 安卓高性能编程实战:优化工具与关键策略
  • ComfyUI破限版全解析:中文界面优化与显卡适配实战指南
  • 惠州市龙门县黄金回收白银回收铂金回收彩金回收门店优选+联系方式推荐_转自TXT - 余情未了888
  • 2026年7月最新沈阳劳力士官方售后热线及客户服务网点地址 - 劳力士官方服务中心
  • Stream Deck与Codex结合:自然语言驱动的开发自动化实践
  • 乐山市井研县黄金回收白银回收铂金回收彩金回收门店优选+联系方式推荐_转自TXT - 余情未了888
  • OpenMemories-Tweak深度解析:全面掌握索尼相机隐藏功能解锁实战指南
  • 终极隐私保护指南:如何用开源键盘OpenBoard彻底告别数据泄露风险
  • APICloud应用上架App Store全流程指南
  • 沧州防水修缮优选|筑宅安99.5高分五星品牌,专治雨季、汛期各类漏水难题 - 筑宅安
  • 终极指南:3分钟免费实现Axure RP界面全面中文化
  • 深入解析TI C2000 DCSM_Z2_REGS:嵌入式安全硬件配置与工程实践
  • Windows 11系统优化揭秘:用Win11Debloat打造纯净高效的操作系统
  • 深入解析C2000 CLB输出选择与Tile架构:从原理到电机控制实战
  • 如何在Mac上使用CXPatcher:3个简单步骤提升CrossOver游戏性能40%
  • 鸡西市黄金回收白银回收铂金回收彩金回收门店优选+联系方式推荐_转自TXT - 余情未了888
  • 宝玑中国官方售后服务中心|官方地址及售后热线权威信息通知(2026年7月更新) - 亨得利官方服务中心
  • 乐山市沐川县黄金回收白银回收铂金回收彩金回收门店优选+联系方式推荐_转自TXT - 余情未了888
  • WA2417 LLC开关电源设计实战:从原理到调试完整指南
  • 武汉初中毕业生读护理去哪?武汉助产学校 2026 官方招生电话更新,资质齐全老牌卫校 - Luckyone王
  • Texify数学公式OCR:从图片到LaTeX的终极转换指南
  • 高效处理Android OTA的payload-dumper-go解决方案