);
}
export default function YouTubePlayer({
videoId,
title,
autoplay = true,
onVideoEnd,
onVideoReady
}: YouTubePlayerProps) {
const playerRef = useRef(null);
const playerInstanceRef = useRef(null);
const [isApiReady, setIsApiReady] = useState(false);
const [isPlayerReady, setIsPlayerReady] = useState(false);
const [error, setError] = useState(null);
const router = useRouter();
// Load YouTube IFrame API
useEffect(() => {
if (window.YT && window.YT.Player) {
setIsApiReady(true);
return;
}
// Check if script already exists
const existingScript = document.querySelector('script[src*="youtube.com/iframe_api"]');
if (existingScript) {
// Script exists, wait for it to load
const checkYT = setInterval(() => {
if (window.YT && window.YT.Player) {
setIsApiReady(true);
clearInterval(checkYT);
}
}, 100);
return () => clearInterval(checkYT);
}
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
tag.async = true;
document.head.appendChild(tag);
window.onYouTubeIframeAPIReady = () => {
console.log('YouTube IFrame API ready');
setIsApiReady(true);
};
return () => {
// Clean up
window.onYouTubeIframeAPIReady = () => {};
};
}, []);
// Initialize player when API is ready
useEffect(() => {
if (!isApiReady || !playerRef.current || !videoId) return;
// Destroy previous player instance if exists
if (playerInstanceRef.current) {
try {
playerInstanceRef.current.destroy();
} catch (e) {
console.log('Error destroying player:', e);
}
playerInstanceRef.current = null;
}
try {
const player = new window.YT.Player(playerRef.current, {
videoId: videoId,
playerVars: {
autoplay: autoplay ? 1 : 0,
controls: 1,
rel: 0,
modestbranding: 0,
playsinline: 1,
enablejsapi: 1,
origin: window.location.origin,
widget_referrer: window.location.href,
iv_load_policy: 3,
fs: 0,
disablekb: 0,
color: 'white',
},
events: {
onReady: (event: any) => {
console.log('YouTube Player ready for video:', videoId);
setIsPlayerReady(true);
if (onVideoReady) onVideoReady();
// Auto-play if enabled
if (autoplay) {
try {
event.target.playVideo();
} catch (e) {
console.log('Autoplay prevented:', e);
}
}
},
onStateChange: (event: any) => {
// Video ended
if (event.data === window.YT.PlayerState.ENDED) {
if (onVideoEnd) {
onVideoEnd();
}
}
},
onError: (event: any) => {
console.error('YouTube Player Error:', event.data);
setError(`Failed to load video (Error ${event.data})`);
},
},
});
playerInstanceRef.current = player;
} catch (error) {
console.error('Failed to create YouTube player:', error);
setError('Failed to initialize video player');
}
return () => {
if (playerInstanceRef.current) {
try {
playerInstanceRef.current.destroy();
} catch (e) {
console.log('Error cleaning up player:', e);
}
playerInstanceRef.current = null;
}
};
}, [isApiReady, videoId, autoplay]);
// Handle video end
useEffect(() => {
if (!isPlayerReady || !onVideoEnd) return;
const handleVideoEnd = () => {
onVideoEnd();
};
// The onStateChange event handler already handles this
}, [isPlayerReady, onVideoEnd]);
if (error) {
return (
{error}
);
}
return (
{!isPlayerReady && !error && }
);
}
// Utility function to play a video
export function playVideo(videoId: string) {
if (window.YT && window.YT.Player) {
// Could create a new player instance or use existing one
console.log('Playing video:', videoId);
}
}
// Utility function to pause video
export function pauseVideo() {
// Would need to reference player instance
}