基于 node-rtsp-stream 的 Web 直播方案详解

node-rtsp-stream 是一个经典的 Node.js 库,用于将 RTSP 流(如 IP 摄像头)通过 FFmpeg 转码为 MPEG1 格式,并经 WebSocket 推送给浏览器,使用 jsmpeg 客户端解码播放,实现低延迟的网页直播。适合监控、实时视频等场景。

注意:该库最后更新于 6 年前(npm 版本 0.0.9),但核心功能仍可用(依赖 FFmpeg 和 WebSocket)。如果遇到兼容问题,可考虑 fork 版本如 node-rtsp-stream-es6 或更现代的替代(如 rtsp-relay + WebRTC)。

1. 环境准备

  • 安装 Node.js(推荐 v18+)

  • 安装 FFmpeg(必须,确保系统 PATH 中可访问 ffmpeg 命令)

    • Windows:从官网下载并添加 PATH
    • Linux:sudo apt install ffmpeg
    • macOS:brew install ffmpeg
  • 创建项目文件夹:

    bash 复制代码
    mkdir rtsp-web-live
    cd rtsp-web-live
    npm init -y
    npm install node-rtsp-stream

2. 服务器端代码(server.js)

创建一个 Node.js 服务器,启动 RTSP 转 WebSocket 流。

javascript 复制代码
const Stream = require('node-rtsp-stream');

const stream = new Stream({
  name: 'camera-live',                          // 流名称(可选)
  streamUrl: 'rtsp://your-rtsp-url',            // 替换为你的 RTSP 地址,例如:
                                                // rtsp://admin:12345@192.168.1.100:554/Streaming/Channels/101
                                                // 测试用公开流:rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov
  wsPort: 9999,                                 // WebSocket 监听端口
  ffmpegOptions: {                              // FFmpeg 参数(可选优化)
    '-stats': '',                               // 显示统计
    '-r': 30,                                   // 输出帧率(建议与源匹配)
    '-b:v': '1M',                               // 视频比特率(控制画质/流量)
    '-bf': 0,                                   // 禁用 B 帧(降低延迟)
    '-rtsp_transport': 'tcp'                    // 使用 TCP 传输(更稳定,UDP 可能丢包)
  }
});

console.log('RTSP 流已启动,WebSocket 监听在 ws://你的服务器IP:9999');

运行服务器:

vbscript 复制代码
node server.js

3. 客户端网页播放(index.html)

创建一个简单的 HTML 文件,使用 jsmpeg 在浏览器中播放。

html 复制代码
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>RTSP Web 直播</title>
  <style>
    body { margin: 0; background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; }
    canvas { max-width: 100%; max-height: 100vh; }
  </style>
</head>
<body>
  <canvas id="videoCanvas"></canvas>

  <!-- 从 CDN 加载 jsmpeg(最新版) -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jsmpeg/0.2/jsmpeg.min.js"></script>
  <script>
    const player = new JSMpeg.Player('ws://你的服务器IP:9999', {
      canvas: document.getElementById('videoCanvas'),
      autoplay: true,          // 自动播放
      audio: false,            // 大多数 RTSP 无音频,或关闭以减少负载
      videoBufferSize: 512 * 1024,  // 增大缓冲(可选,改善卡顿)
      onVideoDecode: () => console.log('视频解码中...')  // 可选日志
    });
  </script>
</body>
</html>
  • 用浏览器打开此 HTML 文件(或通过简单 HTTP 服务器如 npx serve 托管)。
  • 替换 ws://你的服务器IP:9999 为实际地址(局域网测试用本地 IP,公网需端口映射)。

4. 多路摄像头支持

每个流需独立 WebSocket 端口:

javascript 复制代码
// 多路示例
new Stream({ streamUrl: 'rtsp://cam1-url', wsPort: 9999 });
new Stream({ streamUrl: 'rtsp://cam2-url', wsPort: 10000 });
// 客户端对应不同 wsPort 播放

5. 常见问题与优化

  • 延迟:通常 1-3 秒(MPEG1 + WebSocket 特性),适合监控,不适合超低延迟(<1s 用 WebRTC 方案)。
  • 画质/卡顿 :调整 -r、-b:v、分辨率(如添加 -s 640x480)。
  • 无视频:检查 RTSP URL(用 VLC 测试),确保摄像头帧率 ≥15fps。
  • 音频 :若需音频,设 audio: true,但 MPEG1 音频支持有限。
  • 安全性:公网部署加 HTTPS/WSS,或认证。
  • 错误日志:服务器运行时观察控制台 FFmpeg 输出。

6. 测试建议

用公开 RTSP 测试流验证: rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov

相关推荐
百思不得小李几秒前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易14 分钟前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马25 分钟前
前沿视界
前端
kyriewen30 分钟前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易1 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员
IT_陈寒1 小时前
Vue的这个响应式陷阱,差点让我加班到天亮
前端·人工智能·后端
Flynt2 小时前
别写拖拽行为,只声明"能拖到哪":UIST 最佳论文的拖拽方案我实测了
前端·svg·preact
Moment3 小时前
代码都能让 Agent 写了,我们为什么还要学前端?
前端·后端·面试
Hilaku3 小时前
MCP 协议会成为前端 AI 工程的标准接口吗?
前端·javascript·程序员
Zan3 小时前
Tauri 2 实战:为什么一个可靠的桌面应用,应该由 Rust Host 管理生命周期?
前端·架构·rust