snapify-authentik/src/components/VideoPlayer.tsx
2024-11-21 02:01:51 +01:00

83 lines
2 KiB
TypeScript

import "@vidstack/react/player/styles/base.css";
import React, { useEffect, useRef } from "react";
import {
isHLSProvider,
MediaPlayer,
MediaProvider,
Poster,
type MediaCanPlayDetail,
type MediaCanPlayEvent,
type MediaPlayerInstance,
type MediaProviderAdapter,
type MediaProviderChangeEvent,
} from "@vidstack/react";
import { VideoLayout } from "./VideoLayout";
interface Props {
video_url: string;
thumbnailUrl?: string;
}
export default function VideoPlayer({ video_url, thumbnailUrl }: Props) {
const player = useRef<MediaPlayerInstance>(null);
useEffect(() => {
// Subscribe to state updates.
return player.current!.subscribe(({ paused, viewType }) => {
// console.log('is paused?', '->', state.paused);
// console.log('is audio view?', '->', state.viewType === 'audio');
});
}, []);
function onProviderChange(
provider: MediaProviderAdapter | null,
nativeEvent: MediaProviderChangeEvent
) {
// We can configure provider's here.
if (isHLSProvider(provider)) {
provider.config = {};
}
}
// We can listen for the `can-play` event to be notified when the player is ready.
function onCanPlay(
detail: MediaCanPlayDetail,
nativeEvent: MediaCanPlayEvent
) {
// ...
}
return (
<MediaPlayer
className="ring-media-focus aspect-video w-full overflow-hidden rounded-md bg-black font-sans text-white data-[focus]:ring-4"
title="Sprite Fight"
src={[
{
src: video_url,
type: "video/mp4",
},
]}
crossOrigin
playsInline
onProviderChange={onProviderChange}
onCanPlay={onCanPlay}
ref={player}
keyTarget="document"
>
<MediaProvider>
{thumbnailUrl ? (
<Poster
className="absolute inset-0 block h-full w-full rounded-md object-cover opacity-0 transition-opacity data-[visible]:opacity-100"
src={thumbnailUrl}
alt="video thumbnail"
/>
) : null}
</MediaProvider>
<VideoLayout />
</MediaPlayer>
);
}