mirror of https://github.com/nocodb/nocodb
DarkPhoenix2704
4 months ago
4 changed files with 172 additions and 29 deletions
@ -1,23 +1,117 @@
|
||||
<script setup lang="ts"> |
||||
import videojs from 'video.js' |
||||
import { stripUndefinedOrNull } from '~/utils/objectUtils' |
||||
import 'video.js/dist/video-js.css' |
||||
|
||||
interface Props { |
||||
srcs: string[] |
||||
alt?: string |
||||
mimeType?: string |
||||
objectFit?: string |
||||
autoplay?: boolean |
||||
controls?: boolean |
||||
height?: string | number |
||||
loop?: boolean |
||||
muted?: boolean |
||||
poster?: string |
||||
preload?: 'auto' | 'metadata' | 'none' |
||||
width?: string | number |
||||
aspectRatio?: string |
||||
audioOnlyMode?: boolean |
||||
audioPosterMode?: boolean |
||||
autoSetup?: boolean |
||||
disablePictureInPicture?: boolean |
||||
enableDocumentPictireInPicture?: boolean |
||||
enableSmoothSeeking?: boolean |
||||
fluid?: boolean |
||||
src?: string |
||||
fullScreen?: { |
||||
options?: { |
||||
navigationUI?: 'hide' | 'show' |
||||
id?: string |
||||
} |
||||
} |
||||
inactivityTimeout?: number |
||||
language?: string |
||||
liveui?: boolean |
||||
notSupportedMessage?: string |
||||
playbackRates?: number[] |
||||
playsinline?: boolean |
||||
plugins?: Record<string, any> |
||||
preferFullWindow?: boolean |
||||
responsive?: boolean |
||||
restoreEl?: Element | boolean |
||||
skipButtons?: { |
||||
forward?: number |
||||
back?: number |
||||
} |
||||
sources?: { |
||||
src: string |
||||
type: string |
||||
}[] |
||||
suppressNotSupportedError?: boolean |
||||
techOrder?: string[] |
||||
userActions?: { |
||||
click?: (event: Event) => void | boolean |
||||
doubleClick?: (event: Event) => void | boolean |
||||
hotkeys?: (event: Event) => void | boolean | Record<string, (event: Event) => void> |
||||
} |
||||
class?: string |
||||
} |
||||
|
||||
const props = defineProps<Props>() |
||||
const props = withDefaults(defineProps<Props>(), { |
||||
preload: 'metadata', |
||||
aspectRatio: '16:9', |
||||
controls: true, |
||||
audioOnlyMode: false, |
||||
audioPosterMode: false, |
||||
autoSetup: true, |
||||
disablePictureInPicture: false, |
||||
enableDocumentPictireInPicture: false, |
||||
enableSmoothSeeking: true, |
||||
fluid: true, |
||||
fullScreen: { |
||||
options: { |
||||
navigationUI: 'hide', |
||||
id: undefined, |
||||
}, |
||||
}, |
||||
language: 'en', |
||||
liveui: false, |
||||
playsinline: true, |
||||
preferFullWindow: false, |
||||
responsive: false, |
||||
restoreEl: false, |
||||
}) |
||||
|
||||
const index = ref(0) |
||||
const emit = defineEmits<Emits>() |
||||
|
||||
const onError = () => index.value++ |
||||
interface Emits { |
||||
(event: 'init', player: any): void |
||||
} |
||||
|
||||
const videoPlayer = ref<Element>() |
||||
|
||||
const player = ref() |
||||
|
||||
onMounted(() => { |
||||
if (!videoPlayer.value) return |
||||
player.value = videojs(videoPlayer.value, stripUndefinedOrNull(props)) |
||||
emit('init', player.value) |
||||
}) |
||||
|
||||
onBeforeUnmount(() => { |
||||
if (player.value) { |
||||
player.value.dispose() |
||||
} |
||||
}) |
||||
</script> |
||||
|
||||
<template> |
||||
<video controls> |
||||
<source :src="props.srcs[index]" :type="props.mimeType" /> |
||||
Your browser does not support the video tag. |
||||
</video> |
||||
<div |
||||
class="w-full" |
||||
:class="{ |
||||
[props.class]: props.class, |
||||
}" |
||||
> |
||||
<video ref="videoPlayer" class="video-js h-full w-full"></video> |
||||
</div> |
||||
</template> |
||||
|
||||
<style scoped lang="scss"></style> |
||||
|
@ -0,0 +1,26 @@
|
||||
type NonUndefined<T> = T extends undefined ? never : T |
||||
type NonNull<T> = T extends null ? never : T |
||||
type NonNullableObject<T> = { |
||||
[K in keyof T]: NonUndefined<NonNull<T[K]>> |
||||
} |
||||
|
||||
type Prettify<T> = { |
||||
[K in keyof T]: T[K] |
||||
} & {} |
||||
|
||||
export const stripUndefinedOrNull = <T>(obj: T): Prettify<NonNullableObject<T>> => { |
||||
const strip = (input: unknown): unknown => { |
||||
return Array.isArray(input) |
||||
? input.map(strip) |
||||
: input !== null && typeof input === 'object' |
||||
? Object.entries(input) |
||||
.filter(([, value]) => value !== undefined && value !== null) |
||||
.reduce((acc, [key, value]) => { |
||||
acc[key as keyof typeof acc] = strip(value) |
||||
return acc |
||||
}, {} as Record<string, unknown>) |
||||
: input |
||||
} |
||||
|
||||
return strip(obj) as Prettify<NonNullableObject<T>> |
||||
} |
Loading…
Reference in new issue