'use client'; import { useState, useEffect, useCallback } from 'react'; import { detectVideoFormat, VideoFile } from '@/lib/video-format-detector'; import ArtPlayerWrapper from '@/components/artplayer-wrapper'; interface UnifiedVideoPlayerProps { video: VideoFile; isOpen: boolean; onClose: () => void; playerType?: 'modal' | 'inline'; useArtPlayer?: boolean; onProgress?: (time: number) => void; onBookmark?: (videoId: number) => void; onUnbookmark?: (videoId: number) => void; onRate?: (videoId: number, rating: number) => void; showBookmarks?: boolean; showRatings?: boolean; scrollPosition?: number; formatFileSize?: (bytes: number) => string; autoplay?: boolean; } export default function UnifiedVideoPlayer({ video, isOpen, onClose, playerType = 'modal', useArtPlayer: forceArtPlayer = true, // Always use ArtPlayer now onProgress, onBookmark, onUnbookmark, onRate, showBookmarks = false, showRatings = false, scrollPosition, formatFileSize, autoplay = true }: UnifiedVideoPlayerProps) { const [format, setFormat] = useState | null>(null); const [isLoading, setIsLoading] = useState(true); const [isBookmarked, setIsBookmarked] = useState(false); const [bookmarkCheckLoading, setBookmarkCheckLoading] = useState(true); const [currentRating, setCurrentRating] = useState(0); const [ratingCheckLoading, setRatingCheckLoading] = useState(true); // Check current bookmark status and rating when video opens useEffect(() => { if (isOpen && video.id) { checkBookmarkStatus(); checkRatingStatus(); } }, [isOpen, video.id]); const checkBookmarkStatus = async () => { if (!video.id) return; setBookmarkCheckLoading(true); try { const response = await fetch(`/api/bookmarks/${video.id}`); if (response.ok) { const data = await response.json(); setIsBookmarked(data.isBookmarked || false); } else { setIsBookmarked(false); } } catch (error) { console.error('Error checking bookmark status:', error); setIsBookmarked(false); } finally { setBookmarkCheckLoading(false); } }; const checkRatingStatus = async () => { if (!video.id) return; setRatingCheckLoading(true); try { const response = await fetch(`/api/stars/${video.id}`); if (response.ok) { const data = await response.json(); setCurrentRating(data.rating || 0); } else { setCurrentRating(0); } } catch (error) { console.error('Error checking rating status:', error); setCurrentRating(0); } finally { setRatingCheckLoading(false); } }; // Detect format on mount useEffect(() => { if (video) { const detectedFormat = detectVideoFormat(video); setFormat(detectedFormat); setIsLoading(false); } }, [video]); // Handle ArtPlayer errors with recovery const handleArtPlayerError = useCallback((error: string) => { console.log('ArtPlayer encountered error:', error); // Try to recover by using direct streaming if HLS failed if (format?.type === 'hls') { console.log('HLS failed, trying direct streaming fallback...'); const directFormat = { ...format, type: 'direct' as const, url: `/api/stream/direct/${video.id}`, supportLevel: 'native' as const }; setFormat(directFormat); } else { console.log('ArtPlayer error with direct streaming, logging only'); // Just log the error, no more fallbacks needed } }, [format, video.id]); // Handle progress updates const handleProgressUpdate = useCallback((time: number) => { if (onProgress) { onProgress(time); } }, [onProgress]); // Handle bookmark toggle const handleBookmarkToggle = useCallback(async (videoId: number) => { if (onBookmark) { await onBookmark(videoId); setIsBookmarked(true); // Update local state } }, [onBookmark]); // Handle unbookmark const handleUnbookmark = useCallback(async (videoId: number) => { if (onUnbookmark) { await onUnbookmark(videoId); setIsBookmarked(false); // Update local state } }, [onUnbookmark]); // Handle rating const handleRatingUpdate = useCallback(async (videoId: number, rating: number) => { if (onRate) { await onRate(videoId, rating); setCurrentRating(rating); // Update local state } }, [onRate]); // Always render ArtPlayer (no more fallbacks) const renderPlayer = () => { // Always use ArtPlayer for both modal and inline modes return ( ); }; if (isLoading || bookmarkCheckLoading || ratingCheckLoading) { return (

Loading ArtPlayer...

); } return (
{/* ArtPlayer indicator (for debugging) */} {process.env.NODE_ENV === 'development' && format && (
ArtPlayer - {format.supportLevel}
)} {renderPlayer()}
); } // Re-export for external use export { detectVideoFormat };