@maas/vue-equipment 0.20.1 → 0.21.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.
Files changed (42) hide show
  1. package/dist/nuxt/module.json +1 -1
  2. package/dist/nuxt/module.mjs +1 -1
  3. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDrag.mjs +15 -1
  4. package/dist/plugins/MagicDrawer/src/composables/useDrawerApi.d.ts +2 -2
  5. package/dist/plugins/MagicDrawer/src/types/index.d.ts +1 -0
  6. package/dist/plugins/MagicDrawer/src/utils/defaultOptions.mjs +1 -0
  7. package/dist/plugins/MagicPlayer/index.d.ts +3 -3
  8. package/dist/plugins/MagicPlayer/index.mjs +6 -3
  9. package/dist/plugins/MagicPlayer/src/components/MagicPlayer.vue +24 -18
  10. package/dist/plugins/MagicPlayer/src/components/MagicPlayer.vue.d.ts +8 -5
  11. package/dist/plugins/MagicPlayer/src/components/MagicPlayerControls.vue +20 -9
  12. package/dist/plugins/MagicPlayer/src/components/MagicPlayerMuxPopover.vue +2 -4
  13. package/dist/plugins/MagicPlayer/src/components/MagicPlayerOverlay.vue +29 -25
  14. package/dist/plugins/MagicPlayer/src/components/MagicPlayerOverlay.vue.d.ts +1 -0
  15. package/dist/plugins/MagicPlayer/src/components/MagicPlayerPoster.vue +27 -0
  16. package/dist/plugins/MagicPlayer/src/components/MagicPlayerPoster.vue.d.ts +21 -0
  17. package/dist/plugins/MagicPlayer/src/components/MagicPlayerTimeline.vue +10 -7
  18. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerControlsApi.d.ts +34 -0
  19. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerControlsApi.mjs +297 -0
  20. package/dist/plugins/MagicPlayer/src/composables/private/{useMediaApi.d.ts → usePlayerMediaApi.d.ts} +11 -7
  21. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerMediaApi.mjs +263 -0
  22. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerRuntime.d.ts +12 -0
  23. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerRuntime.mjs +70 -0
  24. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStateEmitter.d.ts +15 -0
  25. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStateEmitter.mjs +9 -0
  26. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerVideoApi.d.ts +22 -0
  27. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerVideoApi.mjs +142 -0
  28. package/dist/plugins/MagicPlayer/src/composables/usePlayerApi.d.ts +63 -5
  29. package/dist/plugins/MagicPlayer/src/composables/usePlayerApi.mjs +12 -65
  30. package/dist/plugins/MagicPlayer/src/types/index.d.ts +12 -25
  31. package/package.json +1 -1
  32. package/dist/plugins/MagicPlayer/src/composables/private/useControlsApi.d.ts +0 -17
  33. package/dist/plugins/MagicPlayer/src/composables/private/useControlsApi.mjs +0 -131
  34. package/dist/plugins/MagicPlayer/src/composables/private/useMediaApi.mjs +0 -122
  35. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerInternalApi.d.ts +0 -18
  36. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerInternalApi.mjs +0 -63
  37. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStore.d.ts +0 -20
  38. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStore.mjs +0 -42
  39. package/dist/plugins/MagicPlayer/src/composables/private/useRuntimeSourceProvider.d.ts +0 -6
  40. package/dist/plugins/MagicPlayer/src/composables/private/useRuntimeSourceProvider.mjs +0 -48
  41. package/dist/plugins/MagicPlayer/src/utils/index.d.ts +0 -1
  42. package/dist/plugins/MagicPlayer/src/utils/index.mjs +0 -8
@@ -0,0 +1,297 @@
1
+ import { ref, computed, watch, toValue } from "vue";
2
+ import {
3
+ useResizeObserver,
4
+ useEventListener,
5
+ defaultWindow
6
+ } from "@vueuse/core";
7
+ import { clampValue, mapValue } from "@maas/vue-equipment/utils";
8
+ import { usePlayerMediaApi } from "./usePlayerMediaApi.mjs";
9
+ import { usePlayerVideoApi } from "./usePlayerVideoApi.mjs";
10
+ import { usePlayerStateEmitter } from "./usePlayerStateEmitter.mjs";
11
+ export function usePlayerControlsApi(args) {
12
+ const resumePlay = ref(false);
13
+ const barRect = ref(void 0);
14
+ const trackRect = ref(void 0);
15
+ const popoverRect = ref(void 0);
16
+ const { trackRef, barRef, popoverRef } = args;
17
+ const { buffered, duration, playing, currentTime } = usePlayerMediaApi({
18
+ id: toValue(args.id)
19
+ });
20
+ const { play, pause, seek } = usePlayerVideoApi({
21
+ id: toValue(args.id)
22
+ });
23
+ const dragging = ref(false);
24
+ const mouseEntered = ref(false);
25
+ const seekedTime = ref(0);
26
+ const seekedPercentage = ref(0);
27
+ const scrubbedPercentage = ref(0);
28
+ const thumbPercentage = ref(0);
29
+ const popoverOffsetX = ref(0);
30
+ const bufferedPercentage = computed(() => {
31
+ if (!buffered)
32
+ return 0;
33
+ const endBuffer = buffered.value?.length > 0 ? buffered.value[0][1] : 0;
34
+ const percentage = endBuffer / duration.value * 100;
35
+ return clampValue(percentage, 0, thumbPercentage.value);
36
+ });
37
+ function getPopoverOffsetX() {
38
+ if (!trackRect.value || !popoverRect.value || !barRect.value) {
39
+ return 0;
40
+ } else {
41
+ const trackFactor = barRect.value.width / trackRect.value.width;
42
+ const offsetXPercentage = Math.abs(trackRect.value.x - barRect.value.x) / barRect.value.width * 100;
43
+ const popoverWidthPercentage = popoverRect.value.width / barRect.value.width * 100;
44
+ const maxPercentage = 100 - popoverWidthPercentage;
45
+ const percentage = seekedPercentage.value / trackFactor + offsetXPercentage - popoverWidthPercentage / 2;
46
+ popoverOffsetX.value = clampValue(percentage, 0, maxPercentage);
47
+ }
48
+ }
49
+ function getTimelineTrackSize() {
50
+ if (!toValue(trackRef)) {
51
+ return;
52
+ }
53
+ trackRect.value = toValue(trackRef).getBoundingClientRect();
54
+ thumbPercentage.value = 100 - trackRect.value.height / trackRect.value.width * 100;
55
+ }
56
+ function getPopoverSizes() {
57
+ if (!toValue(barRef) || !toValue(popoverRef)) {
58
+ return;
59
+ }
60
+ barRect.value = toValue(barRef).getBoundingClientRect();
61
+ popoverRect.value = toValue(popoverRef).getBoundingClientRect();
62
+ }
63
+ function seekToTrackPosition(absX) {
64
+ if (!trackRect.value) {
65
+ throw new Error("trackRect is undefined");
66
+ }
67
+ const relX = absX - trackRect.value.x - trackRect.value.height / 2;
68
+ const percentage = Math.round(relX / trackRect.value.width * 100);
69
+ seekedPercentage.value = clampValue(percentage, 0, thumbPercentage.value);
70
+ seekedTime.value = duration.value * mapValue(seekedPercentage.value, 0, thumbPercentage.value, 0, 100) / 100;
71
+ if (dragging.value) {
72
+ scrubbedPercentage.value = seekedPercentage.value;
73
+ seek(seekedTime.value);
74
+ }
75
+ getPopoverOffsetX();
76
+ }
77
+ function onMouseenter() {
78
+ getTimelineTrackSize();
79
+ getPopoverSizes();
80
+ mouseEntered.value = true;
81
+ }
82
+ function onMouseleave() {
83
+ mouseEntered.value = false;
84
+ dragging.value = false;
85
+ seekedTime.value = 0;
86
+ }
87
+ function onPointerdown(e) {
88
+ dragging.value = true;
89
+ resumePlay.value = playing.value;
90
+ pause();
91
+ const x = e instanceof MouseEvent ? e.pageX : e.touches[0].pageX;
92
+ seekToTrackPosition(x);
93
+ }
94
+ function onPointerup() {
95
+ dragging.value = false;
96
+ if (resumePlay.value) {
97
+ play();
98
+ }
99
+ }
100
+ function onPointermove(e) {
101
+ const x = e instanceof MouseEvent ? e.pageX : e.touches[0].pageX;
102
+ seekToTrackPosition(x);
103
+ }
104
+ watch(() => trackRef, getTimelineTrackSize);
105
+ watch(() => popoverRef, getPopoverSizes);
106
+ watch(() => barRef, getPopoverSizes);
107
+ watch(currentTime, (value) => {
108
+ const percentage = value / duration?.value * 100;
109
+ scrubbedPercentage.value = mapValue(
110
+ percentage,
111
+ 0,
112
+ 100,
113
+ 0,
114
+ thumbPercentage.value
115
+ );
116
+ });
117
+ useResizeObserver(trackRef, getTimelineTrackSize);
118
+ useResizeObserver(popoverRef, getPopoverSizes);
119
+ useEventListener(
120
+ defaultWindow,
121
+ "resize",
122
+ () => {
123
+ getTimelineTrackSize;
124
+ getPopoverSizes;
125
+ },
126
+ {
127
+ passive: true
128
+ }
129
+ );
130
+ const emitter = usePlayerStateEmitter();
131
+ emitter.on("update", (payload) => {
132
+ if (payload.id !== toValue(args.id))
133
+ return;
134
+ if (payload.api === "controls") {
135
+ switch (payload.key) {
136
+ case "dragging": {
137
+ dragging.value = payload.value;
138
+ break;
139
+ }
140
+ case "mouseEntered": {
141
+ mouseEntered.value = payload.value;
142
+ break;
143
+ }
144
+ case "seekedTime": {
145
+ seekedTime.value = payload.value;
146
+ break;
147
+ }
148
+ case "seekedPercentage": {
149
+ seekedPercentage.value = payload.value;
150
+ break;
151
+ }
152
+ case "scrubbedPercentage": {
153
+ scrubbedPercentage.value = payload.value;
154
+ break;
155
+ }
156
+ case "thumbPercentage": {
157
+ thumbPercentage.value = payload.value;
158
+ break;
159
+ }
160
+ case "popoverOffsetX": {
161
+ popoverOffsetX.value = payload.value;
162
+ break;
163
+ }
164
+ case "barRect": {
165
+ barRect.value = payload.value;
166
+ break;
167
+ }
168
+ case "trackRect": {
169
+ trackRect.value = payload.value;
170
+ break;
171
+ }
172
+ case "popoverRect": {
173
+ popoverRect.value = payload.value;
174
+ break;
175
+ }
176
+ }
177
+ }
178
+ });
179
+ watch(dragging, (value) => {
180
+ emitter.emit("update", {
181
+ id: toValue(args.id),
182
+ api: "controls",
183
+ key: "dragging",
184
+ value
185
+ });
186
+ });
187
+ watch(mouseEntered, (value) => {
188
+ emitter.emit("update", {
189
+ id: toValue(args.id),
190
+ api: "controls",
191
+ key: "mouseEntered",
192
+ value
193
+ });
194
+ });
195
+ watch(seekedTime, (value) => {
196
+ emitter.emit("update", {
197
+ id: toValue(args.id),
198
+ api: "controls",
199
+ key: "seekedTime",
200
+ value
201
+ });
202
+ });
203
+ watch(seekedPercentage, (value) => {
204
+ emitter.emit("update", {
205
+ id: toValue(args.id),
206
+ api: "controls",
207
+ key: "seekedPercentage",
208
+ value
209
+ });
210
+ });
211
+ watch(scrubbedPercentage, (value) => {
212
+ emitter.emit("update", {
213
+ id: toValue(args.id),
214
+ api: "controls",
215
+ key: "scrubbedPercentage",
216
+ value
217
+ });
218
+ });
219
+ watch(bufferedPercentage, (value) => {
220
+ emitter.emit("update", {
221
+ id: toValue(args.id),
222
+ api: "controls",
223
+ key: "bufferedPercentage",
224
+ value
225
+ });
226
+ });
227
+ watch(thumbPercentage, (value) => {
228
+ emitter.emit("update", {
229
+ id: toValue(args.id),
230
+ api: "controls",
231
+ key: "thumbPercentage",
232
+ value
233
+ });
234
+ });
235
+ watch(popoverOffsetX, (value) => {
236
+ emitter.emit("update", {
237
+ id: toValue(args.id),
238
+ api: "controls",
239
+ key: "popoverOffsetX",
240
+ value
241
+ });
242
+ });
243
+ watch(resumePlay, (value) => {
244
+ emitter.emit("update", {
245
+ id: toValue(args.id),
246
+ api: "controls",
247
+ key: "resumePlay",
248
+ value
249
+ });
250
+ });
251
+ watch(barRect, (value) => {
252
+ if (!value)
253
+ return;
254
+ emitter.emit("update", {
255
+ id: toValue(args.id),
256
+ api: "controls",
257
+ key: "barRect",
258
+ value
259
+ });
260
+ });
261
+ watch(trackRect, (value) => {
262
+ if (!value)
263
+ return;
264
+ emitter.emit("update", {
265
+ id: toValue(args.id),
266
+ api: "controls",
267
+ key: "trackRect",
268
+ value
269
+ });
270
+ });
271
+ watch(popoverRect, (value) => {
272
+ if (!value)
273
+ return;
274
+ emitter.emit("update", {
275
+ id: toValue(args.id),
276
+ api: "controls",
277
+ key: "popoverRect",
278
+ value
279
+ });
280
+ });
281
+ return {
282
+ mouseEntered,
283
+ dragging,
284
+ seekedTime,
285
+ seekedPercentage,
286
+ scrubbedPercentage,
287
+ bufferedPercentage,
288
+ thumbPercentage,
289
+ popoverOffsetX,
290
+ onMouseenter,
291
+ onMouseleave,
292
+ onPointerdown,
293
+ onPointerup,
294
+ onPointermove,
295
+ trackRect
296
+ };
297
+ }
@@ -1,15 +1,19 @@
1
- import type { UseMediaApiArgs } from '../../types.js';
2
- export declare function useMediaApi(args: UseMediaApiArgs): {
1
+ import { type MaybeRef } from 'vue';
2
+ export type UsePlayerMediaApiArgs = {
3
+ id: MaybeRef<string>;
4
+ mediaRef?: MaybeRef<HTMLMediaElement | undefined>;
5
+ };
6
+ export declare function usePlayerMediaApi(args: UsePlayerMediaApiArgs): {
3
7
  currentTime: import("vue").Ref<number>;
4
8
  duration: import("vue").Ref<number>;
5
- waiting: import("vue").Ref<boolean>;
6
9
  seeking: import("vue").Ref<boolean>;
10
+ volume: import("vue").Ref<number>;
11
+ rate: import("vue").Ref<number>;
12
+ waiting: import("vue").Ref<boolean>;
7
13
  ended: import("vue").Ref<boolean>;
14
+ playing: import("vue").Ref<boolean>;
8
15
  stalled: import("vue").Ref<boolean>;
9
16
  buffered: import("vue").Ref<[number, number][]>;
10
- playing: import("vue").Ref<boolean>;
11
- rate: import("vue").Ref<number>;
12
- volume: import("vue").Ref<number>;
13
17
  muted: import("vue").Ref<boolean>;
14
18
  };
15
- export type UseMediaApiReturn = ReturnType<typeof useMediaApi>;
19
+ export type UsePlayerMediaApiReturn = ReturnType<typeof usePlayerMediaApi>;
@@ -0,0 +1,263 @@
1
+ import { ref, watch, unref, toValue } from "vue";
2
+ import { useEventListener, watchIgnorable } from "@vueuse/core";
3
+ import { usePlayerStateEmitter } from "./usePlayerStateEmitter.mjs";
4
+ export function usePlayerMediaApi(args) {
5
+ const currentTime = ref(0);
6
+ const duration = ref(0);
7
+ const seeking = ref(false);
8
+ const volume = ref(1);
9
+ const rate = ref(1);
10
+ const waiting = ref(false);
11
+ const ended = ref(false);
12
+ const playing = ref(false);
13
+ const stalled = ref(false);
14
+ const buffered = ref([]);
15
+ const muted = ref(false);
16
+ const { mediaRef } = args;
17
+ function timeRangeToArray(timeRanges) {
18
+ let ranges = [];
19
+ for (let i = 0; i < timeRanges.length; ++i)
20
+ ranges = [...ranges, [timeRanges.start(i), timeRanges.end(i)]];
21
+ return ranges;
22
+ }
23
+ watch(volume, () => {
24
+ const el = toValue(mediaRef);
25
+ if (!el)
26
+ return;
27
+ el.volume = volume.value;
28
+ });
29
+ watch(muted, () => {
30
+ const el = toValue(mediaRef);
31
+ if (!el)
32
+ return;
33
+ el.muted = muted.value;
34
+ });
35
+ watch(rate, () => {
36
+ const el = toValue(mediaRef);
37
+ if (!el)
38
+ return;
39
+ el.playbackRate = rate.value;
40
+ });
41
+ if (toValue(mediaRef)) {
42
+ watch([mediaRef], () => {
43
+ const el = toValue(mediaRef);
44
+ if (!el)
45
+ return;
46
+ el.volume = volume.value;
47
+ el.muted = muted.value;
48
+ el.playbackRate = rate.value;
49
+ });
50
+ }
51
+ const { ignoreUpdates: ignoreCurrentTimeUpdates } = watchIgnorable(
52
+ currentTime,
53
+ (time) => {
54
+ const el = toValue(mediaRef);
55
+ if (!el)
56
+ return;
57
+ el.currentTime = unref(time);
58
+ }
59
+ );
60
+ const { ignoreUpdates: ignorePlayingUpdates } = watchIgnorable(
61
+ playing,
62
+ (isPlaying) => {
63
+ const el = toValue(mediaRef);
64
+ if (!el)
65
+ return;
66
+ isPlaying ? el.play() : el.pause();
67
+ }
68
+ );
69
+ useEventListener(mediaRef, "timeupdate", () => {
70
+ ignoreCurrentTimeUpdates(
71
+ () => currentTime.value = toValue(mediaRef).currentTime
72
+ );
73
+ });
74
+ useEventListener(mediaRef, "durationchange", () => {
75
+ duration.value = toValue(mediaRef).duration;
76
+ });
77
+ useEventListener(mediaRef, "progress", () => {
78
+ buffered.value = timeRangeToArray(toValue(mediaRef).buffered);
79
+ });
80
+ useEventListener(mediaRef, "seeking", () => {
81
+ seeking.value = true;
82
+ });
83
+ useEventListener(mediaRef, "seeked", () => {
84
+ seeking.value = false;
85
+ });
86
+ useEventListener(mediaRef, ["waiting", "loadstart"], () => {
87
+ waiting.value = true;
88
+ ignorePlayingUpdates(() => playing.value = false);
89
+ });
90
+ useEventListener(mediaRef, "loadeddata", () => {
91
+ waiting.value = false;
92
+ });
93
+ useEventListener(mediaRef, "playing", () => {
94
+ waiting.value = false;
95
+ ended.value = false;
96
+ ignorePlayingUpdates(() => playing.value = true);
97
+ });
98
+ useEventListener(mediaRef, "ratechange", () => {
99
+ rate.value = toValue(mediaRef).playbackRate;
100
+ });
101
+ useEventListener(mediaRef, "stalled", () => {
102
+ stalled.value = true;
103
+ });
104
+ useEventListener(mediaRef, "ended", () => {
105
+ ended.value = true;
106
+ });
107
+ useEventListener(mediaRef, "pause", () => {
108
+ playing.value = false;
109
+ });
110
+ useEventListener(mediaRef, "play", () => {
111
+ playing.value = true;
112
+ });
113
+ useEventListener(mediaRef, "volumechange", () => {
114
+ const el = toValue(mediaRef);
115
+ if (!el)
116
+ return;
117
+ volume.value = el.volume;
118
+ muted.value = el.muted;
119
+ });
120
+ const emitter = usePlayerStateEmitter();
121
+ emitter.on("update", (payload) => {
122
+ if (payload.id !== toValue(args.id))
123
+ return;
124
+ if (payload.api === "media") {
125
+ switch (payload.key) {
126
+ case "currentTime":
127
+ currentTime.value = payload.value;
128
+ break;
129
+ case "duration":
130
+ duration.value = payload.value;
131
+ break;
132
+ case "seeking":
133
+ seeking.value = payload.value;
134
+ break;
135
+ case "volume":
136
+ volume.value = payload.value;
137
+ break;
138
+ case "rate":
139
+ rate.value = payload.value;
140
+ break;
141
+ case "waiting":
142
+ waiting.value = payload.value;
143
+ break;
144
+ case "ended":
145
+ ended.value = payload.value;
146
+ break;
147
+ case "playing":
148
+ playing.value = payload.value;
149
+ break;
150
+ case "stalled":
151
+ stalled.value = payload.value;
152
+ break;
153
+ case "buffered":
154
+ buffered.value = payload.value;
155
+ break;
156
+ case "muted":
157
+ muted.value = payload.value;
158
+ break;
159
+ }
160
+ }
161
+ });
162
+ watch(currentTime, (value) => {
163
+ emitter.emit("update", {
164
+ id: toValue(args.id),
165
+ api: "media",
166
+ key: "currentTime",
167
+ value
168
+ });
169
+ });
170
+ watch(duration, (value) => {
171
+ emitter.emit("update", {
172
+ id: toValue(args.id),
173
+ api: "media",
174
+ key: "duration",
175
+ value
176
+ });
177
+ });
178
+ watch(seeking, (value) => {
179
+ emitter.emit("update", {
180
+ id: toValue(args.id),
181
+ api: "media",
182
+ key: "seeking",
183
+ value
184
+ });
185
+ });
186
+ watch(volume, (value) => {
187
+ emitter.emit("update", {
188
+ id: toValue(args.id),
189
+ api: "media",
190
+ key: "volume",
191
+ value
192
+ });
193
+ });
194
+ watch(rate, (value) => {
195
+ emitter.emit("update", {
196
+ id: toValue(args.id),
197
+ api: "media",
198
+ key: "rate",
199
+ value
200
+ });
201
+ });
202
+ watch(waiting, (value) => {
203
+ emitter.emit("update", {
204
+ id: toValue(args.id),
205
+ api: "media",
206
+ key: "waiting",
207
+ value
208
+ });
209
+ });
210
+ watch(ended, (value) => {
211
+ emitter.emit("update", {
212
+ id: toValue(args.id),
213
+ api: "media",
214
+ key: "ended",
215
+ value
216
+ });
217
+ });
218
+ watch(playing, (value) => {
219
+ emitter.emit("update", {
220
+ id: toValue(args.id),
221
+ api: "media",
222
+ key: "playing",
223
+ value
224
+ });
225
+ });
226
+ watch(stalled, (value) => {
227
+ emitter.emit("update", {
228
+ id: toValue(args.id),
229
+ api: "media",
230
+ key: "stalled",
231
+ value
232
+ });
233
+ });
234
+ watch(buffered, (value) => {
235
+ emitter.emit("update", {
236
+ id: toValue(args.id),
237
+ api: "media",
238
+ key: "buffered",
239
+ value
240
+ });
241
+ });
242
+ watch(muted, (value) => {
243
+ emitter.emit("update", {
244
+ id: toValue(args.id),
245
+ api: "media",
246
+ key: "muted",
247
+ value
248
+ });
249
+ });
250
+ return {
251
+ currentTime,
252
+ duration,
253
+ seeking,
254
+ volume,
255
+ rate,
256
+ waiting,
257
+ ended,
258
+ playing,
259
+ stalled,
260
+ buffered,
261
+ muted
262
+ };
263
+ }
@@ -0,0 +1,12 @@
1
+ import { type MaybeRef } from 'vue';
2
+ import type { SourceType } from '../../types.js';
3
+ export type UsePlayerRuntimeArgs = {
4
+ id: MaybeRef<string>;
5
+ mediaRef?: MaybeRef<HTMLVideoElement | undefined>;
6
+ srcType?: SourceType;
7
+ src?: string;
8
+ };
9
+ export declare function usePlayerRuntime(args: UsePlayerRuntimeArgs): {
10
+ loaded: import("vue").Ref<boolean>;
11
+ };
12
+ export type UsePlayerRuntimeReturn = ReturnType<typeof usePlayerRuntime>;
@@ -0,0 +1,70 @@
1
+ import { ref, watch, onMounted, onUnmounted, toValue } from "vue";
2
+ import { usePlayerStateEmitter } from "./usePlayerStateEmitter.mjs";
3
+ export function usePlayerRuntime(args) {
4
+ let hls;
5
+ const loaded = ref(false);
6
+ const { mediaRef, srcType, src } = args;
7
+ const useNative = () => {
8
+ const el = toValue(mediaRef);
9
+ if (!el || !src)
10
+ return;
11
+ el.src = src;
12
+ el.addEventListener(
13
+ "loadeddata",
14
+ () => {
15
+ loaded.value = true;
16
+ },
17
+ { once: true }
18
+ );
19
+ el.load();
20
+ };
21
+ const useHlsJS = async () => {
22
+ const el = toValue(mediaRef);
23
+ if (!el)
24
+ return;
25
+ const { default: Hls } = await import("hls.js");
26
+ hls = new Hls();
27
+ if (!Hls.isSupported()) {
28
+ useNative();
29
+ } else if (src) {
30
+ hls.loadSource(src);
31
+ hls.attachMedia(el);
32
+ hls.on(Hls.Events.FRAG_LOADED, () => {
33
+ loaded.value = true;
34
+ });
35
+ }
36
+ };
37
+ onMounted(() => {
38
+ if (srcType === "native") {
39
+ useNative();
40
+ } else if (srcType === "hls") {
41
+ useHlsJS();
42
+ }
43
+ });
44
+ onUnmounted(() => {
45
+ hls?.destroy();
46
+ });
47
+ const emitter = usePlayerStateEmitter();
48
+ emitter.on("update", (payload) => {
49
+ if (payload.id !== toValue(args.id))
50
+ return;
51
+ if (payload.api === "runtime") {
52
+ switch (payload.key) {
53
+ case "loaded":
54
+ loaded.value = payload.value;
55
+ break;
56
+ }
57
+ }
58
+ });
59
+ watch(loaded, (value) => {
60
+ emitter.emit("update", {
61
+ id: toValue(args.id),
62
+ api: "runtime",
63
+ key: "loaded",
64
+ value
65
+ });
66
+ });
67
+ return {
68
+ loaded
69
+ };
70
+ }
@@ -0,0 +1,15 @@
1
+ import type { PlayerPrivateEvents } from '../../types.js';
2
+ export declare function usePlayerStateEmitter(): {
3
+ on: {
4
+ <Key extends "update">(type: Key, handler: import("mitt").Handler<PlayerPrivateEvents[Key]>): void;
5
+ (type: "*", handler: import("mitt").WildcardHandler<PlayerPrivateEvents>): void;
6
+ };
7
+ off: {
8
+ <Key_1 extends "update">(type: Key_1, handler?: import("mitt").Handler<PlayerPrivateEvents[Key_1]> | undefined): void;
9
+ (type: "*", handler: import("mitt").WildcardHandler<PlayerPrivateEvents>): void;
10
+ };
11
+ emit: {
12
+ <Key_2 extends "update">(type: Key_2, event: PlayerPrivateEvents[Key_2]): void;
13
+ <Key_3 extends "update">(type: undefined extends PlayerPrivateEvents[Key_3] ? Key_3 : never): void;
14
+ };
15
+ };
@@ -0,0 +1,9 @@
1
+ import mitt from "mitt";
2
+ const emitter = mitt();
3
+ export function usePlayerStateEmitter() {
4
+ return {
5
+ on: emitter.on,
6
+ off: emitter.off,
7
+ emit: emitter.emit
8
+ };
9
+ }