126 lines
2.9 KiB
Vue
126 lines
2.9 KiB
Vue
<template>
|
|
<media-player
|
|
class="magVideoPlayer"
|
|
:title="video.comment"
|
|
:src="{
|
|
src: video.url,
|
|
type: magTransProperty(video, 'mime_type', 'type'),
|
|
}"
|
|
:media-type="magTransProperty(video, 'mime_type', 'type')"
|
|
:volume="volume"
|
|
:controlsDelay="500"
|
|
:hideOnMouseLeave="true"
|
|
:load="'play'"
|
|
crossOrigin
|
|
playsInline
|
|
@volume-change="volumeChange"
|
|
>
|
|
<media-provider>
|
|
<media-poster
|
|
:src="magTransProperty(video, 'thumbnail_url', 'thumbnailUrl')"
|
|
>
|
|
</media-poster>
|
|
</media-provider>
|
|
<media-plyr-layout
|
|
:download="{ filename: video.name, url: video.url }"
|
|
:controls="controls"
|
|
>
|
|
</media-plyr-layout>
|
|
</media-player>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import "vidstack/player/styles/plyr/theme.css";
|
|
import "vidstack/player";
|
|
import "vidstack/player/layouts";
|
|
import "vidstack/player/ui";
|
|
|
|
import type * as misskey from "calckey-js";
|
|
import { packed } from "magnetar-common";
|
|
import { magTransProperty } from "@/scripts-mag/mag-util";
|
|
import { ColdDeviceStorage } from "@/store";
|
|
import { computed, ref } from "vue";
|
|
import { useWindowSize } from "@vueuse/core";
|
|
import { MediaPlayerElement } from "vidstack/elements";
|
|
|
|
defineProps<{
|
|
video: packed.PackDriveFileBase | misskey.entities.DriveFile;
|
|
}>();
|
|
|
|
const controlsSmall = [
|
|
"play",
|
|
"current-time",
|
|
"progress",
|
|
"duration",
|
|
"mute",
|
|
"download",
|
|
"fullscreen",
|
|
];
|
|
|
|
const controlsLarge = [
|
|
"play",
|
|
"current-time",
|
|
"progress",
|
|
"duration",
|
|
"mute+volume",
|
|
"settings",
|
|
"download",
|
|
"pip",
|
|
"fullscreen",
|
|
];
|
|
|
|
function getLayoutControls(width: number) {
|
|
if (width > 600) {
|
|
return controlsLarge;
|
|
} else {
|
|
return controlsSmall;
|
|
}
|
|
}
|
|
|
|
const volume = ref(ColdDeviceStorage.get("mediaVolume"));
|
|
const { width } = useWindowSize();
|
|
const controls = computed(() =>
|
|
structuredClone(getLayoutControls(width.value))
|
|
);
|
|
|
|
function volumeChange(e: Event): void {
|
|
let tgt = e.target as MediaPlayerElement | undefined;
|
|
|
|
if (tgt?.volume) ColdDeviceStorage.set("mediaVolume", tgt?.volume);
|
|
}
|
|
</script>
|
|
<style lang="scss">
|
|
.magVideoPlayer {
|
|
--plyr-color-main: var(--accent);
|
|
|
|
&[data-view-type="video"] {
|
|
aspect-ratio: 16 / 9;
|
|
}
|
|
|
|
& video {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
& .plyr--video {
|
|
& .plyr__controls {
|
|
transition: opacity 0.2s ease-in-out;
|
|
|
|
& .plyr__volume {
|
|
@media all and (max-width: 600px) {
|
|
flex: initial;
|
|
|
|
& + .plyr__controls__item {
|
|
margin-left: 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
&.plyr--hide-controls .plyr__controls {
|
|
transform: unset;
|
|
}
|
|
}
|
|
}
|
|
</style>
|