npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@le5le/live-player

v0.1.0

Published

浏览器摄像头与直播播放器:WS-FLV / HTTP-FLV / WebRTC 直播 + 录像回放,一个地址自动识别容器,专治 H265 切后台断流与多路同屏带不动 | Browser player for IP cameras and live streams: WS-FLV / HTTP-FLV / WebRTC live plus recording playback, transport auto-detected from the URL, built to fix H265 stalls af

Readme

live-player - 浏览器摄像头和直播播放器

中文 | English

live-player 是一款浏览器摄像头和直播播放器:支持 WS-FLV 直播 + 录像文件(FLV / MP4)。

安装

pnpm add @le5le/live-player mpegts.js

mpegts.js 是 peerDependency,需要宿主自己安装。

npm 包里只有 dist/:一个未压缩的 ESM 文件 + 各文件的 .d.ts,另带 sourcemap。

不用打包器的项目直接 <script type="module"> import dist/live-player.js 即可。

适合什么场景

为监控摄像头这类流写的播放器,不是通用视频播放器。它解决的是这几件在监控场景里反复出问题的事:

  • 一个地址既可能是直播也可能是录像。国标(GB28181)设备回放的 ws-flv 地址与直播长得一模一样, 容器也相同,只能由调用方告知语义(live),库据此决定要不要丢帧、要不要允许拖动、断了要不要重连。
  • H265 直播切后台再回来会断流重连。这是本库的起点:隐藏期积压的数据回到前台后触发 seek, 而 H265 跳到非 IDR 位置就解不开。库在 MSE 写入层拦下来,切走几分钟回来也不必等「正在恢复画面」。
  • 多路同屏带不动。九宫格主码流是 9 路 4MP H265 解码,浏览器没有任何 API 能查询剩余硬解会话数。 库只能在失败后反应:一路解码失败就整组降到子码流(设备原生双码流,服务端不转码)。
  • 播放地址带短寿命凭据。平台侧播放 token 常是 30 秒 TTL,而重连恰恰最容易撞上它过期。 库重连前会回调 renewSources 向宿主索取新地址。

不适合:点播站、HLS/DASH 自适应码率、直播带货这类只需要「放一个 mp4/m3u8」的场景 —— 那些用 <video> 或 hls.js 更合适,本库的复杂度全花在上面四件事上。

功能

协议

按地址里的路径标记自动选传输方式(不是按扩展名 —— 现网直播地址常没有扩展名):

| 地址形态 | 传输方式 | 说明 | | -------------------------------------------------------- | -------- | ---------------------------------------- | | ws:// wss:// + 路径含 flv/mpegts | MSE 直播 | 主力路径,过 mpegts.js | | http(s):// 含 flv/ts 且路径有 .live. 或 /live/ | MSE 直播 | ZLM / 乐吾乐的 http-flv 直播 | | http(s):// 含 flv/ts,不带 live 段 | MSE 录像 | FLV 录像文件,可拖动 | | http(s):// 含 .mp4/fmp4 | 原生播放 | 交给浏览器,白拿 seek 与进度条 | | 路径含 webrtc/whep | WebRTC | 延迟约 0.2~0.4s,需宿主开 preferWebrtc |

  • WebSocket 地址不带容器标记时不猜,直接判 unsupported —— 猜错的代价是播不出来却报错到别处。 这是前后端契约:后端新增播放地址必须在 path 里带 flv/mpegts/ts/mp4 之一。
  • WebRTC 不由 URL 自动启用。两条路的取舍随同屏路数翻转(WebRTC 延迟低但没有 MSE、 后台仍满速解码),而库不知道自己是九宫格里的一格还是单画面,所以由宿主决定。 走不通会自动退回 FLV,不必宿主兜。

用 resolveTransport(url) 可以单独查某个地址会被判成什么,isLiveUrl(url) 判断要不要显示进度条。

格式

容器:FLV、MPEG-TS(均过 mpegts.js)、MP4 / fMP4(交给浏览器原生播放)。

视频编码:H264、H265(HEVC)。H265 的浏览器支持是分裂的 —— Chrome 136+ 原生支持但要求硬件解码、 Safari 18+ 通、Edge 至今未跟上、Firefox 不支持。hevcSupported() 可做静态能力查询,但要注意 它只说明浏览器认不认这个 codec,不代表还有可用的硬解会话 —— 已经开了 8 路解码器它照样返回 true。 真正能不能播只有喂进去才知道,由看门狗与自动降级兜底。

音频:MSE 这条路目前固定关闭音频(hasAudio: false,不可配)。原因是国标 PS 流的音频常是 G.711,而 mpegts.js 只认 AAC/MP3,遇到别的会抛 CodecUnsupported 打断整条解复用;更要紧的是 音轨 SourceBuffer 一旦出错会把 <video> 整个置成 error 态,视频的 appendBuffer 也跟着全失败 —— 画面直接黑。监控场景不需要声音,所以选择让 demuxer 在读 soundFormat 之前就丢掉音频 tag。 WebRTC 这条路会协商 audio 轨(ZLM 少一条媒体行会整体协商失败),能不能出声取决于服务端。

使用

import { createPlayer, createGroup, isLiveUrl } from '@le5le/live-player';

const player = createPlayer(videoEl, {
  sources: {
    main: 'wss://host/ws/gb/flv?streamId=xxx',
    sub: 'wss://host/ws/gb/flv?streamId=xxx_sub', // 没有子码流就不传,不参与降级
  },
  live: true, // 录像回放必须传 false —— 国标回放地址与直播同形,库看不出区别
});

// 事件用 on/off 注册,不是构造参数
player.on('statechange', (s) => console.log(s)); // idle|connecting|playing|resyncing|reconnecting|failed
player.on('error', (e) => console.log(e.kind, e.message, e.fatal));
player.on('qualitychange', (q, reason) => console.log(q, reason));
player.on('ended', () => console.log('这一段放完了')); // 只有非实时流会触发

await player.play();

播放地址带短寿命凭据时,传 renewSources 让库在重连前换一份新地址:

const player = createPlayer(videoEl, {
  sources,
  live: true,
  renewSources: async () => (await api.renewPlay(channelId)).sources,
});

想用 WebRTC 换低延迟(单画面或小宫格):

createPlayer(videoEl, {
  sources: { main: flvUrl, webrtc: webrtcUrl },
  preferWebrtc: true, // 走不通会自动退回 main 的 FLV
  live: true,
});

读 player.transport 拿到实际在用的传输方式 —— preferWebrtc 为真时也可能已经退回 FLV, 想在界面上标「低延迟」就得读这个,读 preferWebrtc 会在退回后说谎。

其余成员:pause() / destroy() / setQuality(q) / snapshot() 抓拍,以及只读的 state / quality / hasSub / live。

宫格

const group = createGroup();
group.add(player); // 任一路解码失败时,整组一起切子码流(有子码才切)
group.add(player2);

createGroup() 用于同屏多路:某一路因为解码带不动而降级时整组一起切,避免只降一格、 其余仍在抢解码会话。单画面不用。

手动 setQuality() 过的实例从组自动降级中豁免 —— 用户明确要这一格看主码流,库不跟他抢。

live: false 时库允许 seek(录像本来就该能拖),live: true 时永不 seek 到未缓冲位置—— 那正是断流重连的真身。