在Web开发中,使用HTML5播放RTSP流媒体时,经常会遇到跨域访问被浏览器拦截的问题,同时HTML5本身并不原生支持RTSP协议,因此需要通过额外的配置和处理来实现播放需求。下面介绍几种常用的解决方案。

方案一:使用nginx+ffmpeg实现RTSP转HTTP-FLV并解决跨域
这种方案的核心思路是将RTSP流通过ffmpeg转码为HTTP-FLV格式,再通过nginx提供访问服务,同时配置nginx的跨域响应头解决跨域问题。
1. 安装ffmpeg和nginx
首先确保服务器上已经安装了ffmpeg和nginx,以Ubuntu系统为例,安装命令如下:
# 安装ffmpeg sudo apt update sudo apt install ffmpeg -y # 安装nginx sudo apt install nginx -y
2. 配置ffmpeg转码RTSP流
使用ffmpeg将RTSP流转换为FLV格式并通过HTTP方式输出,命令示例如下:
ffmpeg -i rtsp://192.168.0.1:554/stream1 -c:v libx264 -c:a aac -f flv http://127.0.0.1:8080/live/stream1
上述命令中,rtsp://192.168.0.1:554/stream1是原始的RTSP流地址,http://127.0.0.1:8080/live/stream1是转码后的HTTP-FLV输出地址。
3. 配置nginx解决跨域并转发流
修改nginx的配置文件,添加跨域响应头和流转发规则,配置示例如下:
http {
server {
listen 80;
server_name localhost;
# 跨域配置
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
# 转发FLV流
location /live/ {
proxy_pass http://127.0.0.1:8080/live/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
4. HTML5页面播放配置
前端使用支持FLV格式的播放器,比如flv.js来播放转码后的流,示例代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>RTSP跨域播放示例</title>
<script src="https://cdn.jsdelivr.net/npm/flv.js@1.6.2/dist/flv.min.js"></script>
</head>
<body>
<video id="videoElement" controls width="800" height="400"></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://localhost/live/stream1'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
</body>
</html>
方案二:使用nginx-rtmp-module搭建流媒体服务器
nginx-rtmp-module是nginx的一个扩展模块,支持RTMP协议,也可以实现RTSP流的接入和转发,同时可以配置跨域。
1. 安装带nginx-rtmp-module的nginx
需要编译安装nginx并添加该模块,步骤如下:
# 下载nginx和模块源码 wget http://nginx.org/download/nginx-1.24.0.tar.gz tar -zxvf nginx-1.24.0.tar.gz git clone https://github.com/arut/nginx-rtmp-module.git # 编译安装 cd nginx-1.24.0 ./configure --add-module=../nginx-rtmp-module make sudo make install
2. 配置nginx-rtmp-module
修改nginx配置文件,添加RTMP服务和HTTP跨域配置:
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
# 接收RTSP流并转推为RTMP
pull rtsp://192.168.0.1:554/stream1 name=stream1;
}
}
}
http {
server {
listen 80;
server_name localhost;
# 跨域配置
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
location / {
root html;
index index.html index.htm;
}
# 统计页面可选
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root html;
}
}
}
3. 前端播放RTMP流
HTML5原生不支持RTMP,需要使用支持RTMP的播放器,比如video.js配合相关插件,示例配置如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>RTMP播放示例</title>
<link href="https://vjs.zencdn.net/7.20.3/video-js.css" rel="stylesheet" />
</head>
<body>
<video id="my-video" class="video-js" controls preload="auto" width="800" height="400">
<source src="rtmp://localhost/live/stream1" type="rtmp/flv">
</video>
<script src="https://vjs.zencdn.net/7.20.3/video.min.js"></script>
<script>
var player = videojs('my-video');
player.play();
</script>
</body>
</html>
常见问题排查
- 如果转码后无法播放,检查ffmpeg命令是否正确,RTSP地址是否可访问。
- 跨域问题未解决时,检查nginx的跨域响应头是否正确添加,可通过浏览器开发者工具的Network面板查看响应头。
- 播放卡顿可以调整ffmpeg的转码参数,降低码率或者分辨率。
| 方案 | 优点 | 缺点 |
|---|---|---|
| nginx+ffmpeg转HTTP-FLV | 兼容性好,支持HTML5原生播放,延迟较低 | 需要额外运行ffmpeg进程,资源占用稍高 |
| nginx-rtmp-module | 支持RTMP协议,适合低延迟直播场景 | 需要前端额外支持RTMP播放插件,配置相对复杂 |