rivmux 0.4.0 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,14 +1,10 @@
1
1
  # Rivmux Player
2
2
 
3
- Public browser player facade for Rivmux low-latency live playback.
3
+ `rivmux` Rivmux 面向用户的浏览器播放器包。它在 Dedicated Worker 中读取 HTTP-FLV,将音视频转封装为 fragmented MP4,并通过 Worker MSE 连接到 `<video>` 元素。当前没有主线程 MSE 降级路径。
4
4
 
5
- `rivmux` loads HTTP-FLV streams in a dedicated worker, transmuxes supported
6
- audio/video into fragmented MP4, and attaches the resulting media stream to a
7
- browser `<video>` element.
5
+ ## 安装
8
6
 
9
- M1 supports only the dedicated-worker MSE runtime path. Main-thread MSE is not available.
10
-
11
- ## Install
7
+ 当前发布格式为 ESM-only,不提供 CommonJS、UMD 或全局变量构建。
12
8
 
13
9
  ```sh
14
10
  pnpm add rivmux
@@ -18,10 +14,11 @@ pnpm add rivmux
18
14
  npm install rivmux
19
15
  ```
20
16
 
21
- ## Basic Usage
17
+ 当前发布目标是浏览器 ESM Bundler。Vite 已完成验证,其他 bundler 暂不形成兼容承诺。包的 `exports` 只提供 `import` 和类型条件,不提供 CommonJS、UMD 或全局变量入口。Node.js 仅支持 ESM 导入以及 SSR/能力探测调用,不提供 Node 播放运行时。
18
+
19
+ ## 基本用法
22
20
 
23
- Always wait for `attach()` before calling `start()`. `attach()` initializes the
24
- worker and connects the internal `MediaSourceHandle` to the video element.
21
+ 调用 `start()` 前必须等待 `attach()` 完成。`attach()` 会初始化 Worker,并把内部 `MediaSourceHandle` 连接到 video 元素。
25
22
 
26
23
  ```ts
27
24
  import { RivmuxPlayer } from 'rivmux'
@@ -29,7 +26,7 @@ import { RivmuxPlayer } from 'rivmux'
29
26
  const video = document.querySelector<HTMLVideoElement>('#player')
30
27
 
31
28
  if (!video) {
32
- throw new Error('Missing video element')
29
+ throw new Error('未找到 video 元素')
33
30
  }
34
31
 
35
32
  const player = new RivmuxPlayer('https://example.com/live.flv', {
@@ -39,7 +36,7 @@ const player = new RivmuxPlayer('https://example.com/live.flv', {
39
36
  })
40
37
 
41
38
  player.on('mediaInfo', (info) => {
42
- console.log('media info', info)
39
+ console.log('媒体信息', info)
43
40
  })
44
41
 
45
42
  player.on('error', (error) => {
@@ -49,31 +46,87 @@ player.on('error', (error) => {
49
46
  await player.attach(video)
50
47
  await player.start()
51
48
 
52
- // Later:
49
+ // 不再使用时:
53
50
  await player.stop()
54
51
  await player.destroy()
55
52
  ```
56
53
 
57
- ## Player Lifecycle
54
+ ## 能力探测
55
+
56
+ 创建播放器前可同步读取基础运行环境和解码能力:
57
+
58
+ ```ts
59
+ import { getCapabilities, isSupported } from 'rivmux'
60
+
61
+ if (!isSupported()) {
62
+ throw new Error('当前环境不具备 Rivmux 基础运行能力')
63
+ }
64
+
65
+ const capabilities = getCapabilities()
66
+ console.log(capabilities.decoding.stableProfiles.hevcAac)
67
+ ```
68
+
69
+ ```ts
70
+ type SupportStatus = 'supported' | 'unsupported' | 'unknown'
71
+
72
+ type RivmuxCapabilities = {
73
+ supported: boolean
74
+ runtime: {
75
+ dedicatedWorker: boolean
76
+ workerMse: boolean
77
+ fetchStreaming: boolean
78
+ readableStream: boolean
79
+ webAssembly: boolean
80
+ }
81
+ decoding: {
82
+ video: {
83
+ avc: SupportStatus
84
+ hevc: SupportStatus
85
+ av1: SupportStatus
86
+ }
87
+ audio: {
88
+ aac: SupportStatus
89
+ opus: SupportStatus
90
+ }
91
+ stableProfiles: {
92
+ avcAac: SupportStatus
93
+ hevcAac: SupportStatus
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ `isSupported()` 始终等于 `getCapabilities().supported`。这里的 `supported` 是基础运行能力结果,只表示 Dedicated Worker、Worker MSE、流式 Fetch、ReadableStream 和 WebAssembly 等条件可用,不保证具体媒体流能够播放。下面解码矩阵中的 `supported` 是另一层 codec 前置探测结果,二者都不等于实际播放成功。
100
+
101
+ 解码矩阵通过同步的 `MediaSource.isTypeSupported()` 对代表性 codec 执行前置判断:`supported` 表示环境报告支持,`unsupported` 表示环境明确拒绝,`unknown` 表示 API 不可用或无法可靠判断。该结果不会改变输入的 Stable、Experimental 或不支持边界,也不替代真实流校验。Rivmux 取得实际 codec、profile 和 level 后,仍会使用准确 MIME 做最终 MSE 校验。
102
+
103
+ 能力探测不会创建 Worker、发起网络请求或修改 DOM。在 SSR 和 Node.js 环境中调用不会抛错:基础能力为 `false`,无法判断的解码能力为 `unknown`。
104
+
105
+ ## 播放器生命周期
58
106
 
59
107
  ```ts
60
108
  const player = new RivmuxPlayer(url, options)
61
109
  ```
62
110
 
63
- | Call | Description |
64
- | --------------------------------- | -------------------------------------------------------------------------------------------------------- |
65
- | `new RivmuxPlayer(url, options?)` | Creates a player instance for one stream URL. |
66
- | `await player.attach(video)` | Attaches the player to a `<video>` element and prepares the worker/MSE pipeline. |
67
- | `await player.start()` | Starts loading, transmuxing, buffering, and playback control. Call after `attach()`. |
68
- | `await player.stop()` | Stops loading, detaches the media source, and keeps the instance reusable. |
69
- | `await player.destroy()` | Releases the worker, timers, listeners, and video source. The instance cannot be reused after this call. |
70
- | `player.on(type, listener)` | Subscribes to a player event. |
71
- | `player.off(type, listener)` | Removes a previously registered listener. |
111
+ | 调用 | 含义 |
112
+ | --------------------------------- | ------------------------------------------------------------ |
113
+ | `new RivmuxPlayer(url, options?)` | 为一个流地址创建播放器实例。 |
114
+ | `await player.attach(video)` | 绑定 `<video>` 元素并准备 Worker/MSE 链路。 |
115
+ | `await player.start()` | 启动加载、转封装、缓冲与播放控制;必须在 `attach()` 后调用。 |
116
+ | `await player.stop()` | 停止加载并解绑媒体源;实例可以再次启动。 |
117
+ | `await player.destroy()` | 释放 Worker、定时器、监听器和媒体源;实例不可再用。 |
118
+ | `player.on(type, listener)` | 订阅播放器事件。 |
119
+ | `player.off(type, listener)` | 移除先前注册的监听器。 |
120
+
121
+ `attach()` 完成只表示媒体源句柄已经连接;`start()` 完成只表示 Worker 已建立本次启动所需的内部加载、转封装和 MSE 会话。两者都不表示已经解析出媒体信息、已经追加首个媒体片段,也不表示 `<video>` 已触发 `canplay` 或开始播放。请通过 `mediaInfo`、`stats`、`error` 和视频元素事件观察后续结果。
122
+
123
+ 同一启动过程中的并发 `start()` 调用会等待同一个操作,不会重复发送启动命令。播放器已经启动后再次调用 `start()` 会直接完成。若 `stop()` 或 `destroy()` 在启动确认前开始,待处理的 `start()` 会以 `RIVMUX_START_CANCELLED` 拒绝,而停止或销毁操作仍会正常完成。终止错误会使 `start()` 以相同错误码拒绝。
72
124
 
73
- ## Options
125
+ 上述规则收紧了旧版本中“发送启动命令后立即完成”的时序;依赖旧时序的调用方应改为等待 `start()`,并将媒体就绪逻辑放到对应事件中。
74
126
 
75
- All options are optional. Missing fields are merged with
76
- `DEFAULT_RIVMUX_PLAYER_OPTIONS`.
127
+ ## 配置项
128
+
129
+ 所有配置均为可选项,缺省字段会由播放器内部默认值补齐。
77
130
 
78
131
  ```ts
79
132
  import { RivmuxPlayer } from 'rivmux'
@@ -92,130 +145,182 @@ const player = new RivmuxPlayer('https://example.com/live.flv', {
92
145
  },
93
146
  network: {
94
147
  credentials: 'include',
148
+ readIdleTimeoutMs: 10000,
95
149
  headers: {
96
150
  Authorization: 'Bearer token',
97
151
  },
98
152
  retry: {
99
153
  maxAttempts: 5,
100
154
  backoffMs: 500,
155
+ maxBackoffMs: 8000,
156
+ jitterRatio: 0.2,
101
157
  },
102
158
  },
103
159
  diagnostics: {
104
160
  statsIntervalMs: 1000,
105
- debug: false,
106
161
  },
107
162
  })
108
163
  ```
109
164
 
110
165
  ### `playback`
111
166
 
112
- | Option | Default | Description |
113
- | ---------- | ------- | --------------------------------------------------------------------------------- |
114
- | `autoPlay` | `true` | Lets the runtime request `video.play()` when enough startup buffer is available. |
115
- | `muted` | `false` | Sets `video.muted`. Many browsers require muted playback for autoplay with audio. |
167
+ | 配置项 | 默认值 | 含义 |
168
+ | ---------- | ------- | ---------------------------------------------------------- |
169
+ | `autoPlay` | `true` | 启动缓冲足够时,由运行时请求 `video.play()`。 |
170
+ | `muted` | `false` | 设置 `video.muted`;浏览器通常只允许带音频的静音自动播放。 |
116
171
 
117
172
  ### `latency`
118
173
 
119
- Values are in seconds.
174
+ 以下数值单位均为秒。
120
175
 
121
- | Option | Default | Description |
122
- | ------------------ | ------- | ---------------------------------------------------------------------------------------------- |
123
- | `startupBuffer` | `0.35` | Buffered duration required before automatic playback starts. |
124
- | `target` | `1.2` | Desired live latency. The runtime uses this when resuming fetches and restoring playback rate. |
125
- | `max` | `2.5` | Maximum tolerated live latency before the runtime seeks closer to the live edge. |
126
- | `maxForwardBuffer` | `4` | Forward buffer threshold where the loader may pause to avoid excessive buffering. |
127
- | `backwardBuffer` | `1.5` | Amount of buffer to keep behind the current playhead during cleanup. |
176
+ | 配置项 | 默认值 | 含义 |
177
+ | ------------------ | ------ | ------------------------------------------------ |
178
+ | `startupBuffer` | `0.35` | 发起自动播放前需要的缓冲时长。 |
179
+ | `target` | `1.2` | 目标直播延迟;恢复读取和播放速率时使用。 |
180
+ | `max` | `2.5` | 最大可接受直播延迟;超过后向直播边缘追帧。 |
181
+ | `maxForwardBuffer` | `4` | 前向缓冲上限;Loader 可暂停读取以避免过度缓冲。 |
182
+ | `backwardBuffer` | `1.5` | 清理缓冲时在当前播放位置之前保留的历史缓冲时长。 |
128
183
 
129
184
  ### `network`
130
185
 
131
- | Option | Default | Description |
132
- | ------------------- | --------------- | ----------------------------------------------------------------- |
133
- | `headers` | `{}` | Extra request headers for the HTTP-FLV stream. |
134
- | `credentials` | `'same-origin'` | Fetch credentials mode for stream requests. |
135
- | `retry.maxAttempts` | `3` | Maximum stream request attempts before reporting a network error. |
136
- | `retry.backoffMs` | `500` | Base retry delay in milliseconds. |
186
+ | 配置项 | 默认值 | 含义 |
187
+ | -------------------- | --------------- | ---------------------------------------------------------------------------------------- |
188
+ | `headers` | `{}` | HTTP-FLV 请求附带的额外请求头。 |
189
+ | `credentials` | `'same-origin'` | Fetch 请求的 credentials 模式。 |
190
+ | `readIdleTimeoutMs` | `10000` | 主动读取期间持续无数据的超时时间;Loader 因背压暂停时不计时。 |
191
+ | `retry.maxAttempts` | `3` | 单次故障恢复周期允许的连接总次数,包含发生故障的当前连接;成功恢复后下一次故障重新计数。 |
192
+ | `retry.backoffMs` | `500` | 指数退避的基础延迟,单位为毫秒。 |
193
+ | `retry.maxBackoffMs` | `8000` | 应用抖动后的最大退避延迟,单位为毫秒。 |
194
+ | `retry.jitterRatio` | `0.2` | 对称抖动比例,取值范围为 `0` 至 `1`;`0` 表示关闭抖动。 |
137
195
 
138
196
  ### `runtime`
139
197
 
140
- | Option | Default | Description |
141
- | ----------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------- |
142
- | `preferWorkerMse` | `true` | Must remain `true` in M1. Main-thread MSE fallback is not implemented. |
143
- | `workerUrl` | bundled worker URL | Advanced override for the packaged Dedicated Worker script URL. |
144
- | `wasmUrl` | bundled WASM module | Advanced override for the packaged WASM binary URL. It must match the Worker release that contains the wasm-bindgen glue. |
198
+ `runtime.workerUrl` `runtime.wasmUrl` 是 Experimental 资产部署覆盖项;它们嵌套在稳定的 `RivmuxPlayerOptions` 形状中,但不改变当前固定的 Worker MSE runtime,也不承诺跨 bundler、CSP 或部署方式的长期兼容性。
199
+
200
+ | 配置项 | 默认值 | 含义 |
201
+ | ----------- | ------------------ | ----------------------------------------------------------------------------- |
202
+ | `workerUrl` | 包内 Worker URL | 高级配置,用于覆盖包内 Dedicated Worker 脚本 URL。 |
203
+ | `wasmUrl` | 包内 WASM 模块 URL | 高级配置,用于覆盖 WASM URL;必须与包含 wasm-bindgen 胶水的 Worker 版本匹配。 |
145
204
 
146
- ### Advanced Asset Deployment
205
+ ### Worker/WASM 资产部署
147
206
 
148
- Most applications should omit `runtime.workerUrl` and `runtime.wasmUrl`. The
149
- default package assets are tracked by Vite and emitted with the application
150
- build.
207
+ 多数应用无需设置 `runtime.workerUrl` `runtime.wasmUrl`。默认资产 URL 会被 Vite 等打包工具跟踪,并随应用构建输出。
151
208
 
152
- Set these options only when your deployment serves Rivmux assets from a fixed
153
- public path or CDN:
209
+ 只有在固定公共路径或 CDN 部署 Rivmux 资产时才需要覆盖:
154
210
 
155
211
  ```ts
156
212
  const player = new RivmuxPlayer('https://example.com/live.flv', {
157
213
  runtime: {
158
- workerUrl: 'https://cdn.example.com/rivmux/0.4.0/rivmux-runtime-worker.js',
159
- wasmUrl: 'https://cdn.example.com/rivmux/0.4.0/rivmux-transmux-core.wasm',
214
+ workerUrl: 'https://cdn.example.com/rivmux/0.5.0/rivmux-runtime-worker.js',
215
+ wasmUrl: 'https://cdn.example.com/rivmux/0.5.0/rivmux-transmux-core.wasm',
160
216
  },
161
217
  })
162
218
  ```
163
219
 
164
- `workerUrl` does not derive `wasmUrl`; when you override both assets, publish
165
- them as a matching release pair. Treat both URLs as trusted executable asset
166
- locations and never construct them from untrusted input. The host application
167
- is responsible for compatible CSP and CORS policies, serving the WASM asset as
168
- `application/wasm`, and cache-busting the Worker/WASM pair together.
220
+ `workerUrl` 不会推导 `wasmUrl`。覆盖两项时必须发布同一版本的 Worker/WASM 资产对,并使用相同缓存版本策略。两者都是可执行资产地址,不得由不可信输入拼接。宿主应用需配置兼容的 CSP CORS,并以 `application/wasm` 提供 WASM 文件。
169
221
 
170
222
  ### `diagnostics`
171
223
 
172
- | Option | Default | Description |
173
- | ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
174
- | `statsIntervalMs` | `1000` | Requested stats interval in milliseconds. Runtime reporting is clamped internally for stable video-state feedback. |
175
- | `debug` | `false` | Enables debug-oriented behavior where supported by the runtime. |
224
+ | 配置项 | 默认值 | 含义 |
225
+ | ----------------- | ------ | ------------------------------------------------------------ |
226
+ | `statsIntervalMs` | `1000` | 请求的统计上报间隔,单位为毫秒;运行时会在内部限制实际范围。 |
176
227
 
177
- ## Events
228
+ ## 事件
178
229
 
179
230
  ```ts
180
- import type { MediaInfo, PlayerError, PlayerStats, PlayerWarning } from 'rivmux'
231
+ import type { MediaInfo, PlayerError, PlayerStats, PlayerWarning, ReconnectInfo, RecoveryInfo } from 'rivmux'
181
232
 
182
- player.on('ready', () => {})
233
+ player.on('initialized', () => {})
183
234
  player.on('mediaInfo', (info: MediaInfo) => {})
184
235
  player.on('stats', (stats: PlayerStats) => {})
185
236
  player.on('warning', (warning: PlayerWarning) => {})
237
+ player.on('reconnecting', (info: ReconnectInfo) => {})
238
+ player.on('recovered', (info: RecoveryInfo) => {})
186
239
  player.on('error', (error: PlayerError) => {})
187
240
  player.on('stopped', () => {})
188
241
  player.on('destroyed', () => {})
189
242
  ```
190
243
 
191
- | Event | Payload | Description |
192
- | ----------- | --------------- | ----------------------------------------------------------------------- |
193
- | `ready` | `undefined` | The worker/runtime is initialized. |
194
- | `mediaInfo` | `MediaInfo` | Stream container and codec metadata has been detected. |
195
- | `stats` | `PlayerStats` | Runtime diagnostics such as bytes, buffer, latency, and playback state. |
196
- | `warning` | `PlayerWarning` | Recoverable issue reported by the runtime. |
197
- | `error` | `PlayerError` | Runtime, network, demux, codec, mux, MSE, or unsupported-feature error. |
198
- | `stopped` | `undefined` | The stream has stopped and the media source has been detached. |
199
- | `destroyed` | `undefined` | The worker/runtime has been destroyed. |
244
+ | 事件 | 数据 | 含义 |
245
+ | -------------- | --------------- | ------------------------------------------------------------------------------------------------------------ |
246
+ | `initialized` | `undefined` | `attach()` 期间所选 runtime 完成 `init` 后触发;同一 runtime 实例只触发一次,不表示 `canplay` 或 `playing`。 |
247
+ | `mediaInfo` | `MediaInfo` | 已识别媒体容器和 codec 信息。 |
248
+ | `stats` | `PlayerStats` | 字节数、缓冲、延迟和播放状态等运行时统计。 |
249
+ | `warning` | `PlayerWarning` | Runtime 报告的可恢复问题。 |
250
+ | `reconnecting` | `ReconnectInfo` | 已确定执行下一次连接,并给出连接序号、最大次数、延迟和故障原因。 |
251
+ | `recovered` | `RecoveryInfo` | 新会话的首个媒体片段已经成功追加;仅建立 HTTP 连接不会触发该事件。 |
252
+ | `error` | `PlayerError` | Runtime、网络、demux、codec、mux、MSE 或环境不支持错误。 |
253
+ | `stopped` | `undefined` | 播放已停止,媒体源已解绑。 |
254
+ | `destroyed` | `undefined` | Worker runtime 已销毁。 |
255
+
256
+ 用户事件监听器中的异常属于宿主应用异常,不属于 Rivmux 播放错误,也不会转换为 `PlayerError`。单个监听器抛出异常时,其他监听器仍会继续执行,`stop()`、`destroy()` 等生命周期 Promise 也会按内部状态正常完成。Rivmux 会优先通过平台的 `globalThis.reportError()` 报告该异常;平台不支持时使用 `console.error()` 降级报告。
257
+
258
+ ## 自动播放拒绝
259
+
260
+ 浏览器可能根据自动播放策略拒绝 Rivmux 请求的 `video.play()`。无用户手势的直播场景建议设置 `playback.muted: true`,以提高自动播放成功率。拒绝会产生非终止 warning `RIVMUX_AUTOPLAY_REJECTED`,其 `cause` 保留浏览器错误的 `name` 和 `message`;该 warning 不会中断网络加载、转封装或缓冲,也不会触发 `error` 事件。
261
+
262
+ Rivmux 在同一播放会话中不会自动重复调用 `play()`。调用方可以在按钮点击等真实用户手势处理器内直接恢复:
263
+
264
+ ```ts
265
+ button.addEventListener('click', () => {
266
+ void video.play()
267
+ })
268
+ ```
269
+
270
+ 设置 `playback.autoPlay: false` 后,Rivmux 不会主动请求启动播放,也不会产生该 warning。
271
+
272
+ ## 直播连接恢复
273
+
274
+ Rivmux 会为以下直播网络故障重建 Loader、转封装核心和 MSE 播放会话:
275
+
276
+ - HTTP `408`、`429` 和 `5xx`。
277
+ - 建连或读取阶段的网络异常。
278
+ - 已建立直播流后的异常 EOF。
279
+ - 主动读取期间超过 `network.readIdleTimeoutMs` 未收到数据。
280
+
281
+ HTTP `401`、`403` 和其他不可恢复的 `4xx` 不会重试。媒体解析、codec、mux 和 MSE 错误也不进入网络恢复流程。恢复次数耗尽后会产生一次终止错误 `RIVMUX_RECONNECT_EXHAUSTED`。
282
+
283
+ 恢复采用指数退避、最大延迟和抖动。等待重连或重建会话期间调用 `stop()` 或 `destroy()` 会立即取消恢复,不会继续创建连接。恢复会更换 `MediaSourceHandle`,因此可能出现短暂中断和时间线重置;当前不承诺无缝续播或跨连接连续时间线。
284
+
285
+ ## Codec 支持边界
286
+
287
+ | 输入 | 等级 | 说明 |
288
+ | ---------------------------------------- | ------------ | ---------------------------------- |
289
+ | HTTP-FLV + AVC/H.264 + AAC-LC | Stable | 受浏览器基础 MSE 能力约束 |
290
+ | Enhanced HTTP-FLV + HEVC/`hvc1` + AAC-LC | Stable | 浏览器解码能力是条件化的 |
291
+ | Enhanced HTTP-FLV + AV1 | Experimental | 实现层实验能力,组合与兼容性未承诺 |
292
+ | Enhanced HTTP-FLV + Opus | Experimental | 实现层实验能力,组合与兼容性未承诺 |
293
+ | MPEG-TS | 不支持 | 不属于当前产品输入边界 |
294
+
295
+ HEVC Stable 的具体范围是单视频轨、固定 codec 配置、Enhanced FLV `SequenceStart`、`CodedFrames` 和 HEVC `CodedFramesX`,输出 sample entry 为 `hvc1`。最终解码能力取决于浏览器、操作系统、设备以及具体 HEVC profile、level、bit depth 和 chroma format;Rivmux 不维护固定 profile/level allowlist。结构合法但环境不支持准确 MIME 时会产生终止错误 `RIVMUX_UNSUPPORTED_MSE_CODEC`。
296
+
297
+ `hev1`、多轨 HEVC、播放期间动态 codec 配置切换和 HEVC + Opus 不属于 Stable 范围。AV1 与 Opus 仍为 Experimental;当前未承诺它们与其他音视频 codec 的组合、浏览器兼容矩阵或稳定错误语义。能力矩阵中的 `supported` 不会把它们提升为 Stable。
200
298
 
201
- ## Type Imports
299
+ ## 类型导入
202
300
 
203
- The player package re-exports the key public types from `@rivmux/protocol`:
301
+ 主包会重新导出用户需要的主要类型:
204
302
 
205
303
  ```ts
206
304
  import type {
207
305
  DiagnosticsOptions,
306
+ DecodingCapabilities,
208
307
  LatencyOptions,
209
308
  MediaInfo,
210
309
  NetworkOptions,
211
310
  PlaybackOptions,
212
311
  PlayerError,
312
+ PlayerErrorCause,
213
313
  PlayerStats,
214
314
  PlayerWarning,
315
+ ReconnectInfo,
316
+ ReconnectReason,
317
+ RecoveryInfo,
318
+ RivmuxCapabilities,
215
319
  RivmuxPlayerOptions,
320
+ RuntimeCapabilities,
216
321
  RuntimeOptions,
322
+ SupportStatus,
217
323
  } from 'rivmux'
218
324
  ```
219
325
 
220
- Use `normalizePlayerOptions(options)` if you need to inspect a fully populated
221
- options object with defaults applied.
326
+ 主包会导出上例中的 Experimental `RuntimeOptions`,但它不属于 Stable 兼容承诺。配置归一化和错误构造函数属于内部实现,未导出为应用 API。
package/dist/index.d.ts CHANGED
@@ -1,36 +1,33 @@
1
- import { RuntimeWorkerFactory } from "@rivmux/runtime-worker";
2
- import { DiagnosticsOptions, LatencyOptions, MediaInfo, NetworkOptions, NormalizedRivmuxPlayerOptions, NormalizedRivmuxPlayerOptions as NormalizedRivmuxPlayerOptions$1, PlaybackOptions, PlayerError, PlayerError as PlayerError$1, PlayerErrorKind, PlayerErrorKind as PlayerErrorKind$1, PlayerEventListener, PlayerEventListener as PlayerEventListener$1, PlayerEventMap, PlayerEventType, PlayerEventType as PlayerEventType$1, PlayerStats, PlayerWarning, RivmuxPlayerOptions, RivmuxPlayerOptions as RivmuxPlayerOptions$1, RuntimeOptions } from "@rivmux/protocol";
1
+ import { DecodingCapabilities, DiagnosticsOptions, LatencyOptions, MediaInfo, NetworkOptions, PlaybackOptions, PlayerError, PlayerErrorCause, PlayerErrorKind, PlayerEventListener, PlayerEventListener as PlayerEventListener$1, PlayerEventMap, PlayerEventType, PlayerEventType as PlayerEventType$1, PlayerStats, PlayerWarning, ReconnectInfo, ReconnectReason, RecoveryInfo, RivmuxCapabilities, RivmuxCapabilities as RivmuxCapabilities$1, RivmuxPlayerOptions, RivmuxPlayerOptions as RivmuxPlayerOptions$1, RuntimeCapabilities, RuntimeOptions, SupportStatus } from "@rivmux/protocol";
3
2
  //#region src/player.d.ts
4
- type RivmuxPlayerInternals = {
5
- workerFactory?: RuntimeWorkerFactory;
6
- detectRuntime?: () => PlayerError$1 | undefined;
7
- idFactory?: () => string;
8
- };
9
3
  /**
10
4
  * Public browser player facade for one HTTP-FLV stream.
11
5
  *
12
6
  * Create one instance per stream URL, call `attach(video)` first, then
13
7
  * `start()`. Call `destroy()` when the instance is no longer needed.
14
8
  */
15
- declare class RivmuxPlayer {
9
+ export declare class RivmuxPlayer {
16
10
  /** Original stream URL passed to the constructor. */
17
11
  readonly url: string;
18
- /** Fully normalized options with defaults applied. */
19
- readonly options: NormalizedRivmuxPlayerOptions$1;
20
12
  private readonly id;
21
13
  private readonly events;
22
14
  private readonly workerFactory;
23
15
  private readonly detectRuntime;
16
+ private readonly playback;
24
17
  private workerClient?;
25
- private video?;
26
- private videoStateTimer?;
27
18
  private state;
19
+ private lifecycleGeneration;
20
+ private terminalError?;
21
+ private autoplayWarningEmitted;
22
+ private startPromise?;
23
+ private stopPromise?;
24
+ private destroyPromise?;
28
25
  /**
29
26
  * Creates a player instance for one stream URL.
30
27
  *
31
28
  * The instance does not start network loading until `start()` is called.
32
29
  */
33
- constructor(url: string, options?: RivmuxPlayerOptions$1, internals?: RivmuxPlayerInternals);
30
+ constructor(url: string, options?: RivmuxPlayerOptions$1);
34
31
  /**
35
32
  * Attaches this player to a video element and prepares the worker/MSE pipe.
36
33
  *
@@ -38,11 +35,14 @@ declare class RivmuxPlayer {
38
35
  */
39
36
  attach(video: HTMLVideoElement): Promise<void>;
40
37
  /**
41
- * Starts loading, transmuxing, buffering, and playback control.
38
+ * Waits until the worker has created the transmux core and scheduled stream
39
+ * consumption for this playback session.
42
40
  *
43
- * Requires a successful `attach(video)` call first.
41
+ * This does not wait for media data, `canplay`, or `video.play()`. Requires a
42
+ * successful `attach(video)` call first.
44
43
  */
45
44
  start(): Promise<void>;
45
+ private performStart;
46
46
  /**
47
47
  * Stops loading and detaches the current media source.
48
48
  *
@@ -50,6 +50,7 @@ declare class RivmuxPlayer {
50
50
  * stream after the player has stopped.
51
51
  */
52
52
  stop(): Promise<void>;
53
+ private performStop;
53
54
  /**
54
55
  * Releases worker resources, timers, listeners, and the attached video source.
55
56
  *
@@ -57,6 +58,7 @@ declare class RivmuxPlayer {
57
58
  * again.
58
59
  */
59
60
  destroy(): Promise<void>;
61
+ private performDestroy;
60
62
  /** Registers an event listener for a typed player event. */
61
63
  on<T extends PlayerEventType$1>(type: T, listener: PlayerEventListener$1<T>): void;
62
64
  /** Removes a previously registered event listener. */
@@ -64,21 +66,17 @@ declare class RivmuxPlayer {
64
66
  private ensureWorkerClient;
65
67
  private handleWorkerMessage;
66
68
  private attachMediaSourceHandle;
67
- private applyPlaybackOptions;
68
69
  private startVideoStateReporting;
69
- private stopVideoStateReporting;
70
- private postVideoState;
71
70
  private applyPlaybackControl;
72
- private detachVideoSource;
73
- private assertNotDestroyed;
71
+ private enterFatalErrorState;
72
+ private assertOperational;
73
+ private isLifecycleOperationCurrent;
74
+ private assertStartOperationCurrent;
74
75
  }
75
76
  //#endregion
76
- //#region src/options.d.ts
77
- declare const DEFAULT_RIVMUX_PLAYER_OPTIONS: NormalizedRivmuxPlayerOptions$1;
78
- declare function normalizePlayerOptions(options?: RivmuxPlayerOptions$1): NormalizedRivmuxPlayerOptions$1;
77
+ //#region src/feature-detect.d.ts
78
+ export declare function getCapabilities(): RivmuxCapabilities$1;
79
+ export declare function isSupported(): boolean;
79
80
  //#endregion
80
- //#region src/errors.d.ts
81
- declare function createPlayerError(kind: PlayerErrorKind$1, code: string, message: string, terminal: boolean, cause?: unknown): PlayerError$1;
82
- //#endregion
83
- export { DEFAULT_RIVMUX_PLAYER_OPTIONS, type DiagnosticsOptions, type LatencyOptions, type MediaInfo, type NetworkOptions, type NormalizedRivmuxPlayerOptions, type PlaybackOptions, type PlayerError, type PlayerErrorKind, type PlayerEventListener, type PlayerEventMap, type PlayerEventType, type PlayerStats, type PlayerWarning, RivmuxPlayer, type RivmuxPlayerOptions, type RuntimeOptions, createPlayerError, normalizePlayerOptions };
81
+ export type { DecodingCapabilities, DiagnosticsOptions, LatencyOptions, MediaInfo, NetworkOptions, PlaybackOptions, PlayerError, PlayerErrorCause, PlayerErrorKind, PlayerEventListener, PlayerEventMap, PlayerEventType, PlayerStats, PlayerWarning, ReconnectInfo, ReconnectReason, RecoveryInfo, RivmuxCapabilities, RivmuxPlayerOptions, RuntimeCapabilities, RuntimeOptions, SupportStatus };
84
82
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/player.ts","../src/options.ts","../src/errors.ts"],"mappings":";;;KAmBY;EACV,gBAAgB;EAChB,sBAAsB;EACtB;;;;;;;;cASW;;WAEF;;WAGA,SAAS;mBACD;mBACA;mBACA;mBACA;UACT;UACA;UACA;UACA;;;;;;cAOI,aAAa,UAAU,uBAAqB,YAAW;;;;;;EAa7D,OAAO,OAAO,mBAAmB;;;;;;EAyBjC,SAAS;;;;;;;EA2BT,QAAQ;;;;;;;EAuBR,WAAW;;EA6BjB,GAAG,UAAU,mBAAiB,MAAM,GAAG,UAAU,sBAAoB;;EAKrE,IAAI,UAAU,mBAAiB,MAAM,GAAG,UAAU,sBAAoB;UAI9D;UAaA;UAoCA;UAeA;UAKA;UAUA;UASA;UAoBM;UAkCN;UAYA;;;;cCvUG,+BAA+B;iBA6B5B,uBAAuB,UAAS,wBAA2B;;;iBC/B3D,kBAAkB,MAAM,mBAAiB,cAAc,iBAAiB,mBAAmB,kBAAkB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/player.ts","../src/feature-detect.ts"],"mappings":";;;;;;;;qBAgCa;;WAEF;mBAIQ;mBACA;mBACA;mBACA;mBACA;UACT;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;;;;;EAOI,YAAA,aAAa,UAAU;;;;;;EAkB7B,OAAO,OAAO,mBAAmB;;;;;;;;EA8BvC,SAAS;UAiCK;;;;;;;EA0Bd,QAAQ;UAyBM;;;;;;;EAkCR,WAAW;UAeH;;EA6Bd,GAAG,UAAU,mBAAiB,MAAM,GAAG,UAAU,sBAAoB;;EAKrE,IAAI,UAAU,mBAAiB,MAAM,GAAG,UAAU,sBAAoB;UAI9D;UAgBA;UAmDA;UAiBA;UAcM;UA4BN;UAWA;UAmBA;UAIA;;;;wBCrUM,mBAAmB;wBAInB"}