如何在Nest.js后端获取本地RTSP流并转发至React前端
Nest.js后端转发RTSP流至React前端方案
问题
本地网络中由USB摄像头推送的RTSP流(rtsp://192.168.1.238:8554/mystream)可通过VLC正常播放,需通过Nest.js后端获取该流并转发至React前端(必须走后端,流还要供给其他服务使用)。
以下是我尝试的代码:
服务端代码(基于node-media-server)
const NodeMediaServer = require('node-media-server'); const config = { rtmp: { port: 1488, chunk_size: 60000, gop_cache: false, ping: 60, ping_timeout: 30, }, http: { port: 6666, allow_origin: '*', }, relay: { ffmpeg: './ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe', tasks: [ { app: 'live', mode: 'static', edge: `rtsp://192.168.1.238:8554/mystream`, }, ], }, }; const nms = new NodeMediaServer(config); nms.run(); nms.on('prePublish', (id, streamPath, args) => { if (streamPath.indexOf('mystream') === -1) { nms.getSession(id).reject(); } }); console.log('Node Media Server is running');
React前端代码
import { Player, ControlBar } from 'video-react'; function App() { return ( <div> <Player playsInline autoPlay src="http://localhost:8001/live/mystream.m3u8" > <ControlBar autoHide={false}/> </Player> </div> ) } export default App;
解决方案
1. 修复端口不匹配问题
服务端配置的HTTP端口为6666,但前端请求的是8001,直接修改前端流地址:
src="http://localhost:6666/live/mystream.m3u8"
2. 集成node-media-server到Nest.js
当前代码是独立运行的node-media-server,需将其封装为Nest.js服务,确保与Nest.js应用生命周期同步:
创建媒体流服务
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'; const NodeMediaServer = require('node-media-server'); @Injectable() export class MediaStreamService implements OnModuleInit, OnModuleDestroy { private nmsInstance: any; onModuleInit() { const config = { rtmp: { port: 1488, chunk_size: 60000, gop_cache: false, ping: 60, ping_timeout: 30, }, http: { port: 6666, allow_origin: '*', }, relay: { ffmpeg: './ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe', tasks: [ { app: 'live', mode: 'static', edge: 'rtsp://192.168.1.238:8554/mystream', }, ], }, }; this.nmsInstance = new NodeMediaServer(config); this.nmsInstance.run(); this.nmsInstance.on('prePublish', (id: string, streamPath: string) => { if (!streamPath.includes('mystream')) { this.nmsInstance.getSession(id).reject(); } }); console.log('Media stream server started with Nest.js'); } onModuleDestroy() { this.nmsInstance?.stop(); console.log('Media stream server stopped'); } }
注册到Nest.js模块
import { Module } from '@nestjs/common'; import { MediaStreamService } from './media-stream.service'; @Module({ providers: [MediaStreamService], exports: [MediaStreamService], }) export class MediaStreamModule {}
3. 前端播放兼容性调整
浏览器通常限制自动播放,需添加用户交互触发播放,同时引入video-react样式:
import { Player, ControlBar } from 'video-react'; import 'video-react/dist/video-react.css'; import { useRef } from 'react'; function App() { const playerRef = useRef(null); const triggerPlay = () => { playerRef.current?.play(); }; return ( <div onClick={triggerPlay} style={{ cursor: 'pointer' }}> <Player ref={playerRef} playsInline src="http://localhost:6666/live/mystream.m3u8" > <ControlBar autoHide={false} /> </Player> </div> ); } export default App;
4. 验证FFmpeg可用性
确保配置的FFmpeg路径正确,在终端执行:
./ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe -version
若无法执行,需修正FFmpeg路径或重新下载适配系统的版本。
内容的提问来源于stack exchange,提问作者Daskis
相关产品推荐
相关产品推荐

