@video-lab/vue 2.0.0 → 3.0.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/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(){h(),m()}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.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`reconnectstart`:t(`reconnectStart`,{attempt:e.payload.attempt,maxAttempts:e.payload.maxAttempts});break;case`reconnectsuccess`:t(`reconnectSuccess`);break;case`reconnectfailed`:t(`reconnectFailed`);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`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:{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},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.ready.play.pause.ended.timeUpdate.volumeChange.seeking.seeked.waiting.playing.qualityChange.subtitleChange.error.autoplayBlocked.reconnectStart.reconnectSuccess.reconnectFailed.compatWarning.stalled.playableChange.kernelHealth.audioHealth.bufferHealth.contextChange.sourceRoute.firstFrame.frameFreeze.userAction`.split(`.`),setup(n,{expose:r,emit:c}){let l=n,u=c,d=(0,e.shallowRef)(null),{handle:f,overlay:p,isMounted:m,handleRetry:h,dismissPauseImage:g}=s(d,l,u),_=(0,e.computed)(()=>(0,t.resolveLocaleMessages)(l.locale).messages),v=(0,e.computed)(()=>typeof l.poster==`string`?l.poster:l.poster?.url),y=(0,e.computed)(()=>typeof l.pauseImage==`string`?l.pauseImage:l.pauseImage?.url),b=()=>[v.value?i(`sentinel-poster`,{visible:p.value.posterVisible,poster:l.poster}):null,y.value?i(`sentinel-pause`,{visible:p.value.pauseImageVisible,pauseImage:l.pauseImage,"close-label":a(_.value,`close`),"onSentinel-close":g}):null,i(`sentinel-loading`,{visible:p.value.loadingVisible,text:a(_.value,`loading`)}),p.value.error?i(`sentinel-error`,{visible:!0,code:p.value.error.code,message:o(_.value,p.value.error.code,p.value.error.message),retryable:p.value.error.retryable,"retry-label":a(_.value,`retry`),"onSentinel-retry":h}):null];return r({play:()=>f.value?.play()??Promise.resolve(),pause:()=>f.value?.pause(),seek:e=>f.value?.seek(e),setMuted:e=>f.value?.setMuted(e),setVolume:e=>f.value?.setVolume(e),setPlaybackRate:e=>f.value?.setPlaybackRate(e),enterFullscreen:()=>f.value?.enterFullscreen()??Promise.resolve(),exitFullscreen:()=>f.value?.exitFullscreen()??Promise.resolve(),setQuality:e=>f.value?.setQuality(e),setSubtitle:e=>f.value?.setSubtitle(e),setLocale:e=>f.value?.setLocale(e),pushDanmaku:e=>f.value?.pushDanmaku(e),setDanmakuEnabled:e=>f.value?.setDanmakuEnabled(e),clearDanmaku:()=>f.value?.clearDanmaku(),reconnect:e=>f.value?.reconnect(e),destroy:()=>f.value?.destroy(),getCurrentTime:()=>f.value?.getCurrentTime()??0,getDuration:()=>f.value?.getDuration()??0,getPlaybackContext:()=>f.value?.getPlaybackContext()??null,getPlayerHandle:()=>f.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:d,class:`sentinel-video__player`,style:{width:`100%`,height:`100%`}},null,512),(0,e.createVNode)(b),(0,e.unref)(m)?(0,e.createCommentVNode)(``,!0):(0,e.renderSlot)(t.$slots,`ssr-placeholder`,{key:0})],4))}});exports.VideoPlayer=u;
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
@@ -19,7 +19,13 @@ function O(e, t, n) {
19
19
  let r = p(null), i = p(b), a = d(!1);
20
20
  function o(e) {
21
21
  let t = y(e);
22
- i.value = S(i.value, t), A(t, n);
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;
@@ -39,8 +45,14 @@ function O(e, t, n) {
39
45
  r.value = w({
40
46
  el: s,
41
47
  config: k(t),
48
+ pageFullscreen: t.pageFullscreen,
42
49
  onEvent: (e) => {
43
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) {
@@ -61,7 +73,8 @@ function O(e, t, n) {
61
73
  e !== void 0 && s((t) => t.setLocale(e));
62
74
  }, { deep: !0 });
63
75
  function m() {
64
- f(), u();
76
+ let e = r.value;
77
+ e && (i.value.action === "play" ? e.play() : e.retry()).catch(() => {});
65
78
  }
66
79
  function v() {
67
80
  i.value = {
@@ -80,7 +93,7 @@ function O(e, t, n) {
80
93
  }
81
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
98
  function A(e, t) {
86
99
  try {
@@ -129,18 +142,6 @@ function A(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 A(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;
@@ -183,6 +187,7 @@ function A(e, t) {
183
187
  var j = /* @__PURE__ */ a({
184
188
  __name: "VideoPlayer",
185
189
  props: {
190
+ pageFullscreen: {},
186
191
  source: {},
187
192
  autoplay: {
188
193
  type: Boolean,
@@ -200,6 +205,15 @@ var j = /* @__PURE__ */ a({
200
205
  type: Boolean,
201
206
  default: void 0
202
207
  },
208
+ showErrorOverlay: {
209
+ type: Boolean,
210
+ default: void 0
211
+ },
212
+ showLoadingOverlay: {
213
+ type: Boolean,
214
+ default: void 0
215
+ },
216
+ controlVisibility: {},
203
217
  interactive: {
204
218
  type: Boolean,
205
219
  default: void 0
@@ -222,53 +236,54 @@ var j = /* @__PURE__ */ a({
222
236
  default: void 0
223
237
  }
224
238
  },
225
- emits: /* @__PURE__ */ "playerEvent.ready.play.pause.ended.timeUpdate.volumeChange.seeking.seeked.waiting.playing.qualityChange.subtitleChange.error.autoplayBlocked.reconnectStart.reconnectSuccess.reconnectFailed.compatWarning.stalled.playableChange.kernelHealth.audioHealth.bufferHealth.contextChange.sourceRoute.firstFrame.frameFreeze.userAction".split("."),
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("."),
226
240
  setup(a, { expose: o, emit: c }) {
227
- let l = a, d = c, h = p(null), { handle: g, overlay: _, isMounted: y, handleRetry: b, dismissPauseImage: x } = O(h, l, d), S = e(() => v(l.locale).messages), C = e(() => typeof l.poster == "string" ? l.poster : l.poster?.url), w = e(() => typeof l.pauseImage == "string" ? l.pauseImage : l.pauseImage?.url), k = () => [
228
- C.value ? T("sentinel-poster", {
229
- visible: _.value.posterVisible,
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,
230
244
  poster: l.poster
231
245
  }) : null,
232
- w.value ? T("sentinel-pause", {
233
- visible: _.value.pauseImageVisible,
246
+ A.value ? T("sentinel-pause", {
247
+ visible: b.value.pauseImageVisible,
234
248
  pauseImage: l.pauseImage,
235
- "close-label": E(S.value, "close"),
236
- "onSentinel-close": x
249
+ "close-label": E(w.value, "close"),
250
+ "onSentinel-close": C
237
251
  }) : null,
238
252
  T("sentinel-loading", {
239
- visible: _.value.loadingVisible,
240
- text: E(S.value, "loading")
253
+ visible: g && b.value.loadingVisible,
254
+ text: E(w.value, "loading")
241
255
  }),
242
- _.value.error ? T("sentinel-error", {
256
+ h && b.value.error ? T("sentinel-error", {
243
257
  visible: !0,
244
- code: _.value.error.code,
245
- message: D(S.value, _.value.error.code, _.value.error.message),
246
- retryable: _.value.error.retryable,
247
- "retry-label": E(S.value, "retry"),
248
- "onSentinel-retry": b
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
249
263
  }) : null
250
264
  ];
251
265
  return o({
252
- play: () => g.value?.play() ?? Promise.resolve(),
253
- pause: () => g.value?.pause(),
254
- seek: (e) => g.value?.seek(e),
255
- setMuted: (e) => g.value?.setMuted(e),
256
- setVolume: (e) => g.value?.setVolume(e),
257
- setPlaybackRate: (e) => g.value?.setPlaybackRate(e),
258
- enterFullscreen: () => g.value?.enterFullscreen() ?? Promise.resolve(),
259
- exitFullscreen: () => g.value?.exitFullscreen() ?? Promise.resolve(),
260
- setQuality: (e) => g.value?.setQuality(e),
261
- setSubtitle: (e) => g.value?.setSubtitle(e),
262
- setLocale: (e) => g.value?.setLocale(e),
263
- pushDanmaku: (e) => g.value?.pushDanmaku(e),
264
- setDanmakuEnabled: (e) => g.value?.setDanmakuEnabled(e),
265
- clearDanmaku: () => g.value?.clearDanmaku(),
266
- reconnect: (e) => g.value?.reconnect(e),
267
- destroy: () => g.value?.destroy(),
268
- getCurrentTime: () => g.value?.getCurrentTime() ?? 0,
269
- getDuration: () => g.value?.getDuration() ?? 0,
270
- getPlaybackContext: () => g.value?.getPlaybackContext() ?? null,
271
- getPlayerHandle: () => g.value
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
272
287
  }), (e, a) => (u(), n("div", {
273
288
  class: "sentinel-video",
274
289
  style: s({
@@ -280,15 +295,15 @@ var j = /* @__PURE__ */ a({
280
295
  }, [
281
296
  r("div", {
282
297
  ref_key: "containerRef",
283
- ref: h,
298
+ ref: _,
284
299
  class: "sentinel-video__player",
285
300
  style: {
286
301
  width: "100%",
287
302
  height: "100%"
288
303
  }
289
304
  }, null, 512),
290
- i(k),
291
- m(y) ? t("", !0) : f(e.$slots, "ssr-placeholder", { key: 0 })
305
+ i(j),
306
+ m(x) ? t("", !0) : f(e.$slots, "ssr-placeholder", { key: 0 })
292
307
  ], 4));
293
308
  }
294
309
  });
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, PauseImageConfig, PlayableReason, PlaybackContext, PlaybackContextPayload, PlayerError, PlayerEvent, PosterConfig, PresetName, QualityLevel, SourceRouteEventPayload, SubtitleTrackInfo, UserActionPayload } from '@video-lab/protocol';
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
- playable: boolean;
171
- reason: PlayableReason;
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
- reconnect(options?: {
257
- resetCounter?: boolean;
258
- }): void;
261
+ retry(): Promise<void>;
259
262
  destroy(): void;
260
263
  getCurrentTime(): number;
261
264
  getDuration(): number;
@@ -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
- * **契约声明的 19 个事件必须一个不少地出现在这里**,由 `protocol/tests/consumer-surface.contract.test.ts`
39
+ * **契约声明的 27 个事件必须一个不少地出现在这里**,由 `protocol/tests/consumer-surface.contract.test.ts`
40
40
  * 静态断言。`video-react` 曾经漏过 4 个(seeking / seeked / waiting / playing)——
41
- * 而静态 iframe 模式是裸广播、19 个全发,于是同一份契约在几种接入方式下能收到的事件
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": "2.0.0",
3
+ "version": "3.0.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -28,9 +28,9 @@
28
28
  "vue": "^3.4.0"
29
29
  },
30
30
  "dependencies": {
31
- "@video-lab/protocol": "2.0.0",
32
- "@video-lab/player-core": "2.0.0",
33
- "@video-lab/player-ui": "2.0.0"
31
+ "@video-lab/protocol": "3.0.1",
32
+ "@video-lab/player-ui": "3.0.1",
33
+ "@video-lab/player-core": "3.0.1"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@vitejs/plugin-vue": "^6.0.8",