Thinking
桌面应用开发者的视频能力,原本要靠浏览器插件、流媒体中转服务器、或者一堆难啃的 C++ 代码才能拼出来。
现在,一个npm install就够了。
如果你做过 Electron 桌面应用,一定撞过这堵墙:浏览器原生不支持 RTSP / RTMP。
你手里的摄像头、NVR、直播推流,几乎都跑在这两个协议上。但 Chromium 的 <video> 只认 MP4、WebM、HLS,想让它直连一台 rtsp:// 的 IPC 摄像头?做不到。常见的解法是:在服务端架一个 FFmpeg / GStreamer / 流媒体网关,把 RTSP 转码成 HLS 或 WebRTC,再喂给前端。代价是——多一台服务器、多一份延迟、多一倍运维成本,还多了一个永远在转码的 CPU。
我们觉得这件事不该这么难。
所以有了 NodePlayerAddon——一款专为 Electron 打造的原生播放器扩展,用 N-API C++ 写成,让 Electron 直连 RTSP / RTMP / KMP / HTTP(S)-FLV,无需任何中转服务器。
把”专业级视频监控播放器”的能力,封装成一个 Electron 可直接 require 的 npm 包。
低延迟、硬解码、跨平台、可商用。
| 协议 | 场景 |
|---|---|
| RTSP | IPC 摄像头、NVR、安防监控的事实标准 |
| RTMP | 直播推流、 CDN 回源 |
| KMP | NodeMedia 自有高效传输协议 |
| HTTP(S)-FLV | 直播拉流 |
不再需要”先架一个流媒体服务器再开发前端”。Electron 进程内直接拉流、解码、上屏。
一套代码,七个目标平台:
对国产化、信创、嵌入式工控场景,这是少有的”开箱即用”选项。我们直接随包发布预编译二进制(prebuilds/),开发者无需本地 C++ 工具链,npm install 即用。
底层基于 FFmpeg,视频支持 H.264 / H.265,音频支持 AAC / G.711 / G.726 / MP2。解码走硬件加速,配合自研的 MediaSource 管线(FIFO 队列 + updateend 驱动 append),实测端到端延迟显著低于”服务端转码 + HLS”方案。
播放过程中随时可用:
captureScreenshot() 拿内存 data URL,或 saveScreenshot() 直接落盘成 JPGstartRecord(path) / stopRecord(),原生封装、输出 MP4这是一个被很多监控产品忽略、但实际开发中极高频的需求:
在创建播放器之前,先探测地址是否可达、拿到音视频编码参数、并截取首帧预览图。
const result = await NodePlayerView.getMediaInfo('rtsp://192.168.1.100:554/stream')// result.info = { video: { codecId, width, height }, audio: { codecId, sampleRate, channels }, screenshot }
这意味着用户在”添加摄像头”的表单里,输入地址的瞬间就能看到真实画面预览 + 编码信息,而不是傻等播放器连上、黑屏三秒才知道地址对不对。体验差距立竿见影。
主进程里只要一句:
NodePlayerAddon.registerIpc(ipcMain, { getWindow: () => mainWindow, licensePath })
registerIpc 自动注册好 8 个 IPC handler(create / start / stop / destroy / startRecord / stopRecord / saveScreenshot / getMediaInfo),多实例用 Map 隔离,事件按 player:{event|info|data}:{id} 分通道推送。配合 contextBridge,渲染进程拿到的是一个干净、类型清晰的 window.electronAPI。
安全模型不妥协:contextIsolation 全程开启,渲染进程不直接碰原生模块。

光说特性不直观。我们用 NodePlayerAddon 做了一个完整的、产品级的监控中心 Demo——SkyWatch,它就是一个你今天就能跑起来、能作为产品基线的真实应用。
技术栈:Electron 39 + electron-vite + React 19 + Tailwind CSS v4 + react-router v7。
SkyWatch 不是”Hello World”。它是一套完整的视频监控运营平台 UI,包含:
| 模块 | 能力 |
|---|---|
| 仪表盘 | 摄像头网络总览、状态卡片、在线/离线统计 |
| 添加摄像头 | 三步向导,第一步就用 getMediaInfo 探测 RTSP 地址并显示首帧预览,自动识别分辨率、编码、音频参数 |
| 视频墙 | 4 / 9 / 16 宫格,一键自动填满在线摄像头,单路全屏、整墙全屏、布局切换 |
| 录像 | 录制管理、本地库浏览 |
| 截图 | IndexedDB 存储、画廊浏览 |
| 统计 / 告警 / 设置 | 完整的后台管理骨架,CPU/内存/磁盘实时采样 |
其中播放器组件 VideoPlayer.jsx 封装得相当干净,可以作为集成参考:
import NodePlayerView from 'nodeplayer-addon/NodePlayerView'const player = new NodePlayerView(videoRef.current, id)player.on('event', (code, msg) => { /* 1001=已连接, 3001=录制中... */ })player.on('error', (err) => {})player.start(url) // 开始拉流await player.startRecord(path) // 录像await player.saveScreenshot(path) // 截图player.stop()
整个 SkyWatch 的渲染层,没有一个手写的解码/缓冲/拉流逻辑——全部由 NodePlayerAddon 托管。开发者只关心 React UI 和业务交互。
SkyWatch 完整源码可作为商用项目的脚手架。它演示了从”加摄像头”到”多路同屏”到”录像回放”的全链路最佳实践。
# 1. 用 Electron Forge 建项目npx create-electron-app@latest my-app && cd my-app# 2. 装扩展npm i nodeplayer-addon# 3. 主进程一行注册 IPC# NodePlayerAddon.registerIpc(ipcMain, { getWindow, licensePath })# 4. preload 用 contextBridge 暴露 API# 5. 渲染层 <video> + new NodePlayerView(videoEl, id).start(url)npm start# 输入 rtsp://... 即可播放
没有授权文件?直接开跑——内置 10 分钟试用模式,足够验证你的业务场景。
React / Vue 前端的完整脚手架集成指南,见 docs/react-frontend.md 与 docs/vue-frontend.md。
NodePlayerAddon 是商用授权产品。
license.dat(Ed25519 签名,离线校验)联系方式
Electron 让”用 Web 技术写桌面应用”成为现实,但视频流一直是它最别扭的角落。NodePlayerAddon 想做的事情很小,也很明确:
把”直连 RTSP/RTMP、硬解、低延迟、可录像可截图”这件事,变成 Electron 生态里一个开箱即用的标准能力。
SkyWatch 是这个能力的证明——一个产品级的监控中心,前端用 React 19 写得清清爽爽,视频流部分全部交给 NodePlayerAddon。
如果你正在做、或正准备做一个 Electron 视频应用,欢迎来试。我们很想知道你用它做出了什么。
npm i nodeplayer-addon —— 然后,开始播放。