feat: Introduce videojs as video player

Replaces the old default HTML video player with one on the basis of video.js
This commit is contained in:
aprilthepink 2025-02-05 20:34:09 +01:00
parent 094cb16801
commit 223d8b7870
4 changed files with 14 additions and 69 deletions

View file

@ -23,6 +23,7 @@
"@tiptap/vue-3": "^2.11.3", "@tiptap/vue-3": "^2.11.3",
"@vee-validate/zod": "^4.15.0", "@vee-validate/zod": "^4.15.0",
"@versia/client": "0.1.5", "@versia/client": "0.1.5",
"@videojs-player/vue": "^1.0.0",
"@vite-pwa/nuxt": "^0.10.6", "@vite-pwa/nuxt": "^0.10.6",
"@vueuse/core": "^12.5.0", "@vueuse/core": "^12.5.0",
"@vueuse/nuxt": "^12.5.0", "@vueuse/nuxt": "^12.5.0",
@ -744,6 +745,8 @@
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
"@types/video.js": ["@types/video.js@7.3.58", "", {}, "sha512-1CQjuSrgbv1/dhmcfQ83eVyYbvGyqhTvb2Opxr0QCV+iJ4J6/J+XWQ3Om59WiwCd1MN3rDUHasx5XRrpUtewYQ=="],
"@types/web-bluetooth": ["@types/web-bluetooth@0.0.20", "", {}, "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="], "@types/web-bluetooth": ["@types/web-bluetooth@0.0.20", "", {}, "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="],
"@unhead/dom": ["@unhead/dom@1.11.18", "", { "dependencies": { "@unhead/schema": "1.11.18", "@unhead/shared": "1.11.18" } }, "sha512-zQuJUw/et9zYEV0SZWTDX23IgurwMaXycAuxt4L6OgNL0T4TWP3a0J/Vm3Q02hmdNo/cPKeVBrwBdnFUXjGU4w=="], "@unhead/dom": ["@unhead/dom@1.11.18", "", { "dependencies": { "@unhead/schema": "1.11.18", "@unhead/shared": "1.11.18" } }, "sha512-zQuJUw/et9zYEV0SZWTDX23IgurwMaXycAuxt4L6OgNL0T4TWP3a0J/Vm3Q02hmdNo/cPKeVBrwBdnFUXjGU4w=="],
@ -762,6 +765,8 @@
"@versia/client": ["@versia/client@0.1.5", "", { "dependencies": { "@badgateway/oauth2-client": "^2.4.2", "zod": "^3.24.1" } }, "sha512-POD2/IT98EZZ32kWEPc3XUY2zApX94tuBftNWIMyoT04Sp7CPuvv1TT2fxM2kmgrC6kgbh4I6yirPpzVY+FpSA=="], "@versia/client": ["@versia/client@0.1.5", "", { "dependencies": { "@badgateway/oauth2-client": "^2.4.2", "zod": "^3.24.1" } }, "sha512-POD2/IT98EZZ32kWEPc3XUY2zApX94tuBftNWIMyoT04Sp7CPuvv1TT2fxM2kmgrC6kgbh4I6yirPpzVY+FpSA=="],
"@videojs-player/vue": ["@videojs-player/vue@1.0.0", "", { "peerDependencies": { "@types/video.js": "7.x", "video.js": "7.x", "vue": "3.x" } }, "sha512-WonTezRfKu3fYdQLt/ta+nuKH6gMZUv8l40Jke/j4Lae7IqeO/+lLAmBnh3ni88bwR+vkFXIlZ2Ci7VKInIYJg=="],
"@videojs/http-streaming": ["@videojs/http-streaming@3.17.0", "", { "dependencies": { "@babel/runtime": "^7.12.5", "@videojs/vhs-utils": "^4.1.1", "aes-decrypter": "^4.0.2", "global": "^4.4.0", "m3u8-parser": "^7.2.0", "mpd-parser": "^1.3.1", "mux.js": "7.1.0", "video.js": "^7 || ^8" } }, "sha512-Ch1P3tvvIEezeZXyK11UfWgp4cWKX4vIhZ30baN/lRinqdbakZ5hiAI3pGjRy3d+q/Epyc8Csz5xMdKNNGYpcw=="], "@videojs/http-streaming": ["@videojs/http-streaming@3.17.0", "", { "dependencies": { "@babel/runtime": "^7.12.5", "@videojs/vhs-utils": "^4.1.1", "aes-decrypter": "^4.0.2", "global": "^4.4.0", "m3u8-parser": "^7.2.0", "mpd-parser": "^1.3.1", "mux.js": "7.1.0", "video.js": "^7 || ^8" } }, "sha512-Ch1P3tvvIEezeZXyK11UfWgp4cWKX4vIhZ30baN/lRinqdbakZ5hiAI3pGjRy3d+q/Epyc8Csz5xMdKNNGYpcw=="],
"@videojs/vhs-utils": ["@videojs/vhs-utils@4.1.1", "", { "dependencies": { "@babel/runtime": "^7.12.5", "global": "^4.4.0" } }, "sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA=="], "@videojs/vhs-utils": ["@videojs/vhs-utils@4.1.1", "", { "dependencies": { "@babel/runtime": "^7.12.5", "global": "^4.4.0" } }, "sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA=="],

View file

@ -5,18 +5,9 @@
<img :src="attachment.url" :alt="attachment.description ?? undefined" <img :src="attachment.url" :alt="attachment.description ?? undefined"
class="w-full h-full object-contain bg-muted/20" /> class="w-full h-full object-contain bg-muted/20" />
</DialogTrigger> </DialogTrigger>
<VideoPlayer v-else-if="attachment.type === 'video' || attachment.type === 'gifv'" :src="attachment.url" <video-player v-else-if="attachment.type === 'video' || attachment.type === 'gifv'"
:alt="attachment.description ?? undefined" class="w-full h-full object-cover bg-muted/20" :options="{ :alt="attachment.description ?? undefined" class="w-full h-full object-cover bg-muted/20"
autoplay: false, src="attachment.url" controls :volume="0.6" />
controls: true,
preload: 'auto',
sources: [
{
src: attachment.url,
type: 'video/mp4'
}
]
}" />
<audio v-else-if="attachment.type === 'audio'" :src="attachment.url" <audio v-else-if="attachment.type === 'audio'" :src="attachment.url"
:alt="attachment.description ?? undefined" class="w-full h-full object-cover bg-muted/20" controls /> :alt="attachment.description ?? undefined" class="w-full h-full object-cover bg-muted/20" controls />
<DialogTrigger v-else :as-child="true"> <DialogTrigger v-else :as-child="true">
@ -56,18 +47,9 @@
<div class="flex items-center justify-center overflow-hidden *:max-h-[80vh] *:max-w-[80vw]"> <div class="flex items-center justify-center overflow-hidden *:max-h-[80vh] *:max-w-[80vw]">
<img v-if="attachment.type === 'image'" :src="attachment.url" :alt="attachment.description ?? ''" <img v-if="attachment.type === 'image'" :src="attachment.url" :alt="attachment.description ?? ''"
class="object-contain" /> class="object-contain" />
<VideoPlayer v-else-if="attachment.type === 'video' || attachment.type === 'gifv'" :src="attachment.url" <video-player v-else-if="attachment.type === 'video' || attachment.type === 'gifv'"
:alt="attachment.description ?? undefined" class="w-full h-full object-cover bg-muted/20" :options="{ :alt="attachment.description ?? undefined" class="w-full h-full object-cover bg-muted/20"
autoplay: false, src="attachment.url" controls :volume="0.6" />
controls: true,
preload: 'auto',
sources: [
{
src: attachment.url,
type: 'video/mp4'
}
]
}" />
<audio v-else-if="attachment.type === 'audio'" :src="attachment.url" :alt="attachment.description ?? ''" <audio v-else-if="attachment.type === 'audio'" :src="attachment.url" :alt="attachment.description ?? ''"
class="object-cover" controls /> class="object-cover" controls />
<div v-else class="flex flex-col items-center justify-center"> <div v-else class="flex flex-col items-center justify-center">
@ -98,7 +80,8 @@ import {
DialogTrigger, DialogTrigger,
} from "../ui/dialog"; } from "../ui/dialog";
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
import VideoPlayer from '@/components/notes/videoplayer.vue'; import { VideoPlayer } from '@videojs-player/vue'
import 'video.js/dist/video-js.css'
defineProps<{ defineProps<{
attachment: Attachment; attachment: Attachment;

View file

@ -1,44 +0,0 @@
<script lang="ts">
import videojs from 'video.js';
export default {
name: 'VideoPlayer',
props: {
options: {
type: Object,
default() {
return {};
}
},
url: {
type: String,
default() {
return "";
}
}
},
data() {
return {
player: null
}
},
mounted() {
this.player = videojs(this.$refs.videoPlayer, this.options, () => {
this.player.log('onPlayerReady', this);
});
},
beforeDestroy() {
if (this.player) {
this.player.dispose();
}
}
}
</script>
<template>
<div>
<video ref="videoPlayer" class="video-js" controls>
Your browser does not support the video tag.
</video>
</div>
</template>

View file

@ -49,6 +49,7 @@
"@tiptap/vue-3": "^2.11.3", "@tiptap/vue-3": "^2.11.3",
"@vee-validate/zod": "^4.15.0", "@vee-validate/zod": "^4.15.0",
"@versia/client": "0.1.5", "@versia/client": "0.1.5",
"@videojs-player/vue": "^1.0.0",
"@vite-pwa/nuxt": "^0.10.6", "@vite-pwa/nuxt": "^0.10.6",
"@vueuse/core": "^12.5.0", "@vueuse/core": "^12.5.0",
"@vueuse/nuxt": "^12.5.0", "@vueuse/nuxt": "^12.5.0",