如何将浏览器端WebSocket实时视频流转换为后端RTSP流
实现方案
前置校验
首先确认你前端采集输出的视频编码格式,优先在前端采集阶段就指定H.264+AAC编码,避免后端转码消耗额外算力,前端MediaRecorder配置示例:
const mediaRecorder = new MediaRecorder(mediaStream, { mimeType: 'video/webm;codecs=h264,aac', videoBitsPerSecond: 2000000 }) // 分片时长控制在100-500ms,降低端到端延迟 mediaRecorder.start(300)
Node端核心处理逻辑
你已经完成了WebSocket接收分片的逻辑,接下来只需要通过FFmpeg处理流并推送到RTSP服务器即可,步骤如下:
- 环境准备:
- 服务器安装完整FFmpeg(需支持H.264编码、RTSP推流,Windows/macOS/Linux都可以从官网下载对应版本,确保
ffmpeg命令可以全局调用) - Node项目安装
fluent-ffmpeg依赖:npm install fluent-ffmpeg
- 服务器安装完整FFmpeg(需支持H.264编码、RTSP推流,Windows/macOS/Linux都可以从官网下载对应版本,确保
- 初始化FFmpeg进程
每个用户的流对应一个独立的FFmpeg进程,输入设置为标准输入,直接接收你收到的视频分片,输出直接推送到RTSP服务器,示例代码:const ffmpeg = require('fluent-ffmpeg') // WebSocket连接建立时初始化FFmpeg进程 wss.on('connection', (ws) => { // 给当前用户生成唯一流地址,这里示例用固定地址,生产环境可替换为用户ID const rtspPushUrl = 'rtsp://你的RTSP服务器地址:8554/live/user_stream_001' const ffmpegProcess = ffmpeg() .input('pipe:0') // 从标准输入读流 .inputOptions('-f webm') // 匹配前端输出的容器格式 // 如果前端已经输出H264+AAC,直接复制编码,不需要转码,性能最优 .outputOptions('-c:v copy') .outputOptions('-c:a copy') // RTSP推流配置 .outputOptions('-f rtsp') .outputOptions('-rtsp_transport tcp') .outputOptions('-tune zerolatency') // 降低推流延迟 .output(rtspPushUrl) .on('error', (err) => { console.log('FFmpeg错误:', err) ffmpegProcess.kill() }) .on('end', () => { console.log('FFmpeg进程结束') }) // 启动进程 ffmpegProcess.run() // WebSocket收到分片直接写入FFmpeg标准输入 ws.on('message', (chunk) => { if (ffmpegProcess.stdin.writable) { ffmpegProcess.stdin.write(chunk) } }) // 连接断开时销毁FFmpeg进程 ws.on('close', () => { if (ffmpegProcess) { ffmpegProcess.stdin.end() ffmpegProcess.kill() } }) }) - RTSP服务器部署:你需要提前部署一个RTSP服务器接收推流,可选Mediamtx、EasyDarwin、SRS等,部署完成后把上面的
rtspPushUrl替换为你自己的服务器推流地址即可,VLC直接输入该地址就能拉流观看。
常见问题处理
- 如果前端无法输出H264编码,需要在后端转码,把上面的输出编码参数替换为转码配置即可:
.outputOptions('-c:v libx264') .outputOptions('-preset fast') .outputOptions('-crf 28') .outputOptions('-c:a aac') .outputOptions('-ar 44100') .outputOptions('-ac 2') - 出现花屏、断流问题时,先检查前端分片是否按顺序发送,FFmpeg的输入容器格式是否和前端输出匹配,如果是webm分片就加
-f webm输入参数,如果是mp4分片就改成-f mp4。
内容的提问来源于stack exchange,提问作者Mrax
相关产品推荐
相关产品推荐

