如何将RTMP直播视频流拉取到React搭建的浏览器页面中播放
解决方案
问题根本原因
原生浏览器已全面停止支持Flash插件,而RTMP协议本身没有被浏览器原生解码支持,直接将RTMP地址传入前端播放器会无法解析流数据,就是你遇到的报错和无缓冲问题的直接诱因。
推荐方案:服务端转协议中转(兼容性最好、性能最优)
这个方案是目前生产环境最通用的做法,将RTMP流转为浏览器可原生支持的HLS、HTTP-FLV或WebRTC协议后再给前端播放。
实现步骤
- 第一步:部署流媒体中转服务
可选SRS、Nginx+nginx-rtmp-module、FFmpeg作为中转服务,示例用Nginx配置片段:
配置完成后,原始RTMP流推送到中转服务后,会生成对应HLS流地址,格式为rtmp { server { listen 1935; application live { live on; hls on; hls_path /usr/local/nginx/html/hls; hls_fragment 1s; # 调整切片大小控制延迟 hls_type live; } } } http { server { listen 80; location /hls { add_header Access-Control-Allow-Origin *; types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } root html; } } }http://你的服务地址/hls/流名.m3u8 - 第二步:React前端播放转码后的HLS流
安装依赖:npm install hls.js
示例组件代码:import { useRef, useEffect } from 'react'; import Hls from 'hls.js'; const LivePlayer = () => { const videoRef = useRef(null); const hlsUrl = 'http://你的中转服务地址/hls/你的流名.m3u8'; useEffect(() => { const video = videoRef.current; if (!video) return; if (Hls.isSupported()) { const hls = new Hls(); hls.loadSource(hlsUrl); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, () => { video.play().catch(err => console.log('播放需用户交互触发:', err)); }); return () => hls.destroy(); } else if (video.canPlayType('application/vnd.apple.mpegurl')) { // Safari原生支持HLS video.src = hlsUrl; video.addEventListener('loadedmetadata', () => { video.play().catch(err => console.log('播放需用户交互触发:', err)); }); } }, []); return <video ref={videoRef} controls style={{ width: '100%' }} />; }; export default LivePlayer;
备选方案:纯前端Wasm解析(无需中转服务)
如果无法部署中转服务,可以选择Wasm编译的RTMP客户端方案,有两个前置要求:
- 你的RTMP流支持RTMP over WebSocket封装
- 流服务端配置了WebSocket跨域
实现逻辑是通过Wasm客户端拉取WebSocket封装的RTMP流,解析后喂给浏览器MediaSource Extensions接口播放,可使用对应功能的npm包实现,该方案延迟相对较高,性能弱于中转方案。
内容的提问来源于stack exchange,提问作者Roshan Daniel
相关产品推荐
相关产品推荐

