artplayer-plugin-p2p 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.
@@ -0,0 +1,294 @@
1
+ import { DownloadSource, CoreConfig, DynamicCoreConfig } from 'p2p-media-loader-core';
2
+ import { HlsJsP2PEngine } from 'p2p-media-loader-hlsjs';
3
+ import Hls, { HlsConfig } from 'hls.js';
4
+
5
+ /**
6
+ * 插件公共类型契约
7
+ *
8
+ * 本文件是全项目的类型契约源头:下游模块(引擎 / 编排 / UI)
9
+ * 的签名均以此处定义为准,变更须先同步全部下游再动手
10
+ *
11
+ * @module types
12
+ */
13
+
14
+ /**
15
+ * 信令服务器(Tracker)配置组
16
+ *
17
+ * 用于将 P2P 信令从公共 tracker 切换到自建 wt-tracker 等私有部署,
18
+ * 字段名与 p2p-media-loader 的 CoreConfig 完全一致,浅合并进 core
19
+ */
20
+ interface P2PTrackerOptions {
21
+ /** WebTorrent tracker 地址列表;不配置时沿用 p2p-media-loader 官方默认公共 tracker */
22
+ announceTrackers?: string[];
23
+ /** WebRTC STUN/TURN 配置;自建 ICE 服务时覆盖默认的公共 STUN */
24
+ rtcConfig?: RTCConfiguration;
25
+ }
26
+ /**
27
+ * 设置开关组单项显示配置(未指定的项默认显示)
28
+ */
29
+ interface P2PSettingItemsOptions {
30
+ /** 是否显示「P2P 加速」开关 */
31
+ p2pEnabled?: boolean;
32
+ /** 是否显示「仅上传模式」开关 */
33
+ uploadOnly?: boolean;
34
+ /** 是否显示「P2P 统计」开关(stats 关闭时无面板可开,此项不生效) */
35
+ stats?: boolean;
36
+ }
37
+ interface P2PUIOptions {
38
+ /**
39
+ * 设置开关组显示配置:
40
+ * - true / 省略:三项全显
41
+ * - false:整组不挂载
42
+ * - 对象:按项选择性显示
43
+ */
44
+ setting?: boolean | P2PSettingItemsOptions;
45
+ }
46
+ /** 插件选项 */
47
+ interface P2POptions {
48
+ /** customType 注册的格式名,默认 'm3u8' */
49
+ type?: string;
50
+ /** 信令服务器配置组,与 core 配置浅合并(本组优先) */
51
+ tracker?: P2PTrackerOptions;
52
+ /** 完整 core 配置透传(Partial<CoreConfig>);其中 isP2PDisabled / isP2PUploadDisabled 由插件开关状态接管 */
53
+ core?: Partial<CoreConfig>;
54
+ /** 透传给 hls.js 的配置 */
55
+ hls?: Partial<HlsConfig>;
56
+ /** fatal 错误销毁重建的最大次数,默认 2 */
57
+ fatalRetryMax?: number;
58
+ /** 初始 P2P 开关,默认 true;运行时可经句柄 setP2PEnabled 无损切换 */
59
+ enabled?: boolean;
60
+ /** 初始上传开关,默认 true;运行时可经句柄 setUploadEnabled 无缝切换 */
61
+ uploadEnabled?: boolean;
62
+ /** 统计展示总开关,默认 true;false 时不挂「P2P 统计」菜单项与面板,宿主仅能经 getStats() 编程读取 */
63
+ stats?: boolean;
64
+ /** UI 总闸:false 时完全无 UI(不挂菜单项 / 面板 / 设置开关组);对象形式可单独控制设置开关组 */
65
+ ui?: boolean | P2PUIOptions;
66
+ }
67
+ /** P2P 运行时统计快照(一次性读取全部累计量与派生指标) */
68
+ interface P2PStats {
69
+ /** 当前已连接的 peer 数量 */
70
+ peers: number;
71
+ /** 会话内出现过的峰值 peer 数量 */
72
+ peakPeers: number;
73
+ /** 累计 P2P 通道下行字节数 */
74
+ p2pDownloadedBytes: number;
75
+ /** 累计 HTTP 通道下行字节数 */
76
+ httpDownloadedBytes: number;
77
+ /** 累计 P2P 上行字节数 */
78
+ uploadedBytes: number;
79
+ /** 累计总下行字节数(P2P + HTTP) */
80
+ totalDownloadedBytes: number;
81
+ /** P2P 下行占总下行比例 0..1(总下行为 0 时为 0) */
82
+ p2pDownloadRatio: number;
83
+ /** 总下行速率 B/s(滑动时间窗) */
84
+ downloadSpeed: number;
85
+ /** P2P 通道下行速率 B/s(滑动时间窗) */
86
+ p2pDownloadSpeed: number;
87
+ /** P2P 上行速率 B/s(滑动时间窗) */
88
+ uploadSpeed: number;
89
+ }
90
+ /** `p2p:stateChange` 事件负载:开关切换后派发,供宿主同步自定义 UI */
91
+ interface StateChangeDetails {
92
+ /** 当前 P2P 开关状态 */
93
+ p2pEnabled: boolean;
94
+ /** 当前上传开关状态 */
95
+ uploadEnabled: boolean;
96
+ }
97
+ /** 挂载在 art.plugins.artplayerPluginP2P 上的插件句柄 */
98
+ interface P2PPluginHandle {
99
+ /** 插件名(ArtPlayer 以此作为挂载键) */
100
+ name: 'artplayerPluginP2P';
101
+ /** 当前 P2P 引擎实例(无活跃播放实例时为 undefined) */
102
+ readonly engine?: HlsJsP2PEngine;
103
+ /** 当前播放实例(与 art.hls 槽位同步) */
104
+ readonly hls?: Hls;
105
+ /** 销毁当前播放实例 */
106
+ destroy(): void;
107
+ /** 销毁现有实例后按当前 URL 重建 */
108
+ reload(): void;
109
+ /** 获取 P2P 运行时统计快照 */
110
+ getStats(): P2PStats;
111
+ /** P2P 运行时开关:经 applyDynamicConfig 无损切换,不销毁实例、不中断播放 */
112
+ setP2PEnabled(enabled: boolean): void;
113
+ /** 当前 P2P 是否处于启用状态 */
114
+ isP2PEnabled(): boolean;
115
+ /** 上行运行时开关:仅信令广播,完全无缝 */
116
+ setUploadEnabled(enabled: boolean): void;
117
+ /** 当前上传是否处于启用状态 */
118
+ isUploadEnabled(): boolean;
119
+ /** 运行时动态配置透传(DynamicCoreConfig;swarmId 等静态属性由 p2pml 内建防篡改) */
120
+ applyDynamicConfig(patch: DynamicCoreConfig): void;
121
+ }
122
+ /** 下载通道类型(别名自 p2p-media-loader 的 DownloadSource,随上游保持同步) */
123
+ type DownloadChannel = DownloadSource;
124
+ /**
125
+ * 内部使用:解析默认值后的插件选项
126
+ *
127
+ * 由入口层从 P2POptions 归一化生成,供引擎与编排层直接消费;
128
+ * 不对外发布,避免将内部归一化形态固化为公共 API
129
+ */
130
+ interface ResolvedOptions {
131
+ /** customType 注册的格式名(已含默认值) */
132
+ typeName: string;
133
+ /** fatal 销毁重建的最大次数(已含默认值) */
134
+ fatalRetryMax: number;
135
+ /** 初始 P2P 开关(已含默认值) */
136
+ p2pEnabled: boolean;
137
+ /** 初始上传开关(已含默认值) */
138
+ uploadEnabled: boolean;
139
+ /** UI 总闸(ui !== false) */
140
+ uiEnabled: boolean;
141
+ /** 统计展示开关(uiEnabled 且 stats !== false) */
142
+ statsEnabled: boolean;
143
+ /** 设置开关组挂载开关(uiEnabled 且对象形式 setting !== false) */
144
+ settingEnabled: boolean;
145
+ /** 设置开关组单项显示配置(已含默认值) */
146
+ settingItems: P2PSettingItemsOptions;
147
+ /** 原始透传的 core / tracker / hls 配置 */
148
+ core?: Partial<CoreConfig>;
149
+ tracker?: P2PTrackerOptions;
150
+ hls?: Partial<HlsConfig>;
151
+ }
152
+
153
+ /**
154
+ * 插件常量定义
155
+ *
156
+ * @module constants
157
+ */
158
+ /** customType 注册的默认格式名 */
159
+ declare const DEFAULT_TYPE = "m3u8";
160
+ /** fatal 错误销毁重建的默认最大次数 */
161
+ declare const DEFAULT_FATAL_RETRY_MAX = 2;
162
+ /**
163
+ * 统计带宽计算的滑动时间窗长度(毫秒)
164
+ *
165
+ * 直播切片通常 2-6s,10 秒窗口可平滑速率抖动
166
+ */
167
+ declare const BANDWIDTH_WINDOW_MS = 10000;
168
+ /** P2P 面板打开期间的轮询刷新周期(毫秒),与 ArtPlayer 的 INFO_LOOP_TIME 对齐 */
169
+ declare const STATS_POLLING_MS = 1000;
170
+ /**
171
+ * Core 事件到 ArtPlayer 自定义事件的映射表
172
+ *
173
+ * 键集合与 p2p-media-loader 的 CoreEventMap 完全一致,
174
+ * 通过 satisfies 做编译期穷尽性检查:Core 新增事件或本表遗漏/多余键时
175
+ * 构建直接失败,保证事件桥不丢失任何事件
176
+ */
177
+ declare const P2P_EVENT_BRIDGE_MAP: {
178
+ readonly onStreamAdded: "p2p:streamAdded";
179
+ readonly onStreamRegistrationError: "p2p:streamRegistrationError";
180
+ readonly onSegmentLoaded: "p2p:segmentLoaded";
181
+ readonly onSegmentError: "p2p:segmentError";
182
+ readonly onSegmentAbort: "p2p:segmentAbort";
183
+ readonly onSegmentStart: "p2p:segmentStart";
184
+ readonly onPeerConnect: "p2p:peerConnect";
185
+ readonly onPeerConnectError: "p2p:peerConnectError";
186
+ readonly onPeerClose: "p2p:peerClose";
187
+ readonly onPeerError: "p2p:peerError";
188
+ readonly onPeerWarning: "p2p:peerWarning";
189
+ readonly onChunkDownloaded: "p2p:chunkDownloaded";
190
+ readonly onChunkUploaded: "p2p:chunkUploaded";
191
+ readonly onTrackerError: "p2p:trackerError";
192
+ readonly onTrackerWarning: "p2p:trackerWarning";
193
+ };
194
+
195
+ /**
196
+ * 插件配置解析与合并逻辑
197
+ *
198
+ * 独立于引擎模块的纯函数集合,可在 Node 环境直接测试:
199
+ * - resolveOptions:归一化插件选项(默认值合并、stats/ui 降级兼容)
200
+ * - mergeCoreConfig:合并 core 配置与 tracker 快捷配置组
201
+ * - applyRuntimeToggle:将插件运行时开关状态注入 core 配置
202
+ *
203
+ * @module config
204
+ */
205
+
206
+ /**
207
+ * 解析插件选项:填充默认值并归一化 stats / ui 开关
208
+ *
209
+ * 仅做归一化,不修改任何透传配置的内容;
210
+ * core / tracker / hls 原样保留给引擎层合并
211
+ *
212
+ * @param options - 用户传入的插件选项
213
+ * @returns 下游模块可直接消费的解析后选项
214
+ */
215
+ declare function resolveOptions(options: P2POptions): ResolvedOptions;
216
+ /**
217
+ * 合并 core 配置与 tracker 快捷配置组
218
+ *
219
+ * tracker 组字段与 CoreConfig 同名,浅合并且优先级高于 core;
220
+ * 两组皆未配置时返回空对象,保持 p2p-media-loader 官方默认行为
221
+ *
222
+ * @param options - 含 core / tracker 配置的选项(结构化子集即可)
223
+ * @returns 传给 HlsJsP2PEngine 的 core 配置
224
+ */
225
+ declare function mergeCoreConfig(options: Pick<P2POptions, 'core' | 'tracker'>): Partial<CoreConfig>;
226
+ /**
227
+ * 将插件运行时开关状态注入 core 配置
228
+ *
229
+ * isP2PDisabled / isP2PUploadDisabled 由插件开关状态接管
230
+ * (最高优先级):保证 fatal 重建、换源、重连后重建的实例
231
+ * 携带与用户当前选择一致的模式,不因重建而静默丢失开关状态;
232
+ * 宿主表达初始意图应使用 enabled / uploadEnabled 选项
233
+ *
234
+ * @param config - mergeCoreConfig 合并后的 core 配置
235
+ * @param p2pEnabled - 当前 P2P 开关状态
236
+ * @param uploadEnabled - 当前上传开关状态
237
+ * @returns 注入开关状态后的 core 配置
238
+ */
239
+ declare function applyRuntimeToggle(config: Partial<CoreConfig>, p2pEnabled: boolean, uploadEnabled: boolean): Partial<CoreConfig>;
240
+
241
+ /**
242
+ * P2P 统计引擎
243
+ *
244
+ * 累加器 + 三个带宽通道(P2P 下行 / HTTP 下行 / 上行)+ 派生指标;
245
+ * 由事件桥喂点,对外提供快照读取与重置。
246
+ * 纯逻辑实现:不触碰任何播放器与引擎状态,Node 可直接单测
247
+ *
248
+ * @module stats
249
+ */
250
+
251
+ /** P2P 统计引擎 */
252
+ declare class P2PStatsEngine {
253
+ #private;
254
+ /** 记录一个 peer 连接建立(同时维护峰值) */
255
+ recordPeerConnect(): void;
256
+ /** 记录一个 peer 连接断开(计数不小于零) */
257
+ recordPeerClose(): void;
258
+ /**
259
+ * 记录一笔下行字节
260
+ *
261
+ * @param bytes - 字节数
262
+ * @param channel - 下载通道(http / p2p)
263
+ * @param timestampMs - 样本时间戳;缺省取 performance.now(),测试可注入固定时间
264
+ */
265
+ recordDownload(bytes: number, channel: DownloadChannel, timestampMs?: number): void;
266
+ /**
267
+ * 记录一笔 P2P 上行字节
268
+ *
269
+ * @param bytes - 字节数
270
+ * @param timestampMs - 样本时间戳;缺省取 performance.now(),测试可注入固定时间
271
+ */
272
+ recordUpload(bytes: number, timestampMs?: number): void;
273
+ /**
274
+ * 输出当前统计快照(累计量 + 派生指标一次算清)
275
+ *
276
+ * 带宽基准时间只取一次、每通道只计算一次,
277
+ * 保证快照内部指标自洽(downloadSpeed 恒等于两通道之和)
278
+ *
279
+ * @param nowMs - 带宽计算基准时间戳;缺省取 performance.now(),测试可注入固定时间
280
+ */
281
+ snapshot(nowMs?: number): P2PStats;
282
+ /**
283
+ * 清零当前 peer 计数
284
+ *
285
+ * 动态关闭 P2P 或销毁播放实例后连接已全部断开(引擎销毁不保证
286
+ * 逐个发出 onPeerClose),主动清零防止残留计数污染下一次快照;
287
+ * 峰值与字节累计保留
288
+ */
289
+ resetPeers(): void;
290
+ /** 重置全部计数与样本(换源时调用) */
291
+ reset(): void;
292
+ }
293
+
294
+ export { BANDWIDTH_WINDOW_MS as B, DEFAULT_FATAL_RETRY_MAX as D, type P2POptions as P, type ResolvedOptions as R, STATS_POLLING_MS as S, P2PStatsEngine as a, type P2PPluginHandle as b, DEFAULT_TYPE as c, type DownloadChannel as d, type P2PSettingItemsOptions as e, type P2PStats as f, type P2PTrackerOptions as g, type P2PUIOptions as h, P2P_EVENT_BRIDGE_MAP as i, type StateChangeDetails as j, applyRuntimeToggle as k, mergeCoreConfig as m, resolveOptions as r };
@@ -0,0 +1,294 @@
1
+ import { DownloadSource, CoreConfig, DynamicCoreConfig } from 'p2p-media-loader-core';
2
+ import { HlsJsP2PEngine } from 'p2p-media-loader-hlsjs';
3
+ import Hls, { HlsConfig } from 'hls.js';
4
+
5
+ /**
6
+ * 插件公共类型契约
7
+ *
8
+ * 本文件是全项目的类型契约源头:下游模块(引擎 / 编排 / UI)
9
+ * 的签名均以此处定义为准,变更须先同步全部下游再动手
10
+ *
11
+ * @module types
12
+ */
13
+
14
+ /**
15
+ * 信令服务器(Tracker)配置组
16
+ *
17
+ * 用于将 P2P 信令从公共 tracker 切换到自建 wt-tracker 等私有部署,
18
+ * 字段名与 p2p-media-loader 的 CoreConfig 完全一致,浅合并进 core
19
+ */
20
+ interface P2PTrackerOptions {
21
+ /** WebTorrent tracker 地址列表;不配置时沿用 p2p-media-loader 官方默认公共 tracker */
22
+ announceTrackers?: string[];
23
+ /** WebRTC STUN/TURN 配置;自建 ICE 服务时覆盖默认的公共 STUN */
24
+ rtcConfig?: RTCConfiguration;
25
+ }
26
+ /**
27
+ * 设置开关组单项显示配置(未指定的项默认显示)
28
+ */
29
+ interface P2PSettingItemsOptions {
30
+ /** 是否显示「P2P 加速」开关 */
31
+ p2pEnabled?: boolean;
32
+ /** 是否显示「仅上传模式」开关 */
33
+ uploadOnly?: boolean;
34
+ /** 是否显示「P2P 统计」开关(stats 关闭时无面板可开,此项不生效) */
35
+ stats?: boolean;
36
+ }
37
+ interface P2PUIOptions {
38
+ /**
39
+ * 设置开关组显示配置:
40
+ * - true / 省略:三项全显
41
+ * - false:整组不挂载
42
+ * - 对象:按项选择性显示
43
+ */
44
+ setting?: boolean | P2PSettingItemsOptions;
45
+ }
46
+ /** 插件选项 */
47
+ interface P2POptions {
48
+ /** customType 注册的格式名,默认 'm3u8' */
49
+ type?: string;
50
+ /** 信令服务器配置组,与 core 配置浅合并(本组优先) */
51
+ tracker?: P2PTrackerOptions;
52
+ /** 完整 core 配置透传(Partial<CoreConfig>);其中 isP2PDisabled / isP2PUploadDisabled 由插件开关状态接管 */
53
+ core?: Partial<CoreConfig>;
54
+ /** 透传给 hls.js 的配置 */
55
+ hls?: Partial<HlsConfig>;
56
+ /** fatal 错误销毁重建的最大次数,默认 2 */
57
+ fatalRetryMax?: number;
58
+ /** 初始 P2P 开关,默认 true;运行时可经句柄 setP2PEnabled 无损切换 */
59
+ enabled?: boolean;
60
+ /** 初始上传开关,默认 true;运行时可经句柄 setUploadEnabled 无缝切换 */
61
+ uploadEnabled?: boolean;
62
+ /** 统计展示总开关,默认 true;false 时不挂「P2P 统计」菜单项与面板,宿主仅能经 getStats() 编程读取 */
63
+ stats?: boolean;
64
+ /** UI 总闸:false 时完全无 UI(不挂菜单项 / 面板 / 设置开关组);对象形式可单独控制设置开关组 */
65
+ ui?: boolean | P2PUIOptions;
66
+ }
67
+ /** P2P 运行时统计快照(一次性读取全部累计量与派生指标) */
68
+ interface P2PStats {
69
+ /** 当前已连接的 peer 数量 */
70
+ peers: number;
71
+ /** 会话内出现过的峰值 peer 数量 */
72
+ peakPeers: number;
73
+ /** 累计 P2P 通道下行字节数 */
74
+ p2pDownloadedBytes: number;
75
+ /** 累计 HTTP 通道下行字节数 */
76
+ httpDownloadedBytes: number;
77
+ /** 累计 P2P 上行字节数 */
78
+ uploadedBytes: number;
79
+ /** 累计总下行字节数(P2P + HTTP) */
80
+ totalDownloadedBytes: number;
81
+ /** P2P 下行占总下行比例 0..1(总下行为 0 时为 0) */
82
+ p2pDownloadRatio: number;
83
+ /** 总下行速率 B/s(滑动时间窗) */
84
+ downloadSpeed: number;
85
+ /** P2P 通道下行速率 B/s(滑动时间窗) */
86
+ p2pDownloadSpeed: number;
87
+ /** P2P 上行速率 B/s(滑动时间窗) */
88
+ uploadSpeed: number;
89
+ }
90
+ /** `p2p:stateChange` 事件负载:开关切换后派发,供宿主同步自定义 UI */
91
+ interface StateChangeDetails {
92
+ /** 当前 P2P 开关状态 */
93
+ p2pEnabled: boolean;
94
+ /** 当前上传开关状态 */
95
+ uploadEnabled: boolean;
96
+ }
97
+ /** 挂载在 art.plugins.artplayerPluginP2P 上的插件句柄 */
98
+ interface P2PPluginHandle {
99
+ /** 插件名(ArtPlayer 以此作为挂载键) */
100
+ name: 'artplayerPluginP2P';
101
+ /** 当前 P2P 引擎实例(无活跃播放实例时为 undefined) */
102
+ readonly engine?: HlsJsP2PEngine;
103
+ /** 当前播放实例(与 art.hls 槽位同步) */
104
+ readonly hls?: Hls;
105
+ /** 销毁当前播放实例 */
106
+ destroy(): void;
107
+ /** 销毁现有实例后按当前 URL 重建 */
108
+ reload(): void;
109
+ /** 获取 P2P 运行时统计快照 */
110
+ getStats(): P2PStats;
111
+ /** P2P 运行时开关:经 applyDynamicConfig 无损切换,不销毁实例、不中断播放 */
112
+ setP2PEnabled(enabled: boolean): void;
113
+ /** 当前 P2P 是否处于启用状态 */
114
+ isP2PEnabled(): boolean;
115
+ /** 上行运行时开关:仅信令广播,完全无缝 */
116
+ setUploadEnabled(enabled: boolean): void;
117
+ /** 当前上传是否处于启用状态 */
118
+ isUploadEnabled(): boolean;
119
+ /** 运行时动态配置透传(DynamicCoreConfig;swarmId 等静态属性由 p2pml 内建防篡改) */
120
+ applyDynamicConfig(patch: DynamicCoreConfig): void;
121
+ }
122
+ /** 下载通道类型(别名自 p2p-media-loader 的 DownloadSource,随上游保持同步) */
123
+ type DownloadChannel = DownloadSource;
124
+ /**
125
+ * 内部使用:解析默认值后的插件选项
126
+ *
127
+ * 由入口层从 P2POptions 归一化生成,供引擎与编排层直接消费;
128
+ * 不对外发布,避免将内部归一化形态固化为公共 API
129
+ */
130
+ interface ResolvedOptions {
131
+ /** customType 注册的格式名(已含默认值) */
132
+ typeName: string;
133
+ /** fatal 销毁重建的最大次数(已含默认值) */
134
+ fatalRetryMax: number;
135
+ /** 初始 P2P 开关(已含默认值) */
136
+ p2pEnabled: boolean;
137
+ /** 初始上传开关(已含默认值) */
138
+ uploadEnabled: boolean;
139
+ /** UI 总闸(ui !== false) */
140
+ uiEnabled: boolean;
141
+ /** 统计展示开关(uiEnabled 且 stats !== false) */
142
+ statsEnabled: boolean;
143
+ /** 设置开关组挂载开关(uiEnabled 且对象形式 setting !== false) */
144
+ settingEnabled: boolean;
145
+ /** 设置开关组单项显示配置(已含默认值) */
146
+ settingItems: P2PSettingItemsOptions;
147
+ /** 原始透传的 core / tracker / hls 配置 */
148
+ core?: Partial<CoreConfig>;
149
+ tracker?: P2PTrackerOptions;
150
+ hls?: Partial<HlsConfig>;
151
+ }
152
+
153
+ /**
154
+ * 插件常量定义
155
+ *
156
+ * @module constants
157
+ */
158
+ /** customType 注册的默认格式名 */
159
+ declare const DEFAULT_TYPE = "m3u8";
160
+ /** fatal 错误销毁重建的默认最大次数 */
161
+ declare const DEFAULT_FATAL_RETRY_MAX = 2;
162
+ /**
163
+ * 统计带宽计算的滑动时间窗长度(毫秒)
164
+ *
165
+ * 直播切片通常 2-6s,10 秒窗口可平滑速率抖动
166
+ */
167
+ declare const BANDWIDTH_WINDOW_MS = 10000;
168
+ /** P2P 面板打开期间的轮询刷新周期(毫秒),与 ArtPlayer 的 INFO_LOOP_TIME 对齐 */
169
+ declare const STATS_POLLING_MS = 1000;
170
+ /**
171
+ * Core 事件到 ArtPlayer 自定义事件的映射表
172
+ *
173
+ * 键集合与 p2p-media-loader 的 CoreEventMap 完全一致,
174
+ * 通过 satisfies 做编译期穷尽性检查:Core 新增事件或本表遗漏/多余键时
175
+ * 构建直接失败,保证事件桥不丢失任何事件
176
+ */
177
+ declare const P2P_EVENT_BRIDGE_MAP: {
178
+ readonly onStreamAdded: "p2p:streamAdded";
179
+ readonly onStreamRegistrationError: "p2p:streamRegistrationError";
180
+ readonly onSegmentLoaded: "p2p:segmentLoaded";
181
+ readonly onSegmentError: "p2p:segmentError";
182
+ readonly onSegmentAbort: "p2p:segmentAbort";
183
+ readonly onSegmentStart: "p2p:segmentStart";
184
+ readonly onPeerConnect: "p2p:peerConnect";
185
+ readonly onPeerConnectError: "p2p:peerConnectError";
186
+ readonly onPeerClose: "p2p:peerClose";
187
+ readonly onPeerError: "p2p:peerError";
188
+ readonly onPeerWarning: "p2p:peerWarning";
189
+ readonly onChunkDownloaded: "p2p:chunkDownloaded";
190
+ readonly onChunkUploaded: "p2p:chunkUploaded";
191
+ readonly onTrackerError: "p2p:trackerError";
192
+ readonly onTrackerWarning: "p2p:trackerWarning";
193
+ };
194
+
195
+ /**
196
+ * 插件配置解析与合并逻辑
197
+ *
198
+ * 独立于引擎模块的纯函数集合,可在 Node 环境直接测试:
199
+ * - resolveOptions:归一化插件选项(默认值合并、stats/ui 降级兼容)
200
+ * - mergeCoreConfig:合并 core 配置与 tracker 快捷配置组
201
+ * - applyRuntimeToggle:将插件运行时开关状态注入 core 配置
202
+ *
203
+ * @module config
204
+ */
205
+
206
+ /**
207
+ * 解析插件选项:填充默认值并归一化 stats / ui 开关
208
+ *
209
+ * 仅做归一化,不修改任何透传配置的内容;
210
+ * core / tracker / hls 原样保留给引擎层合并
211
+ *
212
+ * @param options - 用户传入的插件选项
213
+ * @returns 下游模块可直接消费的解析后选项
214
+ */
215
+ declare function resolveOptions(options: P2POptions): ResolvedOptions;
216
+ /**
217
+ * 合并 core 配置与 tracker 快捷配置组
218
+ *
219
+ * tracker 组字段与 CoreConfig 同名,浅合并且优先级高于 core;
220
+ * 两组皆未配置时返回空对象,保持 p2p-media-loader 官方默认行为
221
+ *
222
+ * @param options - 含 core / tracker 配置的选项(结构化子集即可)
223
+ * @returns 传给 HlsJsP2PEngine 的 core 配置
224
+ */
225
+ declare function mergeCoreConfig(options: Pick<P2POptions, 'core' | 'tracker'>): Partial<CoreConfig>;
226
+ /**
227
+ * 将插件运行时开关状态注入 core 配置
228
+ *
229
+ * isP2PDisabled / isP2PUploadDisabled 由插件开关状态接管
230
+ * (最高优先级):保证 fatal 重建、换源、重连后重建的实例
231
+ * 携带与用户当前选择一致的模式,不因重建而静默丢失开关状态;
232
+ * 宿主表达初始意图应使用 enabled / uploadEnabled 选项
233
+ *
234
+ * @param config - mergeCoreConfig 合并后的 core 配置
235
+ * @param p2pEnabled - 当前 P2P 开关状态
236
+ * @param uploadEnabled - 当前上传开关状态
237
+ * @returns 注入开关状态后的 core 配置
238
+ */
239
+ declare function applyRuntimeToggle(config: Partial<CoreConfig>, p2pEnabled: boolean, uploadEnabled: boolean): Partial<CoreConfig>;
240
+
241
+ /**
242
+ * P2P 统计引擎
243
+ *
244
+ * 累加器 + 三个带宽通道(P2P 下行 / HTTP 下行 / 上行)+ 派生指标;
245
+ * 由事件桥喂点,对外提供快照读取与重置。
246
+ * 纯逻辑实现:不触碰任何播放器与引擎状态,Node 可直接单测
247
+ *
248
+ * @module stats
249
+ */
250
+
251
+ /** P2P 统计引擎 */
252
+ declare class P2PStatsEngine {
253
+ #private;
254
+ /** 记录一个 peer 连接建立(同时维护峰值) */
255
+ recordPeerConnect(): void;
256
+ /** 记录一个 peer 连接断开(计数不小于零) */
257
+ recordPeerClose(): void;
258
+ /**
259
+ * 记录一笔下行字节
260
+ *
261
+ * @param bytes - 字节数
262
+ * @param channel - 下载通道(http / p2p)
263
+ * @param timestampMs - 样本时间戳;缺省取 performance.now(),测试可注入固定时间
264
+ */
265
+ recordDownload(bytes: number, channel: DownloadChannel, timestampMs?: number): void;
266
+ /**
267
+ * 记录一笔 P2P 上行字节
268
+ *
269
+ * @param bytes - 字节数
270
+ * @param timestampMs - 样本时间戳;缺省取 performance.now(),测试可注入固定时间
271
+ */
272
+ recordUpload(bytes: number, timestampMs?: number): void;
273
+ /**
274
+ * 输出当前统计快照(累计量 + 派生指标一次算清)
275
+ *
276
+ * 带宽基准时间只取一次、每通道只计算一次,
277
+ * 保证快照内部指标自洽(downloadSpeed 恒等于两通道之和)
278
+ *
279
+ * @param nowMs - 带宽计算基准时间戳;缺省取 performance.now(),测试可注入固定时间
280
+ */
281
+ snapshot(nowMs?: number): P2PStats;
282
+ /**
283
+ * 清零当前 peer 计数
284
+ *
285
+ * 动态关闭 P2P 或销毁播放实例后连接已全部断开(引擎销毁不保证
286
+ * 逐个发出 onPeerClose),主动清零防止残留计数污染下一次快照;
287
+ * 峰值与字节累计保留
288
+ */
289
+ resetPeers(): void;
290
+ /** 重置全部计数与样本(换源时调用) */
291
+ reset(): void;
292
+ }
293
+
294
+ export { BANDWIDTH_WINDOW_MS as B, DEFAULT_FATAL_RETRY_MAX as D, type P2POptions as P, type ResolvedOptions as R, STATS_POLLING_MS as S, P2PStatsEngine as a, type P2PPluginHandle as b, DEFAULT_TYPE as c, type DownloadChannel as d, type P2PSettingItemsOptions as e, type P2PStats as f, type P2PTrackerOptions as g, type P2PUIOptions as h, P2P_EVENT_BRIDGE_MAP as i, type StateChangeDetails as j, applyRuntimeToggle as k, mergeCoreConfig as m, resolveOptions as r };
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "artplayer-plugin-p2p",
3
+ "version": "1.0.0",
4
+ "description": "P2P media streaming plugin for ArtPlayer, powered by p2p-media-loader (hls.js engine)",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "iuk-ink"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/iuk-ink/artplayer-plugin-p2p.git"
12
+ },
13
+ "homepage": "https://github.com/iuk-ink/artplayer-plugin-p2p#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/iuk-ink/artplayer-plugin-p2p/issues"
16
+ },
17
+ "sideEffects": false,
18
+ "exports": {
19
+ ".": {
20
+ "types": {
21
+ "import": "./dist/index.d.mts",
22
+ "require": "./dist/index.d.ts"
23
+ },
24
+ "import": "./dist/index.mjs",
25
+ "require": "./dist/index.js"
26
+ },
27
+ "./pure": {
28
+ "types": {
29
+ "import": "./dist/pure.d.mts",
30
+ "require": "./dist/pure.d.ts"
31
+ },
32
+ "import": "./dist/pure.mjs",
33
+ "require": "./dist/pure.js"
34
+ }
35
+ },
36
+ "main": "./dist/index.js",
37
+ "module": "./dist/index.mjs",
38
+ "types": "./dist/index.d.ts",
39
+ "unpkg": "./dist/artplayer-plugin-p2p.iife.js",
40
+ "jsdelivr": "./dist/artplayer-plugin-p2p.iife.js",
41
+ "files": [
42
+ "dist"
43
+ ],
44
+ "scripts": {
45
+ "build": "tsup",
46
+ "typecheck": "tsc --noEmit",
47
+ "test": "node scripts/test-plugin.mjs",
48
+ "test:pure": "node scripts/test-pure.mjs",
49
+ "smoke:dist": "node --conditions=p2pml:core-as-bundle scripts/smoke-dist.mjs",
50
+ "prepublishOnly": "npm run typecheck && npm run build && npm test"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "engines": {
56
+ "node": ">=20"
57
+ },
58
+ "dependencies": {
59
+ "p2p-media-loader-core": "^4.0.0",
60
+ "p2p-media-loader-hlsjs": "^4.0.0"
61
+ },
62
+ "peerDependencies": {
63
+ "artplayer": ">=5.0.0",
64
+ "hls.js": "^1.7.0"
65
+ },
66
+ "devDependencies": {
67
+ "@types/node": "^26.4.1",
68
+ "artplayer": "^5.4.0",
69
+ "hls.js": "^1.7.2",
70
+ "tsup": "^8.5.1",
71
+ "typescript": "^5.9.3"
72
+ },
73
+ "keywords": [
74
+ "artplayer",
75
+ "p2p",
76
+ "p2p-media-loader",
77
+ "hls",
78
+ "hls.js",
79
+ "webrtc",
80
+ "video",
81
+ "player",
82
+ "plugin"
83
+ ]
84
+ }