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"> |
<script setup lang="ts"> |
||||||
|
import videojs from 'video.js' |
||||||
|
import { stripUndefinedOrNull } from '~/utils/objectUtils' |
||||||
|
import 'video.js/dist/video-js.css' |
||||||
|
|
||||||
interface Props { |
interface Props { |
||||||
srcs: string[] |
autoplay?: boolean |
||||||
alt?: string |
controls?: boolean |
||||||
mimeType?: string |
height?: string | number |
||||||
objectFit?: string |
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> |
</script> |
||||||
|
|
||||||
<template> |
<template> |
||||||
<video controls> |
<div |
||||||
<source :src="props.srcs[index]" :type="props.mimeType" /> |
class="w-full" |
||||||
Your browser does not support the video tag. |
:class="{ |
||||||
</video> |
[props.class]: props.class, |
||||||
|
}" |
||||||
|
> |
||||||
|
<video ref="videoPlayer" class="video-js h-full w-full"></video> |
||||||
|
</div> |
||||||
</template> |
</template> |
||||||
|
|
||||||
<style scoped lang="scss"></style> |
<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