import { Image } from 'expo-image'; import { useVideoPlayer, VideoView } from 'expo-video'; import { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { StyleSheet, View } from 'react-native'; import type { VideoPlayerProps } from './types'; import { useSharedVisibility } from './useSharedVisibility'; import { getVideoThumbnail, getVideoUrl } from '@/lib/utils/media'; const videoViewStyle = { width: '100%', height: '100%', position: 'absolute' as const, top: 0, left: 0, right: 0, bottom: 0 }; const originalImageStyle = { width: 64, height: 64, position: 'absolute' as const, bottom: 8, left: 8, borderRadius: 12, borderWidth: 1, borderColor: "#ffffff", zIndex: 99 }; const imageStyle = { width: '100%', borderWidth: 0 }; function VideoPlayerComponent({ source, originalImage, style, dwellTime = 500, threshold = 0.1 }: VideoPlayerProps) { const [imageAspectRatio, setImageAspectRatio] = useState(1); const { ref: viewRef, isVisible, shouldPlay } = useSharedVisibility(threshold, dwellTime); const url = useMemo(() => { return source?.uri }, [source]) const isVideo = useMemo(() => { return /\.(mp4|webm|ogg|mov|avi)$/i.test(url || ``) }, [url]) const thumbnailUrl = useMemo(() => { if (!isVideo) return url; return getVideoThumbnail(url!, { time: '0s', width: 600, height: 600, fit: 'cover' }); }, [url, isVideo]); const player = useVideoPlayer( isVideo ? { ...source, uri: getVideoUrl(source.uri!) } : null, (p) => { p.loop = true; p.muted = true; } ) useEffect(() => { if (!isVideo || !player) return; try { shouldPlay ? player.play() : player.pause(); } catch { } }, [shouldPlay, player, isVideo]); const handleImageLoad = useCallback((e: any) => { const { width, height } = e.source; if (width && height) { setImageAspectRatio(width / height); } }, []); const element = useMemo(() => { if (!isVisible) return null; if (isVideo && player) { return <> {originalImage && } } else { return } }, [isVideo, isVisible, imageAspectRatio, player, thumbnailUrl, originalImage, handleImageLoad]) return ( {element} ); } const styles = StyleSheet.create({ container: { width: '100%', height: '100%', overflow: 'hidden' } }); export default memo(VideoPlayerComponent);