Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 51 additions & 32 deletions src/player/components/PlayerIframe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@ interface PlayerIframeProps {
}

export default function PlayerIframe({ videoSrc, onNextVideo, isPlaying }: PlayerIframeProps) {
const iframeRef = useRef<HTMLIFrameElement>(null);
const iframeRef = useRef<HTMLIFrameElement | null>(null);
const isPlayingRef = useRef(isPlaying);
const onNextVideoRef = useRef(onNextVideo);

const [time, setTime] = useState({ current: 0, duration: 0 });

// iframe 랜더링 시 이벤트 등록
const setIframeRef = (node: HTMLIFrameElement | null) => {
iframeRef.current = node;
if (node) {
node.addEventListener('load', loadEventListener);
}
};

useEffect(() => {
const interval = setInterval(() => {
const video = getVideoElement();
Expand Down Expand Up @@ -54,7 +62,7 @@ export default function PlayerIframe({ videoSrc, onNextVideo, isPlaying }: Playe
};

// load 이벤트 시 video listener 세팅
const attachVideoListeners = () => {
const loadEventListener = () => {
const video = getVideoElement();
if (!video) return;

Expand All @@ -69,8 +77,8 @@ export default function PlayerIframe({ videoSrc, onNextVideo, isPlaying }: Playe
useEffect(() => {
const iframe = iframeRef.current;
if (!iframe) return;
iframe.addEventListener('load', attachVideoListeners);
return () => iframe.removeEventListener('load', attachVideoListeners);
iframe.addEventListener('load', loadEventListener);
return () => iframe.removeEventListener('load', loadEventListener);
}, [videoSrc]);

// isPlaying 변경 시 재생 상태 제어
Expand All @@ -89,38 +97,49 @@ export default function PlayerIframe({ videoSrc, onNextVideo, isPlaying }: Playe
}, []);

return (
<div className="relative w-full h-full items-center justify-center">
<div className="absolute inset-0 flex items-center justify-center text-white text-6xl font-bold bg-transparent pointer-events-none">
{time.duration > 0 ? (
<div className="flex items-center justify-center p-8 bg-zinc-950 bg-opacity-80 rounded-xl">
<span className="flex items-center justify-center text-white min-w-[4ch]">
{Math.floor(time.current / 60)}:
{Math.floor(time.current % 60)
.toString()
.padStart(2, '0')}{' '}
</span>
<span className="flex items-center justify-center text-zinc-300"> / </span>
<span className="flex items-center justify-center text-zinc-300 min-w-[4ch]">
{Math.floor(time.duration / 60)}:
{Math.floor(time.duration % 60)
.toString()
.padStart(2, '0')}
</span>
</div>
<div className={`relative w-full h-full items-center justify-center rounded-xl ${!isPlaying && 'bg-black'}`}>
<div
className={`absolute inset-0 flex items-center justify-center text-white
text-6xl font-bold bg-transparent pointer-events-none`}
>
{isPlaying ? (
time.duration > 0 ? (
<div className="flex items-center justify-center p-8 bg-zinc-950 bg-opacity-80 rounded-xl">
<span className="flex items-center justify-center text-white min-w-[4ch]">
{Math.floor(time.current / 60)}:
{Math.floor(time.current % 60)
.toString()
.padStart(2, '0')}{' '}
</span>
<span className="flex items-center justify-center text-zinc-300"> / </span>
<span className="flex items-center justify-center text-zinc-300 min-w-[4ch]">
{Math.floor(time.duration / 60)}:
{Math.floor(time.duration % 60)
.toString()
.padStart(2, '0')}
</span>
</div>
) : (
<div>영상 정보가 없습니다</div>
)
) : (
<div>영상 정보가 없습니다</div>
<div className="flex justify-center items-center text-center text-3xl">
자동수강을 시작하려면 수강시작 버튼을 눌러주세요
</div>
)}
</div>

<iframe
ref={iframeRef}
src={videoSrc}
sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation-by-user-activation"
allow="autoplay"
width="100%"
height="100%"
className="rounded-lg pointer-events-none"
/>
{videoSrc && isPlaying && (
<iframe
ref={setIframeRef}
src={videoSrc}
sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation-by-user-activation"
allow="autoplay"
width="100%"
height="100%"
className="rounded-lg pointer-events-none"
/>
)}
</div>
);
}
Loading