@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.
- package/dist/nuxt/module.json +1 -1
- package/dist/nuxt/module.mjs +1 -1
- package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDrag.mjs +15 -1
- package/dist/plugins/MagicDrawer/src/composables/useDrawerApi.d.ts +2 -2
- package/dist/plugins/MagicDrawer/src/types/index.d.ts +1 -0
- package/dist/plugins/MagicDrawer/src/utils/defaultOptions.mjs +1 -0
- package/dist/plugins/MagicPlayer/index.d.ts +3 -3
- package/dist/plugins/MagicPlayer/index.mjs +6 -3
- package/dist/plugins/MagicPlayer/src/components/MagicPlayer.vue +24 -18
- package/dist/plugins/MagicPlayer/src/components/MagicPlayer.vue.d.ts +8 -5
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerControls.vue +20 -9
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerMuxPopover.vue +2 -4
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerOverlay.vue +29 -25
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerOverlay.vue.d.ts +1 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerPoster.vue +27 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerPoster.vue.d.ts +21 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerTimeline.vue +10 -7
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerControlsApi.d.ts +34 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerControlsApi.mjs +297 -0
- package/dist/plugins/MagicPlayer/src/composables/private/{useMediaApi.d.ts → usePlayerMediaApi.d.ts} +11 -7
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerMediaApi.mjs +263 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerRuntime.d.ts +12 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerRuntime.mjs +70 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStateEmitter.d.ts +15 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStateEmitter.mjs +9 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerVideoApi.d.ts +22 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerVideoApi.mjs +142 -0
- package/dist/plugins/MagicPlayer/src/composables/usePlayerApi.d.ts +63 -5
- package/dist/plugins/MagicPlayer/src/composables/usePlayerApi.mjs +12 -65
- package/dist/plugins/MagicPlayer/src/types/index.d.ts +12 -25
- package/package.json +1 -1
- package/dist/plugins/MagicPlayer/src/composables/private/useControlsApi.d.ts +0 -17
- package/dist/plugins/MagicPlayer/src/composables/private/useControlsApi.mjs +0 -131
- package/dist/plugins/MagicPlayer/src/composables/private/useMediaApi.mjs +0 -122
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerInternalApi.d.ts +0 -18
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerInternalApi.mjs +0 -63
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStore.d.ts +0 -20
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStore.mjs +0 -42
- package/dist/plugins/MagicPlayer/src/composables/private/useRuntimeSourceProvider.d.ts +0 -6
- package/dist/plugins/MagicPlayer/src/composables/private/useRuntimeSourceProvider.mjs +0 -48
- package/dist/plugins/MagicPlayer/src/utils/index.d.ts +0 -1
- package/dist/plugins/MagicPlayer/src/utils/index.mjs +0 -8
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type MaybeRef, type Ref } from 'vue';
|
|
2
|
+
export type UsePlayerVideoApiArgs = {
|
|
3
|
+
id: MaybeRef<string>;
|
|
4
|
+
playerRef?: MaybeRef<HTMLElement | undefined>;
|
|
5
|
+
videoRef?: MaybeRef<HTMLVideoElement | undefined>;
|
|
6
|
+
};
|
|
7
|
+
export declare function usePlayerVideoApi(args: UsePlayerVideoApiArgs): {
|
|
8
|
+
mouseEntered: Ref<boolean>;
|
|
9
|
+
isFullscreen: Ref<boolean>;
|
|
10
|
+
touched: Ref<boolean>;
|
|
11
|
+
play: () => void;
|
|
12
|
+
pause: () => void;
|
|
13
|
+
togglePlay: () => void;
|
|
14
|
+
seek: (time: number) => void;
|
|
15
|
+
mute: () => void;
|
|
16
|
+
unmute: () => void;
|
|
17
|
+
enterFullscreen: () => void;
|
|
18
|
+
exitFullscreen: () => void;
|
|
19
|
+
onMouseenter: () => void;
|
|
20
|
+
onMouseleave: () => void;
|
|
21
|
+
};
|
|
22
|
+
export type UsePlayerVideoApiReturn = ReturnType<typeof usePlayerVideoApi>;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { ref, watch, toValue } from "vue";
|
|
2
|
+
import { useFullscreen } from "@vueuse/core";
|
|
3
|
+
import { isIOS } from "@maas/vue-equipment/utils";
|
|
4
|
+
import { usePlayerStateEmitter } from "./usePlayerStateEmitter.mjs";
|
|
5
|
+
import { usePlayerMediaApi } from "./usePlayerMediaApi.mjs";
|
|
6
|
+
export function usePlayerVideoApi(args) {
|
|
7
|
+
const fullscreenTarget = ref(void 0);
|
|
8
|
+
const { playing, currentTime, muted } = usePlayerMediaApi({
|
|
9
|
+
id: toValue(args.id)
|
|
10
|
+
});
|
|
11
|
+
const { playerRef, videoRef } = args;
|
|
12
|
+
const touched = ref(false);
|
|
13
|
+
const mouseEntered = ref(false);
|
|
14
|
+
const { isFullscreen, enter, exit } = useFullscreen(fullscreenTarget);
|
|
15
|
+
function play() {
|
|
16
|
+
playing.value = true;
|
|
17
|
+
}
|
|
18
|
+
function pause() {
|
|
19
|
+
playing.value = false;
|
|
20
|
+
}
|
|
21
|
+
function togglePlay() {
|
|
22
|
+
playing.value = !playing.value;
|
|
23
|
+
}
|
|
24
|
+
function seek(time) {
|
|
25
|
+
currentTime.value = time;
|
|
26
|
+
}
|
|
27
|
+
function mute() {
|
|
28
|
+
muted.value = true;
|
|
29
|
+
}
|
|
30
|
+
function unmute() {
|
|
31
|
+
muted.value = false;
|
|
32
|
+
}
|
|
33
|
+
function onMouseenter() {
|
|
34
|
+
mouseEntered.value = true;
|
|
35
|
+
}
|
|
36
|
+
function onMouseleave() {
|
|
37
|
+
mouseEntered.value = false;
|
|
38
|
+
}
|
|
39
|
+
function enterFullscreen() {
|
|
40
|
+
if (!fullscreenTarget.value) {
|
|
41
|
+
console.error("No fullscreen target found");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
enter();
|
|
45
|
+
}
|
|
46
|
+
function exitFullscreen() {
|
|
47
|
+
if (!fullscreenTarget.value) {
|
|
48
|
+
console.error("No fullscreen target found");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
exit();
|
|
52
|
+
}
|
|
53
|
+
watch(playing, (value) => {
|
|
54
|
+
if (!touched.value && value) {
|
|
55
|
+
touched.value = true;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
if (playerRef && !videoRef) {
|
|
59
|
+
watch(playerRef, (value) => {
|
|
60
|
+
if (value) {
|
|
61
|
+
fullscreenTarget.value = toValue(value);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (videoRef && !playerRef) {
|
|
66
|
+
watch(videoRef, (value) => {
|
|
67
|
+
if (value) {
|
|
68
|
+
fullscreenTarget.value = toValue(value);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (videoRef && playerRef) {
|
|
73
|
+
watch([playerRef, videoRef], ([player, video]) => {
|
|
74
|
+
if (player && video) {
|
|
75
|
+
fullscreenTarget.value = isIOS() ? toValue(video) : toValue(player);
|
|
76
|
+
} else if (player) {
|
|
77
|
+
fullscreenTarget.value = toValue(player);
|
|
78
|
+
} else if (video) {
|
|
79
|
+
fullscreenTarget.value = toValue(video);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const emitter = usePlayerStateEmitter();
|
|
84
|
+
emitter.on("update", (payload) => {
|
|
85
|
+
if (payload.id !== toValue(args.id))
|
|
86
|
+
return;
|
|
87
|
+
if (payload.api === "player") {
|
|
88
|
+
switch (payload.key) {
|
|
89
|
+
case "mouseEntered":
|
|
90
|
+
mouseEntered.value = payload.value;
|
|
91
|
+
break;
|
|
92
|
+
case "fullscreenTarget":
|
|
93
|
+
fullscreenTarget.value = payload.value;
|
|
94
|
+
break;
|
|
95
|
+
case "touched":
|
|
96
|
+
touched.value = payload.value;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
watch(mouseEntered, (value) => {
|
|
102
|
+
emitter.emit("update", {
|
|
103
|
+
id: toValue(args.id),
|
|
104
|
+
api: "player",
|
|
105
|
+
key: "mouseEntered",
|
|
106
|
+
value
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
watch(touched, (value) => {
|
|
110
|
+
emitter.emit("update", {
|
|
111
|
+
id: toValue(args.id),
|
|
112
|
+
api: "player",
|
|
113
|
+
key: "touched",
|
|
114
|
+
value
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
watch(fullscreenTarget, (value) => {
|
|
118
|
+
if (!value)
|
|
119
|
+
return;
|
|
120
|
+
emitter.emit("update", {
|
|
121
|
+
id: toValue(args.id),
|
|
122
|
+
api: "player",
|
|
123
|
+
key: "fullscreenTarget",
|
|
124
|
+
value
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
return {
|
|
128
|
+
mouseEntered,
|
|
129
|
+
isFullscreen,
|
|
130
|
+
touched,
|
|
131
|
+
play,
|
|
132
|
+
pause,
|
|
133
|
+
togglePlay,
|
|
134
|
+
seek,
|
|
135
|
+
mute,
|
|
136
|
+
unmute,
|
|
137
|
+
enterFullscreen,
|
|
138
|
+
exitFullscreen,
|
|
139
|
+
onMouseenter,
|
|
140
|
+
onMouseleave
|
|
141
|
+
};
|
|
142
|
+
}
|
|
@@ -1,6 +1,64 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
instance: import("vue").ComputedRef<import("./private/usePlayerStore").PlayerInstance>;
|
|
1
|
+
import type { MaybeRef } from '@vueuse/core';
|
|
2
|
+
type usePlayerApiArgs = {
|
|
3
|
+
id: MaybeRef<string>;
|
|
5
4
|
};
|
|
6
|
-
export
|
|
5
|
+
export declare function usePlayerApi(args: usePlayerApiArgs): {
|
|
6
|
+
mediaApi: {
|
|
7
|
+
currentTime: import("vue").Ref<number>;
|
|
8
|
+
duration: import("vue").Ref<number>;
|
|
9
|
+
seeking: import("vue").Ref<boolean>;
|
|
10
|
+
volume: import("vue").Ref<number>;
|
|
11
|
+
rate: import("vue").Ref<number>;
|
|
12
|
+
waiting: import("vue").Ref<boolean>;
|
|
13
|
+
ended: import("vue").Ref<boolean>;
|
|
14
|
+
playing: import("vue").Ref<boolean>;
|
|
15
|
+
stalled: import("vue").Ref<boolean>;
|
|
16
|
+
buffered: import("vue").Ref<[number, number][]>;
|
|
17
|
+
muted: import("vue").Ref<boolean>;
|
|
18
|
+
};
|
|
19
|
+
videoApi: {
|
|
20
|
+
mouseEntered: import("vue").Ref<boolean>;
|
|
21
|
+
isFullscreen: import("vue").Ref<boolean>;
|
|
22
|
+
touched: import("vue").Ref<boolean>;
|
|
23
|
+
play: () => void;
|
|
24
|
+
pause: () => void;
|
|
25
|
+
togglePlay: () => void;
|
|
26
|
+
seek: (time: number) => void;
|
|
27
|
+
mute: () => void;
|
|
28
|
+
unmute: () => void;
|
|
29
|
+
enterFullscreen: () => void;
|
|
30
|
+
exitFullscreen: () => void;
|
|
31
|
+
onMouseenter: () => void;
|
|
32
|
+
onMouseleave: () => void;
|
|
33
|
+
};
|
|
34
|
+
controlsApi: {
|
|
35
|
+
mouseEntered: import("vue").Ref<boolean>;
|
|
36
|
+
dragging: import("vue").Ref<boolean>;
|
|
37
|
+
seekedTime: import("vue").Ref<number>;
|
|
38
|
+
seekedPercentage: import("vue").Ref<number>;
|
|
39
|
+
scrubbedPercentage: import("vue").Ref<number>;
|
|
40
|
+
bufferedPercentage: import("vue").ComputedRef<number>;
|
|
41
|
+
thumbPercentage: import("vue").Ref<number>;
|
|
42
|
+
popoverOffsetX: import("vue").Ref<number>;
|
|
43
|
+
onMouseenter: () => void;
|
|
44
|
+
onMouseleave: () => void;
|
|
45
|
+
onPointerdown: (e: MouseEvent | TouchEvent) => void;
|
|
46
|
+
onPointerup: () => void;
|
|
47
|
+
onPointermove: (e: MouseEvent | TouchEvent) => void;
|
|
48
|
+
trackRect: import("vue").Ref<{
|
|
49
|
+
height: number;
|
|
50
|
+
width: number;
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
readonly bottom: number;
|
|
54
|
+
readonly left: number;
|
|
55
|
+
readonly right: number;
|
|
56
|
+
readonly top: number;
|
|
57
|
+
toJSON: () => any;
|
|
58
|
+
} | undefined>;
|
|
59
|
+
};
|
|
60
|
+
playerRuntime: {
|
|
61
|
+
loaded: import("vue").Ref<boolean>;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
export {};
|
|
@@ -1,69 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { useMediaApi } from "./private/useMediaApi.mjs";
|
|
6
|
-
import { useControlsApi } from "./private/useControlsApi.mjs";
|
|
7
|
-
import { useRuntimeSourceProvider } from "./private/useRuntimeSourceProvider.mjs";
|
|
1
|
+
import { usePlayerMediaApi } from "./private/usePlayerMediaApi.mjs";
|
|
2
|
+
import { usePlayerVideoApi } from "./private/usePlayerVideoApi.mjs";
|
|
3
|
+
import { usePlayerRuntime } from "./private/usePlayerRuntime.mjs";
|
|
4
|
+
import { usePlayerControlsApi } from "./private/usePlayerControlsApi.mjs";
|
|
8
5
|
export function usePlayerApi(args) {
|
|
9
|
-
const {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} else if ("id" in args) {
|
|
14
|
-
return toValue(args.id) || uuid();
|
|
15
|
-
} else {
|
|
16
|
-
return uuid();
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
const instance = computed(() => findInstance(toValue(mappedId)));
|
|
20
|
-
function initialize() {
|
|
21
|
-
const id = toValue(mappedId);
|
|
22
|
-
let instance2 = findInstance(id);
|
|
23
|
-
if (!instance2) {
|
|
24
|
-
instance2 = addInstance(id);
|
|
25
|
-
}
|
|
26
|
-
if (typeof args !== "string") {
|
|
27
|
-
if ("mediaRef" in args) {
|
|
28
|
-
instance2.mediaApi = useMediaApi({ mediaRef: args.mediaRef });
|
|
29
|
-
} else if ("videoRef" in args) {
|
|
30
|
-
instance2.mediaApi = useMediaApi({ mediaRef: args.videoRef });
|
|
31
|
-
}
|
|
32
|
-
if ("videoRef" in args && "playerRef" in args) {
|
|
33
|
-
instance2.playerApi = usePlayerInternalApi({
|
|
34
|
-
id,
|
|
35
|
-
playerRef: args.playerRef,
|
|
36
|
-
videoRef: args.videoRef
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
if ("videoRef" in args && "srcType" in args && "src" in args) {
|
|
40
|
-
instance2.runtimeProvider = useRuntimeSourceProvider({
|
|
41
|
-
videoRef: args.videoRef,
|
|
42
|
-
srcType: args.srcType,
|
|
43
|
-
src: args.src
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
if ("barRef" in args && "trackRef" in args) {
|
|
47
|
-
instance2.controlsApi = useControlsApi({
|
|
48
|
-
id,
|
|
49
|
-
barRef: args.barRef,
|
|
50
|
-
trackRef: args.trackRef,
|
|
51
|
-
popoverRef: args.popoverRef
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return instance2;
|
|
56
|
-
}
|
|
57
|
-
function destroy(id) {
|
|
58
|
-
if (!id)
|
|
59
|
-
return;
|
|
60
|
-
removeInstance(toValue(id));
|
|
61
|
-
}
|
|
62
|
-
onUnmounted(() => {
|
|
63
|
-
destroy(toValue(mappedId));
|
|
64
|
-
});
|
|
65
|
-
initialize();
|
|
6
|
+
const mediaApi = usePlayerMediaApi({ id: args.id });
|
|
7
|
+
const videoApi = usePlayerVideoApi({ id: args.id });
|
|
8
|
+
const controlsApi = usePlayerControlsApi({ id: args.id });
|
|
9
|
+
const playerRuntime = usePlayerRuntime({ id: args.id });
|
|
66
10
|
return {
|
|
67
|
-
|
|
11
|
+
mediaApi,
|
|
12
|
+
videoApi,
|
|
13
|
+
controlsApi,
|
|
14
|
+
playerRuntime
|
|
68
15
|
};
|
|
69
16
|
}
|
|
@@ -1,25 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
type
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
id: MaybeRef<string>;
|
|
14
|
-
playerRef: MaybeRef<HTMLElement | undefined>;
|
|
15
|
-
videoRef: MaybeRef<HTMLVideoElement | undefined>;
|
|
16
|
-
};
|
|
17
|
-
type UseRuntimeSourceProviderArgs = {
|
|
18
|
-
videoRef: MaybeRef<HTMLVideoElement | undefined>;
|
|
19
|
-
srcType: SourceType;
|
|
20
|
-
src: string;
|
|
21
|
-
};
|
|
22
|
-
type UsePlayerApiArgs = Partial<UseMediaApiArgs & UseControlsApiArgs & UsePlayerInternalApiArgs & UseRuntimeSourceProviderArgs> & {
|
|
23
|
-
id: MaybeRef<string>;
|
|
24
|
-
};
|
|
25
|
-
export type { SourceType, UseMediaApiArgs, UsePlayerApiArgs, UseControlsApiArgs, UsePlayerInternalApiArgs, UseRuntimeSourceProviderArgs, };
|
|
1
|
+
export type SourceType = 'native' | 'hls';
|
|
2
|
+
type API = 'media' | 'player' | 'controls' | 'runtime' | 'player';
|
|
3
|
+
export type Buffered = [number, number][];
|
|
4
|
+
export type PlayerPrivateEvents = {
|
|
5
|
+
update: {
|
|
6
|
+
id: string;
|
|
7
|
+
api: API;
|
|
8
|
+
key: string;
|
|
9
|
+
value: string | number | boolean | Buffered | DOMRect | HTMLElement;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maas/vue-equipment",
|
|
3
3
|
"description": "A magic collection of Vue composables, plugins, components and directives",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.21.1",
|
|
5
5
|
"author": "Robin Scholz <https://github.com/robinscholz>, Christoph Jeworutzki <https://github.com/ChristophJeworutzki>",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"@antfu/ni": "^0.21.12",
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { UseControlsApiArgs } from '../../types.js';
|
|
2
|
-
export declare function useControlsApi(args: UseControlsApiArgs): {
|
|
3
|
-
mouseEntered: import("vue").Ref<boolean>;
|
|
4
|
-
dragging: import("vue").Ref<boolean>;
|
|
5
|
-
seekedTime: import("vue").Ref<number>;
|
|
6
|
-
seekedPercentage: import("vue").Ref<number>;
|
|
7
|
-
scrubbedPercentage: import("vue").Ref<number>;
|
|
8
|
-
bufferedPercentage: import("vue").ComputedRef<number>;
|
|
9
|
-
thumbPercentage: import("vue").Ref<number>;
|
|
10
|
-
popoverOffsetX: import("vue").Ref<number>;
|
|
11
|
-
onMouseenter: () => void;
|
|
12
|
-
onMouseleave: () => void;
|
|
13
|
-
onPointerdown: (e: MouseEvent | TouchEvent) => void;
|
|
14
|
-
onPointerup: () => void;
|
|
15
|
-
onPointermove: (e: MouseEvent | TouchEvent) => void;
|
|
16
|
-
};
|
|
17
|
-
export type UseControlsApiReturn = ReturnType<typeof useControlsApi>;
|
|
@@ -1,131 +0,0 @@
|
|
|
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 { usePlayerStore } from "./usePlayerStore.mjs";
|
|
9
|
-
export function useControlsApi(args) {
|
|
10
|
-
const { findInstance } = usePlayerStore();
|
|
11
|
-
const instance = findInstance(toValue(args.id));
|
|
12
|
-
const { buffered, duration, playing, currentTime } = instance.mediaApi;
|
|
13
|
-
const { play, pause, seek } = instance.playerApi;
|
|
14
|
-
const dragging = ref(false);
|
|
15
|
-
const mouseEntered = ref(false);
|
|
16
|
-
const seekedTime = ref(0);
|
|
17
|
-
const seekedPercentage = ref(0);
|
|
18
|
-
const scrubbedPercentage = ref(0);
|
|
19
|
-
const thumbPercentage = ref(0);
|
|
20
|
-
const popoverOffsetX = ref(0);
|
|
21
|
-
const bufferedPercentage = computed(() => {
|
|
22
|
-
if (!instance?.mediaApi)
|
|
23
|
-
return 0;
|
|
24
|
-
const endBuffer = buffered.value?.length > 0 ? buffered.value[0][1] : 0;
|
|
25
|
-
const percentage = endBuffer / duration.value * 100;
|
|
26
|
-
return clampValue(percentage, 0, thumbPercentage.value);
|
|
27
|
-
});
|
|
28
|
-
const resumePlay = ref(false);
|
|
29
|
-
const barRect = ref(void 0);
|
|
30
|
-
const trackRect = ref(void 0);
|
|
31
|
-
const popoverRect = ref(void 0);
|
|
32
|
-
function getPopoverOffsetX() {
|
|
33
|
-
if (!trackRect.value || !popoverRect.value || !barRect.value) {
|
|
34
|
-
return 0;
|
|
35
|
-
} else {
|
|
36
|
-
const trackFactor = barRect.value.width / trackRect.value.width;
|
|
37
|
-
const offsetXPercentage = Math.abs(trackRect.value.x - barRect.value.x) / barRect.value.width * 100;
|
|
38
|
-
const popoverWidthPercentage = popoverRect.value.width / barRect.value.width * 100;
|
|
39
|
-
const maxPercentage = 100 - popoverWidthPercentage;
|
|
40
|
-
const percentage = seekedPercentage.value / trackFactor + offsetXPercentage - popoverWidthPercentage / 2;
|
|
41
|
-
popoverOffsetX.value = clampValue(percentage, 0, maxPercentage);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function getTimelineTrackSize() {
|
|
45
|
-
trackRect.value = toValue(args.trackRef)?.getBoundingClientRect();
|
|
46
|
-
thumbPercentage.value = 100 - trackRect.value.height / trackRect.value.width * 100;
|
|
47
|
-
}
|
|
48
|
-
function getPopoverSizes() {
|
|
49
|
-
barRect.value = toValue(args.barRef)?.getBoundingClientRect();
|
|
50
|
-
popoverRect.value = toValue(args.popoverRef)?.getBoundingClientRect();
|
|
51
|
-
}
|
|
52
|
-
function seekToTrackPosition(absX) {
|
|
53
|
-
if (!trackRect.value) {
|
|
54
|
-
throw new Error("trackRect is undefined");
|
|
55
|
-
}
|
|
56
|
-
const relX = absX - trackRect.value.x - trackRect.value.height / 2;
|
|
57
|
-
const percentage = Math.round(relX / trackRect.value.width * 100);
|
|
58
|
-
seekedPercentage.value = clampValue(percentage, 0, thumbPercentage.value);
|
|
59
|
-
seekedTime.value = duration.value * mapValue(seekedPercentage.value, 0, thumbPercentage.value, 0, 100) / 100;
|
|
60
|
-
if (dragging.value) {
|
|
61
|
-
scrubbedPercentage.value = seekedPercentage.value;
|
|
62
|
-
seek(seekedTime.value);
|
|
63
|
-
}
|
|
64
|
-
getPopoverOffsetX();
|
|
65
|
-
}
|
|
66
|
-
function onMouseenter() {
|
|
67
|
-
getTimelineTrackSize();
|
|
68
|
-
getPopoverSizes();
|
|
69
|
-
mouseEntered.value = true;
|
|
70
|
-
}
|
|
71
|
-
function onMouseleave() {
|
|
72
|
-
mouseEntered.value = false;
|
|
73
|
-
dragging.value = false;
|
|
74
|
-
seekedTime.value = 0;
|
|
75
|
-
}
|
|
76
|
-
function onPointerdown(e) {
|
|
77
|
-
dragging.value = true;
|
|
78
|
-
resumePlay.value = playing.value;
|
|
79
|
-
pause();
|
|
80
|
-
const x = e instanceof MouseEvent ? e.pageX : e.touches[0].pageX;
|
|
81
|
-
seekToTrackPosition(x);
|
|
82
|
-
}
|
|
83
|
-
function onPointerup() {
|
|
84
|
-
dragging.value = false;
|
|
85
|
-
if (resumePlay.value) {
|
|
86
|
-
play();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function onPointermove(e) {
|
|
90
|
-
const x = e instanceof MouseEvent ? e.pageX : e.touches[0].pageX;
|
|
91
|
-
seekToTrackPosition(x);
|
|
92
|
-
}
|
|
93
|
-
watch(currentTime, (value) => {
|
|
94
|
-
const percentage = value / duration.value * 100;
|
|
95
|
-
scrubbedPercentage.value = mapValue(
|
|
96
|
-
percentage,
|
|
97
|
-
0,
|
|
98
|
-
100,
|
|
99
|
-
0,
|
|
100
|
-
thumbPercentage.value
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
useResizeObserver(args.trackRef, getTimelineTrackSize);
|
|
104
|
-
useResizeObserver(args.popoverRef, getPopoverSizes);
|
|
105
|
-
useEventListener(
|
|
106
|
-
defaultWindow,
|
|
107
|
-
"resize",
|
|
108
|
-
() => {
|
|
109
|
-
getTimelineTrackSize;
|
|
110
|
-
getPopoverSizes;
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
passive: true
|
|
114
|
-
}
|
|
115
|
-
);
|
|
116
|
-
return {
|
|
117
|
-
mouseEntered,
|
|
118
|
-
dragging,
|
|
119
|
-
seekedTime,
|
|
120
|
-
seekedPercentage,
|
|
121
|
-
scrubbedPercentage,
|
|
122
|
-
bufferedPercentage,
|
|
123
|
-
thumbPercentage,
|
|
124
|
-
popoverOffsetX,
|
|
125
|
-
onMouseenter,
|
|
126
|
-
onMouseleave,
|
|
127
|
-
onPointerdown,
|
|
128
|
-
onPointerup,
|
|
129
|
-
onPointermove
|
|
130
|
-
};
|
|
131
|
-
}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { ref, watch, unref, toValue } from "vue";
|
|
2
|
-
import { useEventListener, watchIgnorable } from "@vueuse/core";
|
|
3
|
-
export function useMediaApi(args) {
|
|
4
|
-
const currentTime = ref(0);
|
|
5
|
-
const duration = ref(0);
|
|
6
|
-
const seeking = ref(false);
|
|
7
|
-
const volume = ref(1);
|
|
8
|
-
const rate = ref(1);
|
|
9
|
-
const waiting = ref(false);
|
|
10
|
-
const ended = ref(false);
|
|
11
|
-
const playing = ref(false);
|
|
12
|
-
const stalled = ref(false);
|
|
13
|
-
const buffered = ref([]);
|
|
14
|
-
const muted = ref(false);
|
|
15
|
-
const { mediaRef } = args;
|
|
16
|
-
function timeRangeToArray(timeRanges) {
|
|
17
|
-
let ranges = [];
|
|
18
|
-
for (let i = 0; i < timeRanges.length; ++i)
|
|
19
|
-
ranges = [...ranges, [timeRanges.start(i), timeRanges.end(i)]];
|
|
20
|
-
return ranges;
|
|
21
|
-
}
|
|
22
|
-
watch([mediaRef, volume], () => {
|
|
23
|
-
const el = toValue(mediaRef);
|
|
24
|
-
if (!el)
|
|
25
|
-
return;
|
|
26
|
-
el.volume = volume.value;
|
|
27
|
-
});
|
|
28
|
-
watch([mediaRef, muted], () => {
|
|
29
|
-
const el = toValue(mediaRef);
|
|
30
|
-
if (!el)
|
|
31
|
-
return;
|
|
32
|
-
el.muted = muted.value;
|
|
33
|
-
});
|
|
34
|
-
watch([mediaRef, rate], () => {
|
|
35
|
-
const el = toValue(mediaRef);
|
|
36
|
-
if (!el)
|
|
37
|
-
return;
|
|
38
|
-
el.playbackRate = rate.value;
|
|
39
|
-
});
|
|
40
|
-
const { ignoreUpdates: ignoreCurrentTimeUpdates } = watchIgnorable(
|
|
41
|
-
currentTime,
|
|
42
|
-
(time) => {
|
|
43
|
-
const el = toValue(mediaRef);
|
|
44
|
-
if (!el)
|
|
45
|
-
return;
|
|
46
|
-
el.currentTime = unref(time);
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
const { ignoreUpdates: ignorePlayingUpdates } = watchIgnorable(
|
|
50
|
-
playing,
|
|
51
|
-
(isPlaying) => {
|
|
52
|
-
const el = toValue(mediaRef);
|
|
53
|
-
if (!el)
|
|
54
|
-
return;
|
|
55
|
-
isPlaying ? el.play() : el.pause();
|
|
56
|
-
}
|
|
57
|
-
);
|
|
58
|
-
useEventListener(mediaRef, "timeupdate", () => {
|
|
59
|
-
ignoreCurrentTimeUpdates(
|
|
60
|
-
() => currentTime.value = toValue(mediaRef).currentTime
|
|
61
|
-
);
|
|
62
|
-
});
|
|
63
|
-
useEventListener(mediaRef, "durationchange", () => {
|
|
64
|
-
duration.value = toValue(mediaRef).duration;
|
|
65
|
-
});
|
|
66
|
-
useEventListener(mediaRef, "progress", () => {
|
|
67
|
-
buffered.value = timeRangeToArray(toValue(mediaRef).buffered);
|
|
68
|
-
});
|
|
69
|
-
useEventListener(mediaRef, "seeking", () => {
|
|
70
|
-
seeking.value = true;
|
|
71
|
-
});
|
|
72
|
-
useEventListener(mediaRef, "seeked", () => {
|
|
73
|
-
seeking.value = false;
|
|
74
|
-
});
|
|
75
|
-
useEventListener(mediaRef, ["waiting", "loadstart"], () => {
|
|
76
|
-
waiting.value = true;
|
|
77
|
-
ignorePlayingUpdates(() => playing.value = false);
|
|
78
|
-
});
|
|
79
|
-
useEventListener(mediaRef, "loadeddata", () => {
|
|
80
|
-
waiting.value = false;
|
|
81
|
-
});
|
|
82
|
-
useEventListener(mediaRef, "playing", () => {
|
|
83
|
-
waiting.value = false;
|
|
84
|
-
ended.value = false;
|
|
85
|
-
ignorePlayingUpdates(() => playing.value = true);
|
|
86
|
-
});
|
|
87
|
-
useEventListener(mediaRef, "ratechange", () => {
|
|
88
|
-
rate.value = toValue(mediaRef).playbackRate;
|
|
89
|
-
});
|
|
90
|
-
useEventListener(mediaRef, "stalled", () => {
|
|
91
|
-
stalled.value = true;
|
|
92
|
-
});
|
|
93
|
-
useEventListener(mediaRef, "ended", () => {
|
|
94
|
-
ended.value = true;
|
|
95
|
-
});
|
|
96
|
-
useEventListener(mediaRef, "pause", () => {
|
|
97
|
-
playing.value = false;
|
|
98
|
-
});
|
|
99
|
-
useEventListener(mediaRef, "play", () => {
|
|
100
|
-
playing.value = true;
|
|
101
|
-
});
|
|
102
|
-
useEventListener(mediaRef, "volumechange", () => {
|
|
103
|
-
const el = toValue(mediaRef);
|
|
104
|
-
if (!el)
|
|
105
|
-
return;
|
|
106
|
-
volume.value = el.volume;
|
|
107
|
-
muted.value = el.muted;
|
|
108
|
-
});
|
|
109
|
-
return {
|
|
110
|
-
currentTime,
|
|
111
|
-
duration,
|
|
112
|
-
waiting,
|
|
113
|
-
seeking,
|
|
114
|
-
ended,
|
|
115
|
-
stalled,
|
|
116
|
-
buffered,
|
|
117
|
-
playing,
|
|
118
|
-
rate,
|
|
119
|
-
volume,
|
|
120
|
-
muted
|
|
121
|
-
};
|
|
122
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { UsePlayerInternalApiArgs } from '../../types.js';
|
|
2
|
-
export declare function usePlayerInternalApi(args: UsePlayerInternalApiArgs): {
|
|
3
|
-
mouseEntered: import("vue").Ref<boolean>;
|
|
4
|
-
isFullscreen: import("vue").Ref<boolean>;
|
|
5
|
-
touched: import("vue").Ref<boolean>;
|
|
6
|
-
play: () => void;
|
|
7
|
-
pause: () => void;
|
|
8
|
-
togglePlay: () => void;
|
|
9
|
-
seek: (time: number) => void;
|
|
10
|
-
mute: () => void;
|
|
11
|
-
unmute: () => void;
|
|
12
|
-
enterFullscreen: () => Promise<void>;
|
|
13
|
-
exitFullscreen: () => Promise<void>;
|
|
14
|
-
toggleFullscreen: () => Promise<void>;
|
|
15
|
-
onMouseenter: () => void;
|
|
16
|
-
onMouseleave: () => void;
|
|
17
|
-
};
|
|
18
|
-
export type UsePlayerInternalApiReturn = ReturnType<typeof usePlayerInternalApi>;
|