@video-lab/vue 1.0.1 → 3.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/README.md +43 -9
- package/dist/VideoPlayer.vue.d.ts +1442 -10
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +106 -90
- package/dist/types.d.ts +18 -15
- package/dist/use-player.d.ts +2 -2
- package/package.json +9 -8
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("vue"),t=require("@video-lab/protocol"),n=require("@video-lab/player-ui"),r=require("@video-lab/player-core");function i(t,r){return(0,n.defineSentinelOverlays)(),(0,e.h)(t,r)}function a(e,t){return e[t]??t}function o(e,t,n){let r=`error.${t}`,i=a(e,r);return i===r?n:i}function s(i,a,o){let s=(0,e.shallowRef)(null),u=(0,e.shallowRef)(n.INITIAL_OVERLAY),d=(0,e.ref)(!1);function f(e){let r=(0,t.toErrorEvent)(e);u.value=(0,n.reduceOverlay)(u.value,r),l(r,o)}function p(e){let n=s.value;if(n){if(n.destroyed){f({playerError:(0,t.makePlayerError)(`E_PLAYER_DESTROYED`,t.PLAYER_DESTROYED_MESSAGE)});return}e(n)}}function m(){let e=i.value;if(e){u.value=n.INITIAL_OVERLAY;try{s.value=(0,r.createPlayer)({el:e,config:c(a),onEvent:e=>{u.value=(0,n.reduceOverlay)(u.value,e),l(e,o)}}),d.value=!0}catch(e){f(e)}}}function h(){s.value?.destroy(),s.value=null,d.value=!1}(0,e.onMounted)(m),(0,e.onBeforeUnmount)(h),(0,e.watch)(()=>JSON.stringify(a.source),()=>{u.value=(0,n.resetOverlayForNewSource)(u.value),p(e=>{e.load(a.source).catch(f)})}),(0,e.watch)(()=>a.muted,e=>{e!==void 0&&p(t=>t.setMuted(e))}),(0,e.watch)(()=>a.locale,e=>{e!==void 0&&p(t=>t.setLocale(e))},{deep:!0});function g(){
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("vue"),t=require("@video-lab/protocol"),n=require("@video-lab/player-ui"),r=require("@video-lab/player-core");function i(t,r){return(0,n.defineSentinelOverlays)(),(0,e.h)(t,r)}function a(e,t){return e[t]??t}function o(e,t,n){let r=`error.${t}`,i=a(e,r);return i===r?n:i}function s(i,a,o){let s=(0,e.shallowRef)(null),u=(0,e.shallowRef)(n.INITIAL_OVERLAY),d=(0,e.ref)(!1);function f(e){let r=(0,t.toErrorEvent)(e);u.value=s.value?(0,n.reduceOverlay)(u.value,r):{...u.value,posterVisible:!1,loadingVisible:!1,error:r.payload,action:`replace-source`},l(r,o)}function p(e){let n=s.value;if(n){if(n.destroyed){f({playerError:(0,t.makePlayerError)(`E_PLAYER_DESTROYED`,t.PLAYER_DESTROYED_MESSAGE)});return}e(n)}}function m(){let e=i.value;if(e){u.value=n.INITIAL_OVERLAY;try{s.value=(0,r.createPlayer)({el:e,config:c(a),pageFullscreen:a.pageFullscreen,onEvent:e=>{u.value=(0,n.reduceOverlay)(u.value,e),l(e,o)},onDeliveredEvent:e=>{try{o(`deliveredPlayerEvent`,e)}catch{}}}),d.value=!0}catch(e){f(e)}}}function h(){s.value?.destroy(),s.value=null,d.value=!1}(0,e.onMounted)(m),(0,e.onBeforeUnmount)(h),(0,e.watch)(()=>JSON.stringify(a.source),()=>{u.value=(0,n.resetOverlayForNewSource)(u.value),p(e=>{e.load(a.source).catch(f)})}),(0,e.watch)(()=>a.muted,e=>{e!==void 0&&p(t=>t.setMuted(e))}),(0,e.watch)(()=>a.locale,e=>{e!==void 0&&p(t=>t.setLocale(e))},{deep:!0});function g(){let e=s.value;e&&(u.value.action===`play`?e.play():e.retry()).catch(()=>{})}function _(){u.value={...u.value,pauseImageVisible:!1,pauseImageDismissed:!0}}return{handle:s,overlay:u,isMounted:d,handleRetry:g,dismissPauseImage:_}}function c(e){let t={source:e.source};return e.preset!==void 0&&(t.preset=e.preset),e.autoplay!==void 0&&(t.autoplay=e.autoplay),e.muted!==void 0&&(t.muted=e.muted),e.loop!==void 0&&(t.loop=e.loop),e.playsinline!==void 0&&(t.playsinline=e.playsinline),e.playbackRate!==void 0&&(t.playbackRate=e.playbackRate),e.volume!==void 0&&(t.volume=e.volume),e.startTime!==void 0&&(t.startTime=e.startTime),e.preload!==void 0&&(t.preload=e.preload),e.controls!==void 0&&(t.controls=e.controls),e.showErrorOverlay!==void 0&&(t.showErrorOverlay=e.showErrorOverlay),e.showLoadingOverlay!==void 0&&(t.showLoadingOverlay=e.showLoadingOverlay),e.controlVisibility!==void 0&&(t.controlVisibility=e.controlVisibility),e.interactive!==void 0&&(t.interactive=e.interactive),e.poster!==void 0&&(t.poster=e.poster),e.pauseImage!==void 0&&(t.pauseImage=e.pauseImage),e.locale!==void 0&&(t.locale=e.locale),e.danmaku!==void 0&&(t.danmaku=e.danmaku),e.debug!==void 0&&(t.debug=e.debug),t}function l(e,t){try{t(`playerEvent`,e)}catch{}switch(e.event){case`ready`:t(`ready`,e.payload);break;case`play`:t(`play`);break;case`pause`:t(`pause`);break;case`ended`:t(`ended`);break;case`timeupdate`:t(`timeUpdate`,e.payload);break;case`volumechange`:t(`volumeChange`,e.payload);break;case`seeking`:t(`seeking`,e.payload);break;case`seeked`:t(`seeked`,e.payload);break;case`waiting`:t(`waiting`);break;case`playing`:t(`playing`);break;case`qualitychange`:t(`qualityChange`,e.payload);break;case`subtitlechange`:t(`subtitleChange`,e.payload);break;case`error`:t(`error`,e.payload);break;case`autoplayblocked`:t(`autoplayBlocked`);break;case`compatwarning`:t(`compatWarning`,e.payload);break;case`stalled`:t(`stalled`,e.payload);break;case`playablechange`:t(`playableChange`,e.payload);break;case`bufferhealth`:t(`bufferHealth`,e.payload);break;case`contextchange`:t(`contextChange`,e.payload);break;case`sourceroute`:t(`sourceRoute`,e.payload);break;case`firstframe`:t(`firstFrame`,e.payload);break;case`framefreeze`:t(`frameFreeze`,e.payload);break;case`pagefullscreenchange`:t(`pageFullscreenChange`,e.payload);break;case`useraction`:t(`userAction`,e.payload);break;case`kernelhealth`:t(`kernelHealth`,e.payload);break;case`audiohealth`:t(`audioHealth`,e.payload);break;case`recovery`:break;default:break}}var u=(0,e.defineComponent)({__name:`VideoPlayer`,props:{pageFullscreen:{},source:{},autoplay:{type:Boolean,default:void 0},muted:{type:Boolean,default:void 0},loop:{type:Boolean,default:void 0},controls:{type:Boolean,default:void 0},showErrorOverlay:{type:Boolean,default:void 0},showLoadingOverlay:{type:Boolean,default:void 0},controlVisibility:{},interactive:{type:Boolean,default:void 0},playsinline:{type:Boolean,default:void 0},playbackRate:{},volume:{},startTime:{},preload:{},poster:{},pauseImage:{},preset:{},locale:{},danmaku:{},debug:{type:Boolean,default:void 0}},emits:`playerEvent.deliveredPlayerEvent.ready.play.pause.ended.timeUpdate.volumeChange.seeking.seeked.waiting.playing.qualityChange.subtitleChange.error.autoplayBlocked.compatWarning.stalled.playableChange.kernelHealth.audioHealth.bufferHealth.contextChange.sourceRoute.firstFrame.frameFreeze.pageFullscreenChange.userAction`.split(`.`),setup(n,{expose:r,emit:c}){let l=n,u=c,d=l.showErrorOverlay!==!1,f=l.showLoadingOverlay!==!1,p=(0,e.shallowRef)(null),{handle:m,overlay:h,isMounted:g,handleRetry:_,dismissPauseImage:v}=s(p,l,u),y=(0,e.computed)(()=>(0,t.resolveLocaleMessages)(l.locale).messages),b=(0,e.computed)(()=>typeof l.poster==`string`?l.poster:l.poster?.url),x=(0,e.computed)(()=>typeof l.pauseImage==`string`?l.pauseImage:l.pauseImage?.url),S=()=>[b.value?i(`sentinel-poster`,{visible:h.value.posterVisible,poster:l.poster}):null,x.value?i(`sentinel-pause`,{visible:h.value.pauseImageVisible,pauseImage:l.pauseImage,"close-label":a(y.value,`close`),"onSentinel-close":v}):null,i(`sentinel-loading`,{visible:f&&h.value.loadingVisible,text:a(y.value,`loading`)}),d&&h.value.error?i(`sentinel-error`,{visible:!0,code:h.value.error.code,message:o(y.value,h.value.error.code,h.value.error.message),retryable:h.value.action===`retry`||h.value.action===`play`,"retry-label":a(y.value,h.value.action===`play`?`play`:`retry`),"onSentinel-retry":_}):null];return r({play:()=>m.value?.play()??Promise.resolve(),pause:()=>m.value?.pause(),seek:e=>m.value?.seek(e),setMuted:e=>m.value?.setMuted(e),setVolume:e=>m.value?.setVolume(e),setPlaybackRate:e=>m.value?.setPlaybackRate(e),setPageFullscreen:e=>m.value?.setPageFullscreen(e)??Promise.reject(Error(`播放器未就绪`)),enterFullscreen:()=>m.value?.enterFullscreen()??Promise.resolve(),exitFullscreen:()=>m.value?.exitFullscreen()??Promise.resolve(),setQuality:e=>m.value?.setQuality(e),setSubtitle:e=>m.value?.setSubtitle(e),setLocale:e=>m.value?.setLocale(e),pushDanmaku:e=>m.value?.pushDanmaku(e),setDanmakuEnabled:e=>m.value?.setDanmakuEnabled(e),clearDanmaku:()=>m.value?.clearDanmaku(),retry:()=>m.value?.retry()??Promise.resolve(),destroy:()=>m.value?.destroy(),getCurrentTime:()=>m.value?.getCurrentTime()??0,getDuration:()=>m.value?.getDuration()??0,getPlaybackContext:()=>m.value?.getPlaybackContext()??null,getPlayerHandle:()=>m.value}),(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)(`div`,{class:`sentinel-video`,style:(0,e.normalizeStyle)({position:`relative`,width:`100%`,height:`100%`,pointerEvents:l.interactive===!1?`none`:void 0})},[(0,e.createElementVNode)(`div`,{ref_key:`containerRef`,ref:p,class:`sentinel-video__player`,style:{width:`100%`,height:`100%`}},null,512),(0,e.createVNode)(S),(0,e.unref)(g)?(0,e.createCommentVNode)(``,!0):(0,e.renderSlot)(t.$slots,`ssr-placeholder`,{key:0})],4))}});exports.VideoPlayer=u;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* 只做技术,不含团队品牌 UI(ADR-021)。**开门的决策见 ADR-052**
|
|
9
9
|
*(取代 ADR-002「Vue 只做 iframe 不做 inline」—— 那条的唯一论据在 #120 之后已不成立)。
|
|
10
10
|
*/
|
|
11
|
+
export type { PageFullscreenAdapter, PageFullscreenState } from '@video-lab/protocol';
|
|
11
12
|
export type { DanmakuConfig, DanmakuItem, MediaSource, PlayerError, PlayerHandle, QualityLevel, SubtitleTrackInfo, VideoPlayerEmits, VideoPlayerExpose, VideoPlayerProps, } from './types';
|
|
12
13
|
export { default as VideoPlayer } from './VideoPlayer.vue';
|
|
13
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,31 +1,37 @@
|
|
|
1
|
-
import { computed as e, createCommentVNode as t, createElementBlock as n, createElementVNode as r, createVNode as i, defineComponent as a, h as o, normalizeStyle as s, onBeforeUnmount as c, onMounted as l, openBlock as u, ref as d, renderSlot as f, shallowRef as p, unref as m,
|
|
2
|
-
import { PLAYER_DESTROYED_MESSAGE as
|
|
3
|
-
import { INITIAL_OVERLAY as
|
|
4
|
-
import { createPlayer as
|
|
1
|
+
import { computed as e, createCommentVNode as t, createElementBlock as n, createElementVNode as r, createVNode as i, defineComponent as a, h as o, normalizeStyle as s, onBeforeUnmount as c, onMounted as l, openBlock as u, ref as d, renderSlot as f, shallowRef as p, unref as m, watch as h } from "vue";
|
|
2
|
+
import { PLAYER_DESTROYED_MESSAGE as g, makePlayerError as _, resolveLocaleMessages as v, toErrorEvent as y } from "@video-lab/protocol";
|
|
3
|
+
import { INITIAL_OVERLAY as b, defineSentinelOverlays as x, reduceOverlay as S, resetOverlayForNewSource as C } from "@video-lab/player-ui";
|
|
4
|
+
import { createPlayer as w } from "@video-lab/player-core";
|
|
5
5
|
//#region src/overlay-elements.ts
|
|
6
|
-
function
|
|
7
|
-
return
|
|
6
|
+
function T(e, t) {
|
|
7
|
+
return x(), o(e, t);
|
|
8
8
|
}
|
|
9
|
-
function
|
|
9
|
+
function E(e, t) {
|
|
10
10
|
return e[t] ?? t;
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
let r = `error.${t}`, i =
|
|
12
|
+
function D(e, t, n) {
|
|
13
|
+
let r = `error.${t}`, i = E(e, r);
|
|
14
14
|
return i === r ? n : i;
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/use-player.ts
|
|
18
|
-
function
|
|
19
|
-
let r = p(null), i = p(
|
|
18
|
+
function O(e, t, n) {
|
|
19
|
+
let r = p(null), i = p(b), a = d(!1);
|
|
20
20
|
function o(e) {
|
|
21
|
-
let t =
|
|
22
|
-
i.value =
|
|
21
|
+
let t = y(e);
|
|
22
|
+
i.value = r.value ? S(i.value, t) : {
|
|
23
|
+
...i.value,
|
|
24
|
+
posterVisible: !1,
|
|
25
|
+
loadingVisible: !1,
|
|
26
|
+
error: t.payload,
|
|
27
|
+
action: "replace-source"
|
|
28
|
+
}, A(t, n);
|
|
23
29
|
}
|
|
24
30
|
function s(e) {
|
|
25
31
|
let t = r.value;
|
|
26
32
|
if (t) {
|
|
27
33
|
if (t.destroyed) {
|
|
28
|
-
o({ playerError:
|
|
34
|
+
o({ playerError: _("E_PLAYER_DESTROYED", g) });
|
|
29
35
|
return;
|
|
30
36
|
}
|
|
31
37
|
e(t);
|
|
@@ -34,13 +40,19 @@ function k(e, t, n) {
|
|
|
34
40
|
function u() {
|
|
35
41
|
let s = e.value;
|
|
36
42
|
if (s) {
|
|
37
|
-
i.value =
|
|
43
|
+
i.value = b;
|
|
38
44
|
try {
|
|
39
|
-
r.value =
|
|
45
|
+
r.value = w({
|
|
40
46
|
el: s,
|
|
41
|
-
config:
|
|
47
|
+
config: k(t),
|
|
48
|
+
pageFullscreen: t.pageFullscreen,
|
|
42
49
|
onEvent: (e) => {
|
|
43
|
-
i.value =
|
|
50
|
+
i.value = S(i.value, e), A(e, n);
|
|
51
|
+
},
|
|
52
|
+
onDeliveredEvent: (e) => {
|
|
53
|
+
try {
|
|
54
|
+
n("deliveredPlayerEvent", e);
|
|
55
|
+
} catch {}
|
|
44
56
|
}
|
|
45
57
|
}), a.value = !0;
|
|
46
58
|
} catch (e) {
|
|
@@ -51,19 +63,20 @@ function k(e, t, n) {
|
|
|
51
63
|
function f() {
|
|
52
64
|
r.value?.destroy(), r.value = null, a.value = !1;
|
|
53
65
|
}
|
|
54
|
-
l(u), c(f),
|
|
55
|
-
i.value =
|
|
66
|
+
l(u), c(f), h(() => JSON.stringify(t.source), () => {
|
|
67
|
+
i.value = C(i.value), s((e) => {
|
|
56
68
|
e.load(t.source).catch(o);
|
|
57
69
|
});
|
|
58
|
-
}),
|
|
70
|
+
}), h(() => t.muted, (e) => {
|
|
59
71
|
e !== void 0 && s((t) => t.setMuted(e));
|
|
60
|
-
}),
|
|
72
|
+
}), h(() => t.locale, (e) => {
|
|
61
73
|
e !== void 0 && s((t) => t.setLocale(e));
|
|
62
74
|
}, { deep: !0 });
|
|
63
75
|
function m() {
|
|
64
|
-
|
|
76
|
+
let e = r.value;
|
|
77
|
+
e && (i.value.action === "play" ? e.play() : e.retry()).catch(() => {});
|
|
65
78
|
}
|
|
66
|
-
function
|
|
79
|
+
function v() {
|
|
67
80
|
i.value = {
|
|
68
81
|
...i.value,
|
|
69
82
|
pauseImageVisible: !1,
|
|
@@ -75,14 +88,14 @@ function k(e, t, n) {
|
|
|
75
88
|
overlay: i,
|
|
76
89
|
isMounted: a,
|
|
77
90
|
handleRetry: m,
|
|
78
|
-
dismissPauseImage:
|
|
91
|
+
dismissPauseImage: v
|
|
79
92
|
};
|
|
80
93
|
}
|
|
81
|
-
function
|
|
94
|
+
function k(e) {
|
|
82
95
|
let t = { source: e.source };
|
|
83
|
-
return e.preset !== void 0 && (t.preset = e.preset), e.autoplay !== void 0 && (t.autoplay = e.autoplay), e.muted !== void 0 && (t.muted = e.muted), e.loop !== void 0 && (t.loop = e.loop), e.playsinline !== void 0 && (t.playsinline = e.playsinline), e.playbackRate !== void 0 && (t.playbackRate = e.playbackRate), e.volume !== void 0 && (t.volume = e.volume), e.startTime !== void 0 && (t.startTime = e.startTime), e.preload !== void 0 && (t.preload = e.preload), e.controls !== void 0 && (t.controls = e.controls), e.interactive !== void 0 && (t.interactive = e.interactive), e.poster !== void 0 && (t.poster = e.poster), e.pauseImage !== void 0 && (t.pauseImage = e.pauseImage), e.locale !== void 0 && (t.locale = e.locale), e.danmaku !== void 0 && (t.danmaku = e.danmaku), e.debug !== void 0 && (t.debug = e.debug), t;
|
|
96
|
+
return e.preset !== void 0 && (t.preset = e.preset), e.autoplay !== void 0 && (t.autoplay = e.autoplay), e.muted !== void 0 && (t.muted = e.muted), e.loop !== void 0 && (t.loop = e.loop), e.playsinline !== void 0 && (t.playsinline = e.playsinline), e.playbackRate !== void 0 && (t.playbackRate = e.playbackRate), e.volume !== void 0 && (t.volume = e.volume), e.startTime !== void 0 && (t.startTime = e.startTime), e.preload !== void 0 && (t.preload = e.preload), e.controls !== void 0 && (t.controls = e.controls), e.showErrorOverlay !== void 0 && (t.showErrorOverlay = e.showErrorOverlay), e.showLoadingOverlay !== void 0 && (t.showLoadingOverlay = e.showLoadingOverlay), e.controlVisibility !== void 0 && (t.controlVisibility = e.controlVisibility), e.interactive !== void 0 && (t.interactive = e.interactive), e.poster !== void 0 && (t.poster = e.poster), e.pauseImage !== void 0 && (t.pauseImage = e.pauseImage), e.locale !== void 0 && (t.locale = e.locale), e.danmaku !== void 0 && (t.danmaku = e.danmaku), e.debug !== void 0 && (t.debug = e.debug), t;
|
|
84
97
|
}
|
|
85
|
-
function
|
|
98
|
+
function A(e, t) {
|
|
86
99
|
try {
|
|
87
100
|
t("playerEvent", e);
|
|
88
101
|
} catch {}
|
|
@@ -129,18 +142,6 @@ function j(e, t) {
|
|
|
129
142
|
case "autoplayblocked":
|
|
130
143
|
t("autoplayBlocked");
|
|
131
144
|
break;
|
|
132
|
-
case "reconnectstart":
|
|
133
|
-
t("reconnectStart", {
|
|
134
|
-
attempt: e.payload.attempt,
|
|
135
|
-
maxAttempts: e.payload.maxAttempts
|
|
136
|
-
});
|
|
137
|
-
break;
|
|
138
|
-
case "reconnectsuccess":
|
|
139
|
-
t("reconnectSuccess");
|
|
140
|
-
break;
|
|
141
|
-
case "reconnectfailed":
|
|
142
|
-
t("reconnectFailed");
|
|
143
|
-
break;
|
|
144
145
|
case "compatwarning":
|
|
145
146
|
t("compatWarning", e.payload);
|
|
146
147
|
break;
|
|
@@ -165,6 +166,9 @@ function j(e, t) {
|
|
|
165
166
|
case "framefreeze":
|
|
166
167
|
t("frameFreeze", e.payload);
|
|
167
168
|
break;
|
|
169
|
+
case "pagefullscreenchange":
|
|
170
|
+
t("pageFullscreenChange", e.payload);
|
|
171
|
+
break;
|
|
168
172
|
case "useraction":
|
|
169
173
|
t("userAction", e.payload);
|
|
170
174
|
break;
|
|
@@ -179,17 +183,11 @@ function j(e, t) {
|
|
|
179
183
|
}
|
|
180
184
|
}
|
|
181
185
|
//#endregion
|
|
182
|
-
//#region src/VideoPlayer.vue
|
|
183
|
-
var
|
|
184
|
-
ref: "container",
|
|
185
|
-
class: "sentinel-video__player",
|
|
186
|
-
style: {
|
|
187
|
-
width: "100%",
|
|
188
|
-
height: "100%"
|
|
189
|
-
}
|
|
190
|
-
}, N = /* @__PURE__ */ a({
|
|
186
|
+
//#region src/VideoPlayer.vue
|
|
187
|
+
var j = /* @__PURE__ */ a({
|
|
191
188
|
__name: "VideoPlayer",
|
|
192
189
|
props: {
|
|
190
|
+
pageFullscreen: {},
|
|
193
191
|
source: {},
|
|
194
192
|
autoplay: {
|
|
195
193
|
type: Boolean,
|
|
@@ -207,6 +205,15 @@ var M = {
|
|
|
207
205
|
type: Boolean,
|
|
208
206
|
default: void 0
|
|
209
207
|
},
|
|
208
|
+
showErrorOverlay: {
|
|
209
|
+
type: Boolean,
|
|
210
|
+
default: void 0
|
|
211
|
+
},
|
|
212
|
+
showLoadingOverlay: {
|
|
213
|
+
type: Boolean,
|
|
214
|
+
default: void 0
|
|
215
|
+
},
|
|
216
|
+
controlVisibility: {},
|
|
210
217
|
interactive: {
|
|
211
218
|
type: Boolean,
|
|
212
219
|
default: void 0
|
|
@@ -229,53 +236,54 @@ var M = {
|
|
|
229
236
|
default: void 0
|
|
230
237
|
}
|
|
231
238
|
},
|
|
232
|
-
emits: /* @__PURE__ */ "playerEvent.ready.play.pause.ended.timeUpdate.volumeChange.seeking.seeked.waiting.playing.qualityChange.subtitleChange.error.autoplayBlocked.
|
|
239
|
+
emits: /* @__PURE__ */ "playerEvent.deliveredPlayerEvent.ready.play.pause.ended.timeUpdate.volumeChange.seeking.seeked.waiting.playing.qualityChange.subtitleChange.error.autoplayBlocked.compatWarning.stalled.playableChange.kernelHealth.audioHealth.bufferHealth.contextChange.sourceRoute.firstFrame.frameFreeze.pageFullscreenChange.userAction".split("."),
|
|
233
240
|
setup(a, { expose: o, emit: c }) {
|
|
234
|
-
let l = a, d = c, { handle:
|
|
235
|
-
|
|
236
|
-
visible:
|
|
241
|
+
let l = a, d = c, h = l.showErrorOverlay !== !1, g = l.showLoadingOverlay !== !1, _ = p(null), { handle: y, overlay: b, isMounted: x, handleRetry: S, dismissPauseImage: C } = O(_, l, d), w = e(() => v(l.locale).messages), k = e(() => typeof l.poster == "string" ? l.poster : l.poster?.url), A = e(() => typeof l.pauseImage == "string" ? l.pauseImage : l.pauseImage?.url), j = () => [
|
|
242
|
+
k.value ? T("sentinel-poster", {
|
|
243
|
+
visible: b.value.posterVisible,
|
|
237
244
|
poster: l.poster
|
|
238
245
|
}) : null,
|
|
239
|
-
|
|
240
|
-
visible:
|
|
246
|
+
A.value ? T("sentinel-pause", {
|
|
247
|
+
visible: b.value.pauseImageVisible,
|
|
241
248
|
pauseImage: l.pauseImage,
|
|
242
|
-
"close-label":
|
|
243
|
-
"onSentinel-close":
|
|
249
|
+
"close-label": E(w.value, "close"),
|
|
250
|
+
"onSentinel-close": C
|
|
244
251
|
}) : null,
|
|
245
|
-
|
|
246
|
-
visible: g.value.loadingVisible,
|
|
247
|
-
text:
|
|
252
|
+
T("sentinel-loading", {
|
|
253
|
+
visible: g && b.value.loadingVisible,
|
|
254
|
+
text: E(w.value, "loading")
|
|
248
255
|
}),
|
|
249
|
-
|
|
256
|
+
h && b.value.error ? T("sentinel-error", {
|
|
250
257
|
visible: !0,
|
|
251
|
-
code:
|
|
252
|
-
message:
|
|
253
|
-
retryable:
|
|
254
|
-
"retry-label":
|
|
255
|
-
"onSentinel-retry":
|
|
258
|
+
code: b.value.error.code,
|
|
259
|
+
message: D(w.value, b.value.error.code, b.value.error.message),
|
|
260
|
+
retryable: b.value.action === "retry" || b.value.action === "play",
|
|
261
|
+
"retry-label": E(w.value, b.value.action === "play" ? "play" : "retry"),
|
|
262
|
+
"onSentinel-retry": S
|
|
256
263
|
}) : null
|
|
257
264
|
];
|
|
258
265
|
return o({
|
|
259
|
-
play: () =>
|
|
260
|
-
pause: () =>
|
|
261
|
-
seek: (e) =>
|
|
262
|
-
setMuted: (e) =>
|
|
263
|
-
setVolume: (e) =>
|
|
264
|
-
setPlaybackRate: (e) =>
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
266
|
+
play: () => y.value?.play() ?? Promise.resolve(),
|
|
267
|
+
pause: () => y.value?.pause(),
|
|
268
|
+
seek: (e) => y.value?.seek(e),
|
|
269
|
+
setMuted: (e) => y.value?.setMuted(e),
|
|
270
|
+
setVolume: (e) => y.value?.setVolume(e),
|
|
271
|
+
setPlaybackRate: (e) => y.value?.setPlaybackRate(e),
|
|
272
|
+
setPageFullscreen: (e) => y.value?.setPageFullscreen(e) ?? Promise.reject(/* @__PURE__ */ Error("播放器未就绪")),
|
|
273
|
+
enterFullscreen: () => y.value?.enterFullscreen() ?? Promise.resolve(),
|
|
274
|
+
exitFullscreen: () => y.value?.exitFullscreen() ?? Promise.resolve(),
|
|
275
|
+
setQuality: (e) => y.value?.setQuality(e),
|
|
276
|
+
setSubtitle: (e) => y.value?.setSubtitle(e),
|
|
277
|
+
setLocale: (e) => y.value?.setLocale(e),
|
|
278
|
+
pushDanmaku: (e) => y.value?.pushDanmaku(e),
|
|
279
|
+
setDanmakuEnabled: (e) => y.value?.setDanmakuEnabled(e),
|
|
280
|
+
clearDanmaku: () => y.value?.clearDanmaku(),
|
|
281
|
+
retry: () => y.value?.retry() ?? Promise.resolve(),
|
|
282
|
+
destroy: () => y.value?.destroy(),
|
|
283
|
+
getCurrentTime: () => y.value?.getCurrentTime() ?? 0,
|
|
284
|
+
getDuration: () => y.value?.getDuration() ?? 0,
|
|
285
|
+
getPlaybackContext: () => y.value?.getPlaybackContext() ?? null,
|
|
286
|
+
getPlayerHandle: () => y.value
|
|
279
287
|
}), (e, a) => (u(), n("div", {
|
|
280
288
|
class: "sentinel-video",
|
|
281
289
|
style: s({
|
|
@@ -285,11 +293,19 @@ var M = {
|
|
|
285
293
|
pointerEvents: l.interactive === !1 ? "none" : void 0
|
|
286
294
|
})
|
|
287
295
|
}, [
|
|
288
|
-
r("div",
|
|
289
|
-
|
|
290
|
-
|
|
296
|
+
r("div", {
|
|
297
|
+
ref_key: "containerRef",
|
|
298
|
+
ref: _,
|
|
299
|
+
class: "sentinel-video__player",
|
|
300
|
+
style: {
|
|
301
|
+
width: "100%",
|
|
302
|
+
height: "100%"
|
|
303
|
+
}
|
|
304
|
+
}, null, 512),
|
|
305
|
+
i(j),
|
|
306
|
+
m(x) ? t("", !0) : f(e.$slots, "ssr-placeholder", { key: 0 })
|
|
291
307
|
], 4));
|
|
292
308
|
}
|
|
293
309
|
});
|
|
294
310
|
//#endregion
|
|
295
|
-
export {
|
|
311
|
+
export { j as VideoPlayer };
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlayerCoreHandle } from '@video-lab/player-core';
|
|
2
|
-
import { AudioHealthPayload, BufferHealthPayload, DanmakuConfig, DanmakuItem, FirstFramePayload, FrameFreezePayload, KernelHealthPayload, LocaleConfig, MediaSource,
|
|
2
|
+
import { AudioHealthPayload, BufferHealthPayload, ControlVisibilityConfig, DanmakuConfig, DanmakuItem, DeliveredPlayerEvent, FirstFramePayload, FrameFreezePayload, KernelHealthPayload, LocaleConfig, MediaSource, PageFullscreenAdapter, PageFullscreenState, PauseImageConfig, PlaybackContext, PlaybackContextPayload, PlayerError, PlayerEvent, PosterConfig, PresetName, QualityLevel, SourceRouteEventPayload, SubtitleTrackInfo, UserActionPayload } from '@video-lab/protocol';
|
|
3
3
|
/**
|
|
4
4
|
* 消费方拿到的底层句柄(逃生舱)。
|
|
5
5
|
*
|
|
@@ -23,12 +23,20 @@ export type { DanmakuConfig, DanmakuItem, MediaSource, PlayerError, QualityLevel
|
|
|
23
23
|
* 声明成 props 反而会把它们从 fallthrough 里摘出来,要自己再拼一遍。
|
|
24
24
|
*/
|
|
25
25
|
export interface VideoPlayerProps {
|
|
26
|
+
/** 挂载期间保持稳定的宿主网页全屏布局适配器。 */
|
|
27
|
+
pageFullscreen?: PageFullscreenAdapter;
|
|
26
28
|
/** 视频源。字符串按 URL 处理,对象可带 type / live / hls 等 */
|
|
27
29
|
source: MediaSource | string;
|
|
28
30
|
autoplay?: boolean;
|
|
29
31
|
muted?: boolean;
|
|
30
32
|
loop?: boolean;
|
|
31
33
|
controls?: boolean;
|
|
34
|
+
/** 默认错误覆盖层,省略时开启。仅初始化读取;变更须重新挂载,不影响错误事件。 */
|
|
35
|
+
showErrorOverlay?: boolean;
|
|
36
|
+
/** 是否显示 SDK 运行时 Loading;构造期读取,默认 true。 */
|
|
37
|
+
showLoadingOverlay?: boolean;
|
|
38
|
+
/** 内置控件初始化显示策略;修改后须由宿主显式重建播放器。 */
|
|
39
|
+
controlVisibility?: ControlVisibilityConfig;
|
|
32
40
|
/** false 时播放器不接收指针事件(点击穿透到下层,如首页预览卡片) */
|
|
33
41
|
interactive?: boolean;
|
|
34
42
|
playsinline?: boolean;
|
|
@@ -88,6 +96,7 @@ export interface VideoPlayerProps {
|
|
|
88
96
|
export interface VideoPlayerEmits {
|
|
89
97
|
/** 完整的契约事件流,供遥测适配器使用;不裁剪 payload。 */
|
|
90
98
|
(e: 'playerEvent', payload: PlayerEvent): void;
|
|
99
|
+
(e: 'deliveredPlayerEvent', payload: DeliveredPlayerEvent): void;
|
|
91
100
|
/**
|
|
92
101
|
* metadata 就绪。`quality` 是可切档位清单(单码率源为空数组),团队层据此渲染清晰度菜单;
|
|
93
102
|
* `subtitles` 是可切字幕轨清单(无字幕源为空/缺省,契约 1.0.0 起可选,ADR-027),团队层据此渲染字幕菜单。
|
|
@@ -137,12 +146,6 @@ export interface VideoPlayerEmits {
|
|
|
137
146
|
}): void;
|
|
138
147
|
(e: 'error', payload: PlayerError): void;
|
|
139
148
|
(e: 'autoplayBlocked'): void;
|
|
140
|
-
(e: 'reconnectStart', payload: {
|
|
141
|
-
attempt: number;
|
|
142
|
-
maxAttempts: number;
|
|
143
|
-
}): void;
|
|
144
|
-
(e: 'reconnectSuccess'): void;
|
|
145
|
-
(e: 'reconnectFailed'): void;
|
|
146
149
|
(e: 'compatWarning', payload: {
|
|
147
150
|
code: string;
|
|
148
151
|
message: string;
|
|
@@ -166,11 +169,9 @@ export interface VideoPlayerEmits {
|
|
|
166
169
|
* `recoverable` 决定盖 loading(等)还是露重试入口(不等);`reason='degraded'`
|
|
167
170
|
* 是唯一 `playable` 仍为 `true` 的值(掉帧严重但画面还在动,可以忽略)。
|
|
168
171
|
*/
|
|
169
|
-
(e: 'playableChange', payload: {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
recoverable: boolean;
|
|
173
|
-
}): void;
|
|
172
|
+
(e: 'playableChange', payload: Extract<PlayerEvent, {
|
|
173
|
+
event: 'playablechange';
|
|
174
|
+
}>['payload']): void;
|
|
174
175
|
/**
|
|
175
176
|
* 内核健康 —— **非致命内核诊断的聚合**(契约 4.1.0 / ADR-062 / issue #391)。
|
|
176
177
|
*
|
|
@@ -213,6 +214,8 @@ export interface VideoPlayerEmits {
|
|
|
213
214
|
* ⚠️ 它不是掉帧率,也不与 `stalled` 重复(后者是缓冲驱动的等待)。
|
|
214
215
|
*/
|
|
215
216
|
(e: 'frameFreeze', payload: FrameFreezePayload): void;
|
|
217
|
+
/** 实际网页全屏状态变化。 */
|
|
218
|
+
(e: 'pageFullscreenChange', payload: PageFullscreenState): void;
|
|
216
219
|
/**
|
|
217
220
|
* 用户动作(ADR-075),经白名单过滤,只含**发生在 SDK 内部**的那些。
|
|
218
221
|
*
|
|
@@ -238,6 +241,8 @@ export interface VideoPlayerExpose {
|
|
|
238
241
|
setMuted(muted: boolean): void;
|
|
239
242
|
setVolume(volume: number): void;
|
|
240
243
|
setPlaybackRate(rate: number): void;
|
|
244
|
+
/** 设置网页全屏;必须等宿主布局与 iframe 状态确认。 */
|
|
245
|
+
setPageFullscreen(active: boolean): Promise<void>;
|
|
241
246
|
/** 进入全屏(容器托管,不碰 video 原生入口,iOS 微信崩溃入口由 FullscreenGuard 中和) */
|
|
242
247
|
enterFullscreen(): Promise<void>;
|
|
243
248
|
/** 退出全屏 */
|
|
@@ -253,9 +258,7 @@ export interface VideoPlayerExpose {
|
|
|
253
258
|
setDanmakuEnabled(enabled: boolean): void;
|
|
254
259
|
/** 清空屏上弹幕(ADR-028) */
|
|
255
260
|
clearDanmaku(): void;
|
|
256
|
-
|
|
257
|
-
resetCounter?: boolean;
|
|
258
|
-
}): void;
|
|
261
|
+
retry(): Promise<void>;
|
|
259
262
|
destroy(): void;
|
|
260
263
|
getCurrentTime(): number;
|
|
261
264
|
getDuration(): number;
|
package/dist/use-player.d.ts
CHANGED
|
@@ -36,9 +36,9 @@ export declare function toConfig(props: VideoPlayerProps): PlayerConfig;
|
|
|
36
36
|
* 播放器事件 → Vue emits。名字从 wire 上的小写拼写换成 camelCase 事件名,
|
|
37
37
|
* 和 `vue-frame` 的 `forward` 逐条对应(cross-mode-parity):同样的事件、同样的 payload。
|
|
38
38
|
*
|
|
39
|
-
* **契约声明的
|
|
39
|
+
* **契约声明的 27 个事件必须一个不少地出现在这里**,由 `protocol/tests/consumer-surface.contract.test.ts`
|
|
40
40
|
* 静态断言。`video-react` 曾经漏过 4 个(seeking / seeked / waiting / playing)——
|
|
41
|
-
* 而静态 iframe 模式是裸广播、
|
|
41
|
+
* 而静态 iframe 模式是裸广播、27 个全发,于是同一份契约在几种接入方式下能收到的事件
|
|
42
42
|
* 不一样,parity 红线实际已破。别再以"业务暂时用不到"为由少接一个。
|
|
43
43
|
*/
|
|
44
44
|
export declare function forward(event: PlayerEvent, emit: VideoPlayerEmits): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@video-lab/vue",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -25,23 +25,24 @@
|
|
|
25
25
|
],
|
|
26
26
|
"sideEffects": false,
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"vue": "
|
|
28
|
+
"vue": "^3.4.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@video-lab/protocol": "
|
|
32
|
-
"@video-lab/player-
|
|
33
|
-
"@video-lab/player-
|
|
31
|
+
"@video-lab/protocol": "3.0.0",
|
|
32
|
+
"@video-lab/player-core": "3.0.0",
|
|
33
|
+
"@video-lab/player-ui": "3.0.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
37
|
-
"@vue/test-utils": "
|
|
37
|
+
"@vue/test-utils": "2.4.6",
|
|
38
38
|
"jsdom": "^24.0.0",
|
|
39
39
|
"typescript": "~5.9.0",
|
|
40
40
|
"vite": "^8.1.5",
|
|
41
41
|
"vite-plugin-dts": "^5.0.3",
|
|
42
42
|
"vitest": "^4.1.10",
|
|
43
|
-
"vue": "
|
|
44
|
-
"vue-tsc": "^2.0.0"
|
|
43
|
+
"vue": "3.4.0",
|
|
44
|
+
"vue-tsc": "^2.0.0",
|
|
45
|
+
"@vue/server-renderer": "3.4.0"
|
|
45
46
|
},
|
|
46
47
|
"description": "Video Lab Player Vue 3 inline 组件:直连 player-core 的高性能接入方式",
|
|
47
48
|
"publishConfig": {
|