mono/packages/ui/src/player/components/VideoPlayer.tsx
babayaga 8ec419b87e ui
2026-01-29 17:57:27 +01:00

87 lines
2.5 KiB
TypeScript

/**
* Main Video Player Component
* Based on deobfuscated TikTok video player implementation
*/
import React, { useRef, useEffect } from 'react';
import { VideoItem } from '../types';
import { MediaPlayer, MediaProvider, type MediaPlayerInstance } from '@vidstack/react';
import { defaultLayoutIcons, DefaultVideoLayout } from '@vidstack/react/player/layouts/default';
// Import Vidstack styles
import '@vidstack/react/player/styles/default/theme.css';
import '@vidstack/react/player/styles/default/layouts/video.css';
interface VideoPlayerProps {
video: VideoItem;
isActive: boolean;
isMuted: boolean;
autoPlay: boolean;
onPlayerChange: (player: MediaPlayerInstance | null) => void;
className?: string;
}
export const VideoPlayer: React.FC<VideoPlayerProps> = ({
video,
isActive,
isMuted,
autoPlay,
onPlayerChange,
className = ''
}) => {
const player = useRef<MediaPlayerInstance>(null);
console.log('autoPlay ' + video.video.playAddr, autoPlay, video);
useEffect(() => {
// player.current.muted = false;
}, []);
useEffect(() => {
// Pass the player instance to the parent component.
onPlayerChange(player.current);
}, [onPlayerChange]);
useEffect(() => {
// This effect ensures that the mute state of the player is always in sync
// with the global mute state managed by the VideoFeed component.
if (player.current) {
player.current.muted = isMuted;
}
}, [isMuted]);
return (
<div className={`w-full h-full bg-black flex justify-center items-center ${className}`}>
{/* Video Player - Using Vidstack for HLS support */}
<MediaPlayer
ref={player}
title={video.desc || 'Video'}
src={
video.video.playAddr.includes('/api/videos/')
? { src: video.video.playAddr, type: 'video/mp4' }
: video.video.playAddr
}
poster={video.video.cover}
playsInline
loop
muted={false}
autoPlay={true}
load={isActive ? "eager" : "idle"}
posterLoad="eager"
crossOrigin="anonymous"
className="w-full h-full"
style={{
'--video-brand': '#ff0050',
'--media-object-fit': 'contain',
'--media-object-position': 'center'
} as any}
>
<MediaProvider />
<DefaultVideoLayout
icons={defaultLayoutIcons}
noScrubGesture
/>
</MediaPlayer>
</div>
);
};