@video-lab/react-frame 4.0.0 → 4.1.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/README.md +1 -0
- package/dist/index.cjs +11 -3
- package/dist/index.d.cts +0 -1
- package/dist/index.d.mts +0 -1
- package/dist/index.mjs +11 -4
- package/package.json +4 -4
- package/skills/host-integration/SKILL.md +2 -2
package/README.md
CHANGED
|
@@ -121,6 +121,7 @@ MIT
|
|
|
121
121
|
## 完整事件与命令失败
|
|
122
122
|
|
|
123
123
|
`onPlayerEvent` 交付完整 `PlayerEvent`,其顶层 `delivery` 包含生产端排序、去重与迟到事件证据。
|
|
124
|
+
`PlayerEvent` 用 `event` 字段区分类型(如 `e.event === 'ready'`),数据在 `payload`;它没有 `type` 字段。
|
|
124
125
|
旧 iframe 的事件可缺少该字段。宿主主动调用的每次可失败命令都应处理 rejection,可在业务封装层
|
|
125
126
|
集中处理,不必在每个按钮里重复写 `catch`。命令 rejection 不保证产生 `error`,播放期 `error`
|
|
126
127
|
也不保证对应某个命令 rejection。`void ref.current?.play()` 不会处理 Promise rejection。
|
package/dist/index.cjs
CHANGED
|
@@ -168,6 +168,10 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
168
168
|
pauseIntentPendingRef.current = false;
|
|
169
169
|
setHostPauseVisible(false);
|
|
170
170
|
awaitingNewSourceRef.current = "switching";
|
|
171
|
+
setLoadingOverlay({
|
|
172
|
+
phase: firstFrameSeenRef.current ? "runtime" : "initial",
|
|
173
|
+
reason: "source_switching"
|
|
174
|
+
});
|
|
171
175
|
handleRef.current?.setSourceSwitching(true).catch(() => {});
|
|
172
176
|
forwardWithDelivery({
|
|
173
177
|
event: "playablechange",
|
|
@@ -242,6 +246,7 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
242
246
|
let cancelled = false;
|
|
243
247
|
const container = containerRef.current;
|
|
244
248
|
if (!container) return;
|
|
249
|
+
const handshake = new AbortController();
|
|
245
250
|
const p = propsRef.current;
|
|
246
251
|
setHostOwnsOverlays(false);
|
|
247
252
|
(0, _video_lab_frame_core.createPlayerFrame)({
|
|
@@ -249,6 +254,7 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
249
254
|
source: activeSourceRef.current,
|
|
250
255
|
config: toConfig(p, hasCustomPoster, hasCustomPause),
|
|
251
256
|
renderDefaultFallback: false,
|
|
257
|
+
signal: handshake.signal,
|
|
252
258
|
onHostOverlayOwnershipChange: (owned) => setHostOwnsOverlays(owned),
|
|
253
259
|
sourceSwitching: sourceSwitchRef.current !== null,
|
|
254
260
|
pageFullscreen: p.pageFullscreen,
|
|
@@ -310,17 +316,18 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
310
316
|
}
|
|
311
317
|
}
|
|
312
318
|
if (event.event === "firstframe" || event.event === "timeupdate") if (awaitingNewSourceRef.current === "switching") {} else {
|
|
313
|
-
|
|
319
|
+
const newSourceArrived = awaitingNewSourceRef.current === "new-source";
|
|
320
|
+
if (newSourceArrived) awaitingNewSourceRef.current = false;
|
|
314
321
|
firstFrameSeenRef.current = true;
|
|
315
322
|
setHostPosterVisible(false);
|
|
316
|
-
setLoadingOverlay(null);
|
|
323
|
+
setLoadingOverlay((prev) => newSourceArrived || prev?.phase !== "runtime" ? null : prev);
|
|
317
324
|
}
|
|
318
325
|
else if (event.event === "playablechange") {
|
|
319
326
|
const { playable, recoverable, reason, action = "none" } = event.payload;
|
|
320
327
|
const terminalError = !playable && !recoverable && reason === "error";
|
|
321
328
|
const blockingAction = !playable && !recoverable && action !== "none";
|
|
322
329
|
if (terminalError) setHostPosterVisible(false);
|
|
323
|
-
setLoadingOverlay(!firstFrameSeenRef.current ? terminalError || blockingAction ? null : {
|
|
330
|
+
if (!(awaitingNewSourceRef.current !== false && (reason === "initializing" || reason === "ok"))) setLoadingOverlay(!firstFrameSeenRef.current ? terminalError || blockingAction ? null : {
|
|
324
331
|
phase: "initial",
|
|
325
332
|
reason
|
|
326
333
|
} : !playable && recoverable && reason !== "initializing" ? {
|
|
@@ -350,6 +357,7 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
350
357
|
});
|
|
351
358
|
return () => {
|
|
352
359
|
cancelled = true;
|
|
360
|
+
handshake.abort();
|
|
353
361
|
handleRef.current?.destroy();
|
|
354
362
|
handleRef.current = null;
|
|
355
363
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -301,4 +301,3 @@ interface VideoPlayerFrameHandle {
|
|
|
301
301
|
declare const VideoPlayerFrame: import("react").ForwardRefExoticComponent<VideoPlayerFrameProps & import("react").RefAttributes<VideoPlayerFrameHandle>>;
|
|
302
302
|
//#endregion
|
|
303
303
|
export { type DanmakuConfig, type DanmakuItem, type LoadingOverlayContext, type MediaSource, type PageFullscreenAdapter, type PageFullscreenState, type PlayerError, type PlayerHandle, PlayerProvider, type PlayerProviderProps, type QualityLevel, type ResolveSource, type SubtitleTrackInfo, VideoPlayerFrame, type VideoPlayerFrameHandle, type VideoPlayerFrameProps, usePlayerI18n };
|
|
304
|
-
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -301,4 +301,3 @@ interface VideoPlayerFrameHandle {
|
|
|
301
301
|
declare const VideoPlayerFrame: import("react").ForwardRefExoticComponent<VideoPlayerFrameProps & import("react").RefAttributes<VideoPlayerFrameHandle>>;
|
|
302
302
|
//#endregion
|
|
303
303
|
export { type DanmakuConfig, type DanmakuItem, type LoadingOverlayContext, type MediaSource, type PageFullscreenAdapter, type PageFullscreenState, type PlayerError, type PlayerHandle, PlayerProvider, type PlayerProviderProps, type QualityLevel, type ResolveSource, type SubtitleTrackInfo, VideoPlayerFrame, type VideoPlayerFrameHandle, type VideoPlayerFrameProps, usePlayerI18n };
|
|
304
|
-
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -167,6 +167,10 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
167
167
|
pauseIntentPendingRef.current = false;
|
|
168
168
|
setHostPauseVisible(false);
|
|
169
169
|
awaitingNewSourceRef.current = "switching";
|
|
170
|
+
setLoadingOverlay({
|
|
171
|
+
phase: firstFrameSeenRef.current ? "runtime" : "initial",
|
|
172
|
+
reason: "source_switching"
|
|
173
|
+
});
|
|
170
174
|
handleRef.current?.setSourceSwitching(true).catch(() => {});
|
|
171
175
|
forwardWithDelivery({
|
|
172
176
|
event: "playablechange",
|
|
@@ -241,6 +245,7 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
241
245
|
let cancelled = false;
|
|
242
246
|
const container = containerRef.current;
|
|
243
247
|
if (!container) return;
|
|
248
|
+
const handshake = new AbortController();
|
|
244
249
|
const p = propsRef.current;
|
|
245
250
|
setHostOwnsOverlays(false);
|
|
246
251
|
createPlayerFrame({
|
|
@@ -248,6 +253,7 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
248
253
|
source: activeSourceRef.current,
|
|
249
254
|
config: toConfig(p, hasCustomPoster, hasCustomPause),
|
|
250
255
|
renderDefaultFallback: false,
|
|
256
|
+
signal: handshake.signal,
|
|
251
257
|
onHostOverlayOwnershipChange: (owned) => setHostOwnsOverlays(owned),
|
|
252
258
|
sourceSwitching: sourceSwitchRef.current !== null,
|
|
253
259
|
pageFullscreen: p.pageFullscreen,
|
|
@@ -309,17 +315,18 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
309
315
|
}
|
|
310
316
|
}
|
|
311
317
|
if (event.event === "firstframe" || event.event === "timeupdate") if (awaitingNewSourceRef.current === "switching") {} else {
|
|
312
|
-
|
|
318
|
+
const newSourceArrived = awaitingNewSourceRef.current === "new-source";
|
|
319
|
+
if (newSourceArrived) awaitingNewSourceRef.current = false;
|
|
313
320
|
firstFrameSeenRef.current = true;
|
|
314
321
|
setHostPosterVisible(false);
|
|
315
|
-
setLoadingOverlay(null);
|
|
322
|
+
setLoadingOverlay((prev) => newSourceArrived || prev?.phase !== "runtime" ? null : prev);
|
|
316
323
|
}
|
|
317
324
|
else if (event.event === "playablechange") {
|
|
318
325
|
const { playable, recoverable, reason, action = "none" } = event.payload;
|
|
319
326
|
const terminalError = !playable && !recoverable && reason === "error";
|
|
320
327
|
const blockingAction = !playable && !recoverable && action !== "none";
|
|
321
328
|
if (terminalError) setHostPosterVisible(false);
|
|
322
|
-
setLoadingOverlay(!firstFrameSeenRef.current ? terminalError || blockingAction ? null : {
|
|
329
|
+
if (!(awaitingNewSourceRef.current !== false && (reason === "initializing" || reason === "ok"))) setLoadingOverlay(!firstFrameSeenRef.current ? terminalError || blockingAction ? null : {
|
|
323
330
|
phase: "initial",
|
|
324
331
|
reason
|
|
325
332
|
} : !playable && recoverable && reason !== "initializing" ? {
|
|
@@ -349,6 +356,7 @@ function useFrameConnection(props, hasCustomPoster = false, hasCustomPause = fal
|
|
|
349
356
|
});
|
|
350
357
|
return () => {
|
|
351
358
|
cancelled = true;
|
|
359
|
+
handshake.abort();
|
|
352
360
|
handleRef.current?.destroy();
|
|
353
361
|
handleRef.current = null;
|
|
354
362
|
};
|
|
@@ -826,4 +834,3 @@ const VideoPlayerFrame = forwardRef(function VideoPlayerFrame(rawProps, ref) {
|
|
|
826
834
|
//#endregion
|
|
827
835
|
export { PlayerProvider, VideoPlayerFrame, usePlayerI18n };
|
|
828
836
|
|
|
829
|
-
//# sourceMappingURL=index.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@video-lab/react-frame",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"react-dom": ">=19.0.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@video-lab/protocol": "4.
|
|
38
|
-
"@video-lab/react-config": "4.
|
|
39
|
-
"@video-lab/frame-core": "4.
|
|
37
|
+
"@video-lab/protocol": "4.1.0",
|
|
38
|
+
"@video-lab/react-config": "4.1.0",
|
|
39
|
+
"@video-lab/frame-core": "4.1.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@testing-library/jest-dom": "^6.0.0",
|
|
@@ -3,8 +3,8 @@ name: video-lab-host-integration
|
|
|
3
3
|
skillVersion: 1
|
|
4
4
|
sdkMajor: 4
|
|
5
5
|
supportedPackages:
|
|
6
|
-
- '@video-lab/react-frame@4.
|
|
7
|
-
- '@video-lab/vue-frame@4.
|
|
6
|
+
- '@video-lab/react-frame@4.1.0'
|
|
7
|
+
- '@video-lab/vue-frame@4.1.0'
|
|
8
8
|
description: >-
|
|
9
9
|
在业务宿主项目中接入 Video Lab Player 时使用。选择五种接入面之一,完成可验证 demo,
|
|
10
10
|
并交接 SDK、宿主与服务端责任;不用于修改 SDK 契约或设计品牌 UI。
|