@maas/vue-equipment 0.11.6 → 0.12.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/MagicModal/src/composables/private/useModalStore.d.ts +2 -2
- package/dist/plugins/MagicModal/src/composables/private/useModalStore.mjs +4 -4
- package/dist/plugins/MagicModal/src/composables/useModalApi.mjs +3 -3
- package/dist/plugins/MagicPlayer/index.d.ts +2 -7
- package/dist/plugins/MagicPlayer/index.mjs +4 -25
- package/dist/plugins/MagicPlayer/nuxt.mjs +1 -13
- package/dist/plugins/MagicPlayer/src/components/MagicPlayer.vue +40 -21
- package/dist/plugins/MagicPlayer/src/components/MagicPlayer.vue.d.ts +19 -28
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerControls.vue +70 -90
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerControls.vue.d.ts +16 -16
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerMuxPopover.vue +11 -11
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerMuxPopover.vue.d.ts +8 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerOverlay.vue +96 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerOverlay.vue.d.ts +21 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerTimeline.vue +25 -15
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerTimeline.vue.d.ts +11 -1
- package/dist/plugins/MagicPlayer/src/components/icons/Waiting.vue +1 -1
- package/dist/plugins/MagicPlayer/src/composables/{useControlsApi.d.ts → private/useControlsApi.d.ts} +8 -8
- package/dist/plugins/MagicPlayer/src/composables/{useControlsApi.mjs → private/useControlsApi.mjs} +22 -19
- package/dist/plugins/MagicPlayer/src/composables/{useMediaApi.d.ts → private/useMediaApi.d.ts} +2 -2
- package/dist/plugins/MagicPlayer/src/composables/{useMediaApi.mjs → private/useMediaApi.mjs} +29 -28
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerInternalApi.d.ts +18 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerInternalApi.mjs +63 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStore.d.ts +20 -0
- package/dist/plugins/MagicPlayer/src/composables/private/usePlayerStore.mjs +42 -0
- package/dist/plugins/MagicPlayer/src/composables/{useRuntimeSourceProvider.d.ts → private/useRuntimeSourceProvider.d.ts} +1 -3
- package/dist/plugins/MagicPlayer/src/composables/usePlayerApi.d.ts +4 -18
- package/dist/plugins/MagicPlayer/src/composables/usePlayerApi.mjs +62 -43
- package/dist/plugins/MagicPlayer/src/types/index.d.ts +14 -3
- package/package.json +1 -1
- package/dist/plugins/MagicPlayer/src/composables/useControls.d.ts +0 -8
- package/dist/plugins/MagicPlayer/src/composables/useControls.mjs +0 -15
- package/dist/plugins/MagicPlayer/src/composables/usePlayer.d.ts +0 -12
- package/dist/plugins/MagicPlayer/src/composables/usePlayer.mjs +0 -33
- package/dist/plugins/MagicPlayer/src/symbols/index.d.ts +0 -45
- package/dist/plugins/MagicPlayer/src/symbols/index.mjs +0 -10
- /package/dist/plugins/MagicPlayer/src/composables/{useRuntimeSourceProvider.mjs → private/useRuntimeSourceProvider.mjs} +0 -0
|
@@ -14,16 +14,12 @@
|
|
|
14
14
|
</div>
|
|
15
15
|
</template>
|
|
16
16
|
<script setup lang="ts">
|
|
17
|
-
import { shallowRef, onMounted, watch, computed } from 'vue'
|
|
17
|
+
import { shallowRef, onMounted, watch, computed, type Ref } from 'vue'
|
|
18
18
|
import { useDevicePixelRatio } from '@vueuse/core'
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
const { controlsApi } = useInjectControls()
|
|
22
|
-
const { seekedTime } = controlsApi
|
|
23
|
-
|
|
24
|
-
import type { Ref } from 'vue'
|
|
19
|
+
import { usePlayerApi } from '../composables/usePlayerApi'
|
|
25
20
|
|
|
26
21
|
type Props = {
|
|
22
|
+
id: string
|
|
27
23
|
playbackId: string
|
|
28
24
|
}
|
|
29
25
|
|
|
@@ -40,13 +36,17 @@ type MuxStoryboard = {
|
|
|
40
36
|
}
|
|
41
37
|
|
|
42
38
|
const props = defineProps<Props>()
|
|
39
|
+
|
|
40
|
+
const { instance } = usePlayerApi(props.id)
|
|
41
|
+
|
|
42
|
+
const { seekedTime } = instance.value.controlsApi
|
|
43
|
+
const { pixelRatio } = useDevicePixelRatio()
|
|
44
|
+
|
|
43
45
|
const canvas = shallowRef() as Ref<HTMLCanvasElement>
|
|
44
|
-
let context: CanvasRenderingContext2D | undefined = undefined
|
|
45
46
|
const storyboard = shallowRef<MuxStoryboard | undefined>()
|
|
47
|
+
let context: CanvasRenderingContext2D | undefined = undefined
|
|
46
48
|
let image: HTMLImageElement | undefined = undefined
|
|
47
49
|
|
|
48
|
-
const { pixelRatio } = useDevicePixelRatio()
|
|
49
|
-
|
|
50
50
|
const thumbWidth = computed(() => {
|
|
51
51
|
if (!storyboard.value) return 0
|
|
52
52
|
return storyboard.value.tile_width / pixelRatio.value
|
|
@@ -112,7 +112,7 @@ function drawFrame(time: number) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
onMounted(init)
|
|
115
|
-
watch(() => seekedTime
|
|
115
|
+
watch(() => seekedTime?.value, drawFrame)
|
|
116
116
|
</script>
|
|
117
117
|
|
|
118
118
|
<style lang="css">
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
declare const _default: import("vue").DefineComponent<{
|
|
2
|
+
id: {
|
|
3
|
+
type: import("vue").PropType<string>;
|
|
4
|
+
required: true;
|
|
5
|
+
};
|
|
2
6
|
playbackId: {
|
|
3
7
|
type: import("vue").PropType<string>;
|
|
4
8
|
required: true;
|
|
5
9
|
};
|
|
6
10
|
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
|
11
|
+
id: {
|
|
12
|
+
type: import("vue").PropType<string>;
|
|
13
|
+
required: true;
|
|
14
|
+
};
|
|
7
15
|
playbackId: {
|
|
8
16
|
type: import("vue").PropType<string>;
|
|
9
17
|
required: true;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="magic-player-overlay"
|
|
4
|
+
:class="{
|
|
5
|
+
'-playing': playing,
|
|
6
|
+
'-paused': !playing,
|
|
7
|
+
'-idle': idle,
|
|
8
|
+
'-not-idle': !idle,
|
|
9
|
+
'-hover': mouseEntered,
|
|
10
|
+
'-not-hover': !mouseEntered,
|
|
11
|
+
}"
|
|
12
|
+
@click.stop="togglePlay"
|
|
13
|
+
>
|
|
14
|
+
<template v-if="waiting">
|
|
15
|
+
<button class="magic-player-overlay__button">
|
|
16
|
+
<slot name="waitingIcon">
|
|
17
|
+
<icon-waiting />
|
|
18
|
+
</slot>
|
|
19
|
+
</button>
|
|
20
|
+
</template>
|
|
21
|
+
<template v-else>
|
|
22
|
+
<button v-if="!playing" class="magic-player-overlay__button">
|
|
23
|
+
<slot name="playIcon">
|
|
24
|
+
<icon-play />
|
|
25
|
+
</slot>
|
|
26
|
+
</button>
|
|
27
|
+
<button v-else class="magic-player-overlay__button">
|
|
28
|
+
<slot name="pauseIcon">
|
|
29
|
+
<icon-pause />
|
|
30
|
+
</slot>
|
|
31
|
+
</button>
|
|
32
|
+
</template>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script setup lang="ts">
|
|
37
|
+
import {} from 'vue'
|
|
38
|
+
import { useIdle } from '@vueuse/core'
|
|
39
|
+
import IconPlay from './icons/Play.vue'
|
|
40
|
+
import IconPause from './icons/Pause.vue'
|
|
41
|
+
import IconWaiting from './icons/Waiting.vue'
|
|
42
|
+
import { usePlayerApi } from '../composables/usePlayerApi'
|
|
43
|
+
|
|
44
|
+
interface Props {
|
|
45
|
+
id: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const props = defineProps<Props>()
|
|
49
|
+
|
|
50
|
+
const { instance } = usePlayerApi(props.id)
|
|
51
|
+
|
|
52
|
+
const { playing, waiting } = instance.value.mediaApi
|
|
53
|
+
const { mouseEntered, togglePlay } = instance.value.playerApi
|
|
54
|
+
|
|
55
|
+
const { idle } = useIdle(3000)
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<style lang="css">
|
|
59
|
+
:root {
|
|
60
|
+
--magic-player-overlay-background-color: rgba(0, 0, 0, 0.3);
|
|
61
|
+
--magic-player-overlay-color: rgba(255, 255, 255, 1);
|
|
62
|
+
--magic-player-overlay-button-size: 2.5rem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.magic-player-overlay {
|
|
66
|
+
position: absolute;
|
|
67
|
+
inset: 0;
|
|
68
|
+
background-color: var(--magic-player-overlay-background-color);
|
|
69
|
+
color: var(--magic-player-overlay-color);
|
|
70
|
+
transition-duration: 300ms;
|
|
71
|
+
transition-property: opacity;
|
|
72
|
+
transition-timing-function: ease;
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.magic-player-overlay__button {
|
|
80
|
+
background-color: transparent;
|
|
81
|
+
color: inherit;
|
|
82
|
+
border: 0;
|
|
83
|
+
border-radius: 0;
|
|
84
|
+
padding: 0;
|
|
85
|
+
outline: none;
|
|
86
|
+
appearance: none;
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
width: var(--magic-player-overlay-button-size);
|
|
89
|
+
height: var(--magic-player-overlay-button-size);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.magic-player-overlay.-playing.-idle,
|
|
93
|
+
.magic-player-overlay.-playing.-not-hover {
|
|
94
|
+
opacity: 0;
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
|
|
2
|
+
id: {
|
|
3
|
+
type: import("vue").PropType<string>;
|
|
4
|
+
required: true;
|
|
5
|
+
};
|
|
6
|
+
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
|
7
|
+
id: {
|
|
8
|
+
type: import("vue").PropType<string>;
|
|
9
|
+
required: true;
|
|
10
|
+
};
|
|
11
|
+
}>>, {}, {}>, {
|
|
12
|
+
waitingIcon?(_: {}): any;
|
|
13
|
+
playIcon?(_: {}): any;
|
|
14
|
+
pauseIcon?(_: {}): any;
|
|
15
|
+
}>;
|
|
16
|
+
export default _default;
|
|
17
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
18
|
+
new (): {
|
|
19
|
+
$slots: S;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
<div class="magic-player-timeline">
|
|
3
3
|
<div
|
|
4
4
|
class="magic-player-timeline__target"
|
|
5
|
-
@mouseenter="
|
|
6
|
-
@mouseleave="
|
|
7
|
-
@pointerdown="
|
|
8
|
-
@pointerup="
|
|
9
|
-
@pointermove="
|
|
5
|
+
@mouseenter="onMouseenter"
|
|
6
|
+
@mouseleave="onMouseleave"
|
|
7
|
+
@pointerdown="onPointerdown"
|
|
8
|
+
@pointerup="onPointerup"
|
|
9
|
+
@pointermove="onPointermove"
|
|
10
10
|
>
|
|
11
11
|
<div class="magic-player-timeline__slider-track">
|
|
12
12
|
<div
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
:style="{ left: `${bufferedPercentage}%` }"
|
|
22
22
|
/>
|
|
23
23
|
<div
|
|
24
|
-
v-show="
|
|
24
|
+
v-show="mouseEntered"
|
|
25
25
|
class="magic-player-timeline__slider-seeked"
|
|
26
26
|
:style="{ left: `${seekedPercentage}%` }"
|
|
27
27
|
/>
|
|
@@ -36,20 +36,30 @@
|
|
|
36
36
|
</template>
|
|
37
37
|
|
|
38
38
|
<script setup lang="ts">
|
|
39
|
-
import {
|
|
39
|
+
import {} from 'vue'
|
|
40
|
+
import { usePlayerApi } from '../composables/usePlayerApi'
|
|
41
|
+
|
|
42
|
+
interface Props {
|
|
43
|
+
id: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const props = defineProps<Props>()
|
|
47
|
+
const { instance } = usePlayerApi(props.id)
|
|
40
48
|
|
|
41
|
-
const { controlsApi } = useInjectControls()
|
|
42
49
|
const {
|
|
43
|
-
|
|
50
|
+
mouseEntered,
|
|
44
51
|
seekedPercentage,
|
|
45
52
|
scrubbedPercentage,
|
|
46
53
|
bufferedPercentage,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
} = instance.value.controlsApi
|
|
55
|
+
|
|
56
|
+
const {
|
|
57
|
+
onMouseenter,
|
|
58
|
+
onMouseleave,
|
|
59
|
+
onPointerdown,
|
|
60
|
+
onPointerup,
|
|
61
|
+
onPointermove,
|
|
62
|
+
} = instance.value.controlsApi
|
|
53
63
|
</script>
|
|
54
64
|
|
|
55
65
|
<style lang="css">
|
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
declare const _default: import("vue").DefineComponent<{
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{
|
|
2
|
+
id: {
|
|
3
|
+
type: import("vue").PropType<string>;
|
|
4
|
+
required: true;
|
|
5
|
+
};
|
|
6
|
+
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
|
7
|
+
id: {
|
|
8
|
+
type: import("vue").PropType<string>;
|
|
9
|
+
required: true;
|
|
10
|
+
};
|
|
11
|
+
}>>, {}, {}>;
|
|
2
12
|
export default _default;
|
package/dist/plugins/MagicPlayer/src/composables/{useControlsApi.d.ts → private/useControlsApi.d.ts}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function useControlsApi(args:
|
|
3
|
-
|
|
1
|
+
import type { UseControlsApiArgs } from '../../types.js';
|
|
2
|
+
export declare function useControlsApi(args: UseControlsApiArgs): {
|
|
3
|
+
mouseEntered: import("vue").Ref<boolean>;
|
|
4
4
|
dragging: import("vue").Ref<boolean>;
|
|
5
5
|
seekedTime: import("vue").Ref<number>;
|
|
6
6
|
seekedPercentage: import("vue").Ref<number>;
|
|
@@ -8,10 +8,10 @@ export declare function useControlsApi(args: UseControlsArgs): {
|
|
|
8
8
|
bufferedPercentage: import("vue").ComputedRef<any>;
|
|
9
9
|
thumbPercentage: import("vue").Ref<number>;
|
|
10
10
|
popoverOffsetX: import("vue").Ref<number>;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
onMouseenter: () => void;
|
|
12
|
+
onMouseleave: () => void;
|
|
13
|
+
onPointerdown: (e: MouseEvent | TouchEvent) => void;
|
|
14
|
+
onPointerup: () => void;
|
|
15
|
+
onPointermove: (e: MouseEvent | TouchEvent) => void;
|
|
16
16
|
};
|
|
17
17
|
export type UseControlsApiReturn = ReturnType<typeof useControlsApi>;
|
package/dist/plugins/MagicPlayer/src/composables/{useControlsApi.mjs → private/useControlsApi.mjs}
RENAMED
|
@@ -5,20 +5,23 @@ import {
|
|
|
5
5
|
defaultWindow
|
|
6
6
|
} from "@vueuse/core";
|
|
7
7
|
import { clampValue, mapValue } from "@maas/vue-equipment/utils";
|
|
8
|
-
import {
|
|
8
|
+
import { usePlayerStore } from "./usePlayerStore.mjs";
|
|
9
9
|
export function useControlsApi(args) {
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
12
|
-
const {
|
|
13
|
-
const
|
|
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
14
|
const dragging = ref(false);
|
|
15
|
+
const mouseEntered = ref(false);
|
|
15
16
|
const seekedTime = ref(0);
|
|
16
17
|
const seekedPercentage = ref(0);
|
|
17
18
|
const scrubbedPercentage = ref(0);
|
|
18
19
|
const thumbPercentage = ref(0);
|
|
19
20
|
const popoverOffsetX = ref(0);
|
|
20
21
|
const bufferedPercentage = computed(() => {
|
|
21
|
-
|
|
22
|
+
if (!instance?.mediaApi)
|
|
23
|
+
return 0;
|
|
24
|
+
const endBuffer = buffered.value?.length > 0 ? buffered.value[0][1] : 0;
|
|
22
25
|
const percentage = endBuffer / duration.value * 100;
|
|
23
26
|
return clampValue(percentage, 0, thumbPercentage.value);
|
|
24
27
|
});
|
|
@@ -60,30 +63,30 @@ export function useControlsApi(args) {
|
|
|
60
63
|
}
|
|
61
64
|
getPopoverOffsetX();
|
|
62
65
|
}
|
|
63
|
-
function
|
|
66
|
+
function onMouseenter() {
|
|
64
67
|
getTimelineTrackSize();
|
|
65
68
|
getPopoverSizes();
|
|
66
|
-
|
|
69
|
+
mouseEntered.value = true;
|
|
67
70
|
}
|
|
68
|
-
function
|
|
69
|
-
|
|
71
|
+
function onMouseleave() {
|
|
72
|
+
mouseEntered.value = false;
|
|
70
73
|
dragging.value = false;
|
|
71
74
|
seekedTime.value = 0;
|
|
72
75
|
}
|
|
73
|
-
function
|
|
76
|
+
function onPointerdown(e) {
|
|
74
77
|
dragging.value = true;
|
|
75
78
|
resumePlay.value = playing.value;
|
|
76
79
|
pause();
|
|
77
80
|
const x = e instanceof MouseEvent ? e.pageX : e.touches[0].pageX;
|
|
78
81
|
seekToTrackPosition(x);
|
|
79
82
|
}
|
|
80
|
-
function
|
|
83
|
+
function onPointerup() {
|
|
81
84
|
dragging.value = false;
|
|
82
85
|
if (resumePlay.value) {
|
|
83
86
|
play();
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
|
-
function
|
|
89
|
+
function onPointermove(e) {
|
|
87
90
|
const x = e instanceof MouseEvent ? e.pageX : e.touches[0].pageX;
|
|
88
91
|
seekToTrackPosition(x);
|
|
89
92
|
}
|
|
@@ -111,7 +114,7 @@ export function useControlsApi(args) {
|
|
|
111
114
|
}
|
|
112
115
|
);
|
|
113
116
|
return {
|
|
114
|
-
|
|
117
|
+
mouseEntered,
|
|
115
118
|
dragging,
|
|
116
119
|
seekedTime,
|
|
117
120
|
seekedPercentage,
|
|
@@ -119,10 +122,10 @@ export function useControlsApi(args) {
|
|
|
119
122
|
bufferedPercentage,
|
|
120
123
|
thumbPercentage,
|
|
121
124
|
popoverOffsetX,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
onMouseenter,
|
|
126
|
+
onMouseleave,
|
|
127
|
+
onPointerdown,
|
|
128
|
+
onPointerup,
|
|
129
|
+
onPointermove
|
|
127
130
|
};
|
|
128
131
|
}
|
package/dist/plugins/MagicPlayer/src/composables/{useMediaApi.d.ts → private/useMediaApi.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function useMediaApi(
|
|
1
|
+
import type { UseMediaApiArgs } from '../../types.js';
|
|
2
|
+
export declare function useMediaApi(args: UseMediaApiArgs): {
|
|
3
3
|
currentTime: import("vue").Ref<number>;
|
|
4
4
|
duration: import("vue").Ref<number>;
|
|
5
5
|
waiting: import("vue").Ref<boolean>;
|
package/dist/plugins/MagicPlayer/src/composables/{useMediaApi.mjs → private/useMediaApi.mjs}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ref, watch, unref, toValue } from "vue";
|
|
2
2
|
import { useEventListener, watchIgnorable } from "@vueuse/core";
|
|
3
|
-
export function useMediaApi(
|
|
3
|
+
export function useMediaApi(args) {
|
|
4
4
|
const currentTime = ref(0);
|
|
5
5
|
const duration = ref(0);
|
|
6
6
|
const seeking = ref(false);
|
|
@@ -12,26 +12,27 @@ export function useMediaApi(target) {
|
|
|
12
12
|
const stalled = ref(false);
|
|
13
13
|
const buffered = ref([]);
|
|
14
14
|
const muted = ref(false);
|
|
15
|
+
const { mediaRef } = args;
|
|
15
16
|
function timeRangeToArray(timeRanges) {
|
|
16
17
|
let ranges = [];
|
|
17
18
|
for (let i = 0; i < timeRanges.length; ++i)
|
|
18
19
|
ranges = [...ranges, [timeRanges.start(i), timeRanges.end(i)]];
|
|
19
20
|
return ranges;
|
|
20
21
|
}
|
|
21
|
-
watch([
|
|
22
|
-
const el = toValue(
|
|
22
|
+
watch([mediaRef, volume], () => {
|
|
23
|
+
const el = toValue(mediaRef);
|
|
23
24
|
if (!el)
|
|
24
25
|
return;
|
|
25
26
|
el.volume = volume.value;
|
|
26
27
|
});
|
|
27
|
-
watch([
|
|
28
|
-
const el = toValue(
|
|
28
|
+
watch([mediaRef, muted], () => {
|
|
29
|
+
const el = toValue(mediaRef);
|
|
29
30
|
if (!el)
|
|
30
31
|
return;
|
|
31
32
|
el.muted = muted.value;
|
|
32
33
|
});
|
|
33
|
-
watch([
|
|
34
|
-
const el = toValue(
|
|
34
|
+
watch([mediaRef, rate], () => {
|
|
35
|
+
const el = toValue(mediaRef);
|
|
35
36
|
if (!el)
|
|
36
37
|
return;
|
|
37
38
|
el.playbackRate = rate.value;
|
|
@@ -39,7 +40,7 @@ export function useMediaApi(target) {
|
|
|
39
40
|
const { ignoreUpdates: ignoreCurrentTimeUpdates } = watchIgnorable(
|
|
40
41
|
currentTime,
|
|
41
42
|
(time) => {
|
|
42
|
-
const el = toValue(
|
|
43
|
+
const el = toValue(mediaRef);
|
|
43
44
|
if (!el)
|
|
44
45
|
return;
|
|
45
46
|
el.currentTime = unref(time);
|
|
@@ -48,58 +49,58 @@ export function useMediaApi(target) {
|
|
|
48
49
|
const { ignoreUpdates: ignorePlayingUpdates } = watchIgnorable(
|
|
49
50
|
playing,
|
|
50
51
|
(isPlaying) => {
|
|
51
|
-
const el = toValue(
|
|
52
|
+
const el = toValue(mediaRef);
|
|
52
53
|
if (!el)
|
|
53
54
|
return;
|
|
54
55
|
isPlaying ? el.play() : el.pause();
|
|
55
56
|
}
|
|
56
57
|
);
|
|
57
|
-
useEventListener(
|
|
58
|
+
useEventListener(mediaRef, "timeupdate", () => {
|
|
58
59
|
ignoreCurrentTimeUpdates(
|
|
59
|
-
() => currentTime.value = toValue(
|
|
60
|
+
() => currentTime.value = toValue(mediaRef).currentTime
|
|
60
61
|
);
|
|
61
62
|
});
|
|
62
|
-
useEventListener(
|
|
63
|
-
duration.value = toValue(
|
|
63
|
+
useEventListener(mediaRef, "durationchange", () => {
|
|
64
|
+
duration.value = toValue(mediaRef).duration;
|
|
64
65
|
});
|
|
65
|
-
useEventListener(
|
|
66
|
-
buffered.value = timeRangeToArray(toValue(
|
|
66
|
+
useEventListener(mediaRef, "progress", () => {
|
|
67
|
+
buffered.value = timeRangeToArray(toValue(mediaRef).buffered);
|
|
67
68
|
});
|
|
68
|
-
useEventListener(
|
|
69
|
+
useEventListener(mediaRef, "seeking", () => {
|
|
69
70
|
seeking.value = true;
|
|
70
71
|
});
|
|
71
|
-
useEventListener(
|
|
72
|
+
useEventListener(mediaRef, "seeked", () => {
|
|
72
73
|
seeking.value = false;
|
|
73
74
|
});
|
|
74
|
-
useEventListener(
|
|
75
|
+
useEventListener(mediaRef, ["waiting", "loadstart"], () => {
|
|
75
76
|
waiting.value = true;
|
|
76
77
|
ignorePlayingUpdates(() => playing.value = false);
|
|
77
78
|
});
|
|
78
|
-
useEventListener(
|
|
79
|
+
useEventListener(mediaRef, "loadeddata", () => {
|
|
79
80
|
waiting.value = false;
|
|
80
81
|
});
|
|
81
|
-
useEventListener(
|
|
82
|
+
useEventListener(mediaRef, "playing", () => {
|
|
82
83
|
waiting.value = false;
|
|
83
84
|
ended.value = false;
|
|
84
85
|
ignorePlayingUpdates(() => playing.value = true);
|
|
85
86
|
});
|
|
86
|
-
useEventListener(
|
|
87
|
-
rate.value = toValue(
|
|
87
|
+
useEventListener(mediaRef, "ratechange", () => {
|
|
88
|
+
rate.value = toValue(mediaRef).playbackRate;
|
|
88
89
|
});
|
|
89
|
-
useEventListener(
|
|
90
|
+
useEventListener(mediaRef, "stalled", () => {
|
|
90
91
|
stalled.value = true;
|
|
91
92
|
});
|
|
92
|
-
useEventListener(
|
|
93
|
+
useEventListener(mediaRef, "ended", () => {
|
|
93
94
|
ended.value = true;
|
|
94
95
|
});
|
|
95
|
-
useEventListener(
|
|
96
|
+
useEventListener(mediaRef, "pause", () => {
|
|
96
97
|
playing.value = false;
|
|
97
98
|
});
|
|
98
|
-
useEventListener(
|
|
99
|
+
useEventListener(mediaRef, "play", () => {
|
|
99
100
|
playing.value = true;
|
|
100
101
|
});
|
|
101
|
-
useEventListener(
|
|
102
|
-
const el = toValue(
|
|
102
|
+
useEventListener(mediaRef, "volumechange", () => {
|
|
103
|
+
const el = toValue(mediaRef);
|
|
103
104
|
if (!el)
|
|
104
105
|
return;
|
|
105
106
|
volume.value = el.volume;
|
|
@@ -0,0 +1,18 @@
|
|
|
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>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ref, watch, toValue } from "vue";
|
|
2
|
+
import { useFullscreen } from "@vueuse/core";
|
|
3
|
+
import { isIOS } from "@maas/vue-equipment/utils";
|
|
4
|
+
import { usePlayerStore } from "./usePlayerStore.mjs";
|
|
5
|
+
export function usePlayerInternalApi(args) {
|
|
6
|
+
const touched = ref(false);
|
|
7
|
+
const mouseEntered = ref(false);
|
|
8
|
+
const fullscreenTarget = isIOS() ? args.videoRef : args.playerRef;
|
|
9
|
+
const { findInstance } = usePlayerStore();
|
|
10
|
+
const instance = findInstance(toValue(args.id));
|
|
11
|
+
const { currentTime, playing, muted } = instance.mediaApi;
|
|
12
|
+
const {
|
|
13
|
+
isFullscreen,
|
|
14
|
+
enter: enterFullscreen,
|
|
15
|
+
exit: exitFullscreen,
|
|
16
|
+
toggle: toggleFullscreen
|
|
17
|
+
} = useFullscreen(fullscreenTarget);
|
|
18
|
+
function play() {
|
|
19
|
+
playing.value = true;
|
|
20
|
+
}
|
|
21
|
+
function pause() {
|
|
22
|
+
playing.value = false;
|
|
23
|
+
}
|
|
24
|
+
function togglePlay() {
|
|
25
|
+
playing.value = !playing.value;
|
|
26
|
+
}
|
|
27
|
+
function seek(time) {
|
|
28
|
+
currentTime.value = time;
|
|
29
|
+
}
|
|
30
|
+
function mute() {
|
|
31
|
+
muted.value = true;
|
|
32
|
+
}
|
|
33
|
+
function unmute() {
|
|
34
|
+
muted.value = false;
|
|
35
|
+
}
|
|
36
|
+
function onMouseenter() {
|
|
37
|
+
mouseEntered.value = true;
|
|
38
|
+
}
|
|
39
|
+
function onMouseleave() {
|
|
40
|
+
mouseEntered.value = false;
|
|
41
|
+
}
|
|
42
|
+
watch(playing, () => {
|
|
43
|
+
if (!touched.value) {
|
|
44
|
+
touched.value = true;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
mouseEntered,
|
|
49
|
+
isFullscreen,
|
|
50
|
+
touched,
|
|
51
|
+
play,
|
|
52
|
+
pause,
|
|
53
|
+
togglePlay,
|
|
54
|
+
seek,
|
|
55
|
+
mute,
|
|
56
|
+
unmute,
|
|
57
|
+
enterFullscreen,
|
|
58
|
+
exitFullscreen,
|
|
59
|
+
toggleFullscreen,
|
|
60
|
+
onMouseenter,
|
|
61
|
+
onMouseleave
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ShallowRef } from 'vue';
|
|
2
|
+
import type { UseMediaApiReturn } from './useMediaApi.js';
|
|
3
|
+
import type { UsePlayerInternalApiReturn } from './usePlayerInternalApi.js';
|
|
4
|
+
import type { UseRuntimeSourceProviderReturn } from './useRuntimeSourceProvider.js';
|
|
5
|
+
import type { UseControlsApiReturn } from './useControlsApi.js';
|
|
6
|
+
import type { UsePlayerApiArgs } from '../../types.js';
|
|
7
|
+
export interface PlayerInstance {
|
|
8
|
+
id: string;
|
|
9
|
+
mediaApi: UseMediaApiReturn;
|
|
10
|
+
playerApi: UsePlayerInternalApiReturn;
|
|
11
|
+
controlsApi: UseControlsApiReturn;
|
|
12
|
+
runtimeProvider: UseRuntimeSourceProviderReturn;
|
|
13
|
+
args: UsePlayerApiArgs;
|
|
14
|
+
}
|
|
15
|
+
export declare function usePlayerStore(): {
|
|
16
|
+
playerStore: ShallowRef<PlayerInstance[]>;
|
|
17
|
+
findInstance: (id: string) => PlayerInstance;
|
|
18
|
+
addInstance: (id: string) => PlayerInstance;
|
|
19
|
+
removeInstance: (id: string) => void;
|
|
20
|
+
};
|