如何将IP摄像头的RTSP视频流转到HTML Video元素?
问题解答
一、基于现有FastAPI服务器改为HTML Video元素推流
当前你的实现是通过multipart/x-mixed-replace协议推送JPEG图片序列,依赖<img>标签刷新。要改用HTML <video>元素,需要输出浏览器原生支持的流媒体格式(如WebM、HLS、MP4),推荐两种方案:
方案1:推WebM流(低延迟,适合实时场景)
通过FFmpeg将RTSP流转码为WebM格式,直接通过FastAPI返回字节流,修改代码如下:
import subprocess from fastapi import StreamingResponse, Query, Depends from urllib.parse import unquote class VideoStreamService: def get_video_stream(self, connection_string: str): # FFmpeg命令:将RTSP流转码为低延迟WebM格式 cmd = [ "ffmpeg", "-i", connection_string, "-c:v", "libvpx-vp9", "-crf", "30", "-b:v", "1M", "-f", "webm", "-preset", "ultrafast", "-tune", "zerolatency", "-" ] process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) try: while True: chunk = process.stdout.read(1024*1024) if not chunk: break yield chunk finally: process.kill() def get_video_stream( connection_string: str = Query(..., alias="connection_string"), video_stream_service: VideoStreamService = Depends() ) -> StreamingResponse: try: stream = video_stream_service.get_video_stream(unquote(connection_string)) return StreamingResponse(stream, media_type="video/webm") except ValueError as error: # 自定义错误处理逻辑 ...
前端使用<video>标签直接播放:
<video src="/get_video_stream?connection_string=rtsp://你的摄像头地址" autoplay muted playsinline></video>
方案2:推HLS流(高兼容性,适合多设备场景)
如果需要兼容Safari等浏览器,可生成HLS切片。需新增两个接口:一个返回M3U8索引文件,另一个返回TS切片文件(需临时存储切片文件,适合非极端低延迟场景)。
二、现成服务器推荐
- Nginx + RTMP模块:轻量高性能,可直接将RTSP流转推为HLS/RTMP/WebM,配置简单,适合生产环境。
- Frigate:专为IP摄像头设计的流媒体服务器,支持RTSP输入、WebUI查看、AI检测,自带浏览器兼容的流输出。
- EasyNVR:国内开源流媒体服务器,支持RTSP转HTTP-FLV、HLS,提供现成Web播放页面,部署便捷。
- Zoneminder:开源视频监控平台,支持RTSP摄像头接入,集成流媒体转码与Web管理界面。
三、JPEG格式推流的效率分析
JPEG推流的优点是延迟极低(每帧独立无缓存)、实现简单;但效率较低:
- 带宽占用高:JPEG是帧内压缩,每帧需传输完整图像数据,相同画质下带宽占用是H.264/H.265的2-5倍。
- CPU开销大:OpenCV每帧编码JPEG会消耗较多计算资源,高分辨率、高帧率场景下易出现性能瓶颈。
仅适合低延迟、小带宽需求的场景,若追求高效传输,建议改用H.264/H.265编码的流媒体格式。
内容的提问来源于stack exchange,提问作者Oded
相关产品推荐
相关产品推荐

