# RTSPToWeb **Repository Path**: tziye/RTSPToWeb ## Basic Information - **Project Name**: RTSPToWeb - **Description**: 三种在Web端播放RTSP监控流的方案,亲测有效! - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 26 - **Forks**: 0 - **Created**: 2020-12-18 - **Last Updated**: 2026-01-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README RTSP是海康等视频监控厂家提供的监控流格式,但在Web端缺少简单实用的方式进行实时播放。目前比较普遍的是通过FFmpeg对RTSP流进行转码,然后在Web端通过插件或原生方式进行播放。 由于之前接触过相关工作内容,前前后后折腾了三个方案,一度怀疑码生,特此将之前实现过的方案进行整理,希望能给有需要的码农朋友提供帮助。特此说明,这些方案都是从网上搜集来的,但都经过二次开发,如有雷同,纯(ju)属(jue)巧(wei)合(nan)。 项目依赖包括: - Docker - JDK 8+ - Maven # 基础镜像构建 三个方案都需要通过FFmpeg转码,在base目录下提供了FFmpeg及相关依赖的统一镜像构建,可以一次构建,到处使用。 进入base目录,如果是Windows系统,需要将以下文件换行符改为LF: x264/configure、x264/config.guess、x264/config.sub、x264/tools/cltostr.sh、x264/version.sh 然后执行: ``` docker build -t tziye/nginx-ffmpeg:v1.0 . ``` 由于依赖很多,构建过程相对缓慢,等待构建完成后,就可以部署具体方案了。 (以下可跳过) 如果要测试基础镜像是否构建成功,可以运行: ``` docker run -p 8888:8888 -p 1935:1935 -d tziye/nginx-ffmpeg:v1.0 ``` 进入容器后执行: ``` ffmpeg -rtsp_transport tcp -i rtsp_ip -f flv -r 15 -b:v 1000k -an rtmp://localhost:1935/live/test ``` 在VLC视频播放客户端中,打开网络串流:rtmp://127.0.0.1:1935/live/test,播放成功说明正常。 再测试转HLS: ``` ffmpeg -f rtsp -rtsp_transport tcp -i rtsp_ip -strict -2 -c:v libx264 -vsync 2 -c:a aac -f hls -hls_time 2 -hls_list_size 5 -hls_wrap 10 /tmp/hls/test.m3u8 ``` 在VLC中打开网络串流:http://127.0.0.1:8888/hls/test.m3u8,播放成功说明正常。 # 方案一:WebSocket WebSocket是经过几次实践之后最终使用的方案,特点是Web原生支持,打开快,最为推荐。以下是这一方案的交互图: ![](./graph/websocket.png) 部署方式如下: 进入websocket目录,执行: ``` mvn install ``` 打好包后就可以构建镜像了: ``` docker build -t tziye/rtsptoweb-websocket:v1.0 . ``` 然后运行容器: ``` docker run -p 7777:7777 -d tziye/rtsptoweb-websocket:v1.0 ``` 浏览器访问:http://localhost:7777/,可以看到以下页面: ![websocket_index](./graph/websocket_index.png) 输入要查看监控的RTSP地址就可以观看了。注意,切换监控时需刷新页面,将前一个连接断开,否则会不断在多个监控间切换。 # 方案二:RTMP RTMP在Web播放需要Flash插件的支持,随着各大浏览器禁用Flash插件,这一方案无法在新版浏览器上使用。但如果是GUI或App,应该还可以使用。RTMP打开快,稳定,如果不是Flash插件禁用问题,是最好的一种方案。以下是这一方案的交互图: ![rtmp](./graph/rtmp.png) 部署方式如下: 进入rtmp_hls目录,Windows系统需先将run.sh换行符改为LF,然后执行: ``` docker build -t tziye/rtsptoweb-rtmp-hls:v1.0 . ``` 镜像构建好后,运行: ``` docker run -p 5555:15555 -p 1935:1935 -d --env SERVER_IP=127.0.0.1 --env SERVER_PORT=5555 tziye/rtsptoweb-rtmp-hls:v1.0 ``` 其中,SERVER_IP和SERVER_PORT是容器运行的宿主机的IP以及暴露的端口。 最后需要进入容器执行: ``` ./run.sh ``` 这一方案给前端提供了三个接口用于控制转码: - /rtspToRtmpOn:开启转码 - /rtspToRtmpOff:关闭转码 - /rtspToRtmpContinue:转码续时,如果超过5分钟没有调用此接口,转码自动关闭,防止资源泄露 # 方案三:HLS HLS方案是在Flash要被禁用时采用的一种方案,但由于延迟太过明显,最终被WebSocket方案替代。HLS方案需要FFmpeg将RTSP流转为一系列切片文件,存放到磁盘,然后由浏览器读取。这一方案打开的时候会有十几秒的延迟,非常不推荐使用。交互图如下: ![hls](./graph/hls.png) 这一方案部署同RTMP方案,但提供的接口不同: - /rtspToHlsOn:开启转码 - /rtspToHlsOff:关闭转码 - /rtspToHlsContinue:转码续时 这一方案的转码命令中有以下三个专有参数进行调整: * -hls_time n:设置每片的长度,默认为2秒。 * -hls_list_size n:设置播放列表保存的最多条目,设置为0会保存所有片信息,默认为5。 * -hls_wrap n:设置多少片之后序号开始覆盖,如果设置为0则不会覆盖,默认为0。 # 其他方案 目前为止已知的最好方案是WebRTC方案,阿里云提供的相关服务就是采用了这一方案。这一方案的难度也是最高的,有兴趣的可以尝试下!