@video-lab/protocol 1.0.0
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/LICENSE +21 -0
- package/README.md +80 -0
- package/dist/index.cjs +1909 -0
- package/dist/index.d.cts +11090 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +11090 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1849 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Video Lab Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# @video-lab/protocol
|
|
2
|
+
|
|
3
|
+
Video Lab Player 的契约层(L4)。定义 host ↔ iframe 的通信契约,**所有其他包依赖它,它不依赖任何内部包**。
|
|
4
|
+
|
|
5
|
+
唯一外部依赖:`zod`。
|
|
6
|
+
|
|
7
|
+
## 它定义什么
|
|
8
|
+
|
|
9
|
+
| 模块 | 内容 |
|
|
10
|
+
|:---|:---|
|
|
11
|
+
| `version` | `CONTRACT_VERSION` + 版本兼容判定 |
|
|
12
|
+
| `envelope` | 通信包裹:`command` / `event` / `response` / `error` |
|
|
13
|
+
| `methods` | 16 条命令(play / pause / seek / load / setSubtitle / pushDanmaku / …) |
|
|
14
|
+
| `events` | 29 个事件(sourceroute / ready / timeupdate / error / reconnectstart / subtitlechange / stalled / …) |
|
|
15
|
+
| `errors` | 29 个错误码 + 2 个警告码 + `PlayerError` |
|
|
16
|
+
| `configs` | `MediaSource`、`PlayerConfig`、poster / locale / danmaku / controls |
|
|
17
|
+
| `presets` | 1 个场景预设(`homepage-preview`,ADR-032)+ `resolvePreset` |
|
|
18
|
+
|
|
19
|
+
类型一律从 Zod schema 用 `z.infer` 推导,不手写 interface——避免 schema 和类型变成两套真相。
|
|
20
|
+
|
|
21
|
+
## 用法
|
|
22
|
+
|
|
23
|
+
<!-- doc-snippet-preamble
|
|
24
|
+
declare const rawMessage: unknown
|
|
25
|
+
declare const originalError: unknown
|
|
26
|
+
-->
|
|
27
|
+
```ts
|
|
28
|
+
import {
|
|
29
|
+
CommandSchema,
|
|
30
|
+
EnvelopeSchema,
|
|
31
|
+
eventEnvelope,
|
|
32
|
+
makePlayerError,
|
|
33
|
+
resolvePreset,
|
|
34
|
+
} from '@video-lab/protocol'
|
|
35
|
+
|
|
36
|
+
// 收到消息:先 parse,再按 type 分支(TS 会自动收窄 payload)
|
|
37
|
+
const envelope = EnvelopeSchema.parse(rawMessage)
|
|
38
|
+
if (envelope.type === 'event' && envelope.payload.event === 'timeupdate') {
|
|
39
|
+
console.log(envelope.payload.payload.time)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 构造错误:category / retryable 从 ERROR_META 推出,不接受调用方伪造
|
|
43
|
+
const err = makePlayerError('E_NETWORK', '拉流失败', originalError)
|
|
44
|
+
|
|
45
|
+
// 应用预设:显式传的字段永远覆盖预设默认值
|
|
46
|
+
const config = resolvePreset('homepage-preview', { source: 'a.m3u8', autoplay: false })
|
|
47
|
+
// → autoplay: false(显式值赢),muted: true(来自预设)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 几个容易踩的点
|
|
51
|
+
|
|
52
|
+
**事件名是全小写连写**(`timeupdate` / `autoplayblocked`),对齐 HTML5 媒体事件。这是 wire 上的名字;消费面各自映射——Vue emit `time-update`,React prop `onTimeUpdate`。(团队约定里的 `snake.case` 指埋点事件名如 `playback.start`,是另一套命名空间。)
|
|
53
|
+
|
|
54
|
+
**`retryable` 是给自动重连看的信号**,不是"用户能不能点重试按钮"。判断标准是:同样的请求原样再发一次,有没有可能得到不同结果。所以 `E_AUTH_EXPIRED` 是 `false`——SDK 不做签名刷新(ADR-022),原样重试必然再次失败。
|
|
55
|
+
|
|
56
|
+
**`source.onBeforeRequest` 不在 wire 契约里**。函数不可序列化,过不了 iframe 边界;它是宿主侧的 hook,由 inline 模式的 player-core 直接消费。且它在 MP4 和 iOS Safari 播 HLS 时**不生效**。
|
|
57
|
+
|
|
58
|
+
**带 query 的 URL 推断不出类型**。`video.m3u8?token=xxx` 必须显式传 `type: 'hls'`,否则会走 MP4 路径。签名 URL 场景尤其注意。
|
|
59
|
+
|
|
60
|
+
**`type DrmConfig = never`**(ADR-014)。v1.0 不做 DRM,消费方传 drm 字段会直接编译报错,而不是运行时才发现没生效。
|
|
61
|
+
|
|
62
|
+
## 版本与冻结
|
|
63
|
+
|
|
64
|
+
当前 `CONTRACT_VERSION = '1.0.0'` —— **契约已冻结**(2026-07-15,见 ADR-025)。现有 schema 不再破坏兼容。
|
|
65
|
+
|
|
66
|
+
兼容规则(host 和 iframe 用同一个 `isContractCompatible`):
|
|
67
|
+
|
|
68
|
+
- `0.x` 阶段(已过):minor 变更即破坏性 → minor 必须相同
|
|
69
|
+
- `>= 1.0.0`(当前):minor 是向后兼容的新增 → **major 相同即兼容**
|
|
70
|
+
- patch 差异永远兼容
|
|
71
|
+
|
|
72
|
+
冻结后:新增 method / event / 可选字段走 **minor** bump(1.x 向后兼容);破坏兼容必须走 **ADR + major** bump。
|
|
73
|
+
|
|
74
|
+
## 测试
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pnpm --filter @video-lab/protocol test
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
契约测试在 `tests/`(和 `src/` 分开,方便冻结后独立管理)。其中 `consumer-parity.contract.test.ts` 拿 `examples/team-video-vue/` 实际用到的事件 / 命令 / 错误码逐个校验——契约一旦漂移到验收基准用不了,它会先红。
|