@@ -24,22 +24,29 @@ function BroadcastPlayer({
2424 const videoRef = useRef < HTMLVideoElement > ( null ) ;
2525 const screenShareRef = useRef < HTMLVideoElement > ( null ) ;
2626 const canvasRef = useRef < HTMLCanvasElement > ( null ) ;
27+ const animationFrameRef = useRef < number > ( ) ;
2728
2829 // 비디오 스트림 설정
2930 useEffect ( ( ) => {
3031 if ( videoRef . current && mediaStream ) {
3132 videoRef . current . srcObject = mediaStream ;
3233 }
33- tracksRef . current [ 'mediaAudio' ] = mediaStream ?. getAudioTracks ( ) [ 0 ] ;
34- } , [ mediaStream , tracksRef . current ] ) ;
34+ } , [ isVideoEnabled , mediaStream ] ) ;
3535
3636 // 화면 공유 스트림 설정
3737 useEffect ( ( ) => {
3838 if ( screenShareRef . current && screenStream ) {
3939 screenShareRef . current . srcObject = screenStream ;
4040 }
41+ } , [ isScreenSharing , screenStream ] ) ;
42+
43+ useEffect ( ( ) => {
44+ tracksRef . current [ 'mediaAudio' ] = mediaStream ?. getAudioTracks ( ) [ 0 ] ;
45+ } , [ mediaStream ] ) ;
46+
47+ useEffect ( ( ) => {
4148 tracksRef . current [ 'screenAudio' ] = screenStream ?. getAudioTracks ( ) [ 0 ] ;
42- } , [ isScreenSharing , screenStream , tracksRef . current ] ) ;
49+ } , [ screenStream ] ) ;
4350
4451 // 미디어스트림 캔버스에 넣기
4552 useEffect ( ( ) => {
@@ -90,78 +97,53 @@ function BroadcastPlayer({
9097 const pipY = canvas . height - pipHeight ;
9198 context . drawImage ( videoRef . current , pipX , pipY , pipWidth , pipHeight ) ;
9299 }
93- } else if ( isVideoEnabled && videoRef . current ) {
94- // 화면 공유 off / 캠 on
95- context . drawImage ( videoRef . current , 0 , 0 , canvas . width , canvas . height ) ;
96- } else {
97- // 화면 공유 off / 캠 off
98- context . fillStyle = '#000000' ;
99- context . fillRect ( 0 , 0 , canvas . width , canvas . height ) ;
100100 }
101- requestAnimationFrame ( draw ) ;
101+ animationFrameRef . current = requestAnimationFrame ( draw ) ;
102102 } ;
103103
104104 const startDrawing = async ( ) => {
105105 draw ( ) ;
106106 tracksRef . current [ 'video' ] = canvas . captureStream ( 30 ) . getVideoTracks ( ) [ 0 ] ;
107+ videoRef . current ?. play ( ) ;
108+ screenShareRef . current ?. play ( ) ;
107109 if ( ! isStreamReady ) setIsStreamReady ( true ) ;
108110 } ;
109111
110112 if ( isVideoEnabled && isScreenSharing && mediaStream && screenStream ) {
111- mediaStream . getVideoTracks ( ) [ 0 ] . enabled = true ;
112- screenStream . getVideoTracks ( ) [ 0 ] . enabled = true ;
113113 startDrawing ( ) ;
114114 }
115+
116+ return ( ) => {
117+ if ( animationFrameRef . current ) {
118+ cancelAnimationFrame ( animationFrameRef . current ) ;
119+ }
120+ } ;
115121 } , [ isVideoEnabled , isScreenSharing , mediaStream , screenStream , isStreamReady ] ) ;
116122
117123 return (
118124 < div className = "relative w-full max-h-[310px] aspect-video" >
119- { isVideoEnabled && isScreenSharing ? (
120- < >
121- < video
122- ref = { videoRef }
123- autoPlay
124- muted
125- playsInline
126- className = "absolute top-0 left-0 w-full h-full object-cover"
127- />
128- < video
129- ref = { screenShareRef }
130- autoPlay
131- muted
132- playsInline
133- className = "absolute top-0 left-0 w-full h-full object-cover"
134- />
135- < canvas
136- ref = { canvasRef }
137- width = { RESOLUTION_OPTIONS [ 'high' ] . width }
138- height = { RESOLUTION_OPTIONS [ 'high' ] . height }
139- className = "absolute top-0 left-0 w-full h-full bg-surface-alt object-cover"
140- />
141- </ >
142- ) : isVideoEnabled && ! isScreenSharing ? (
143- < video
144- ref = { videoRef }
145- autoPlay
146- muted
147- playsInline
148- width = { RESOLUTION_OPTIONS [ 'high' ] . width }
149- height = { RESOLUTION_OPTIONS [ 'high' ] . height }
150- className = "absolute top-0 left-0 w-full h-full bg-surface-alt object-cover"
151- />
152- ) : ! isVideoEnabled && isScreenSharing ? (
153- < video
154- ref = { screenShareRef }
155- autoPlay
156- muted
157- playsInline
158- width = { RESOLUTION_OPTIONS [ 'high' ] . width }
159- height = { RESOLUTION_OPTIONS [ 'high' ] . height }
160- className = "absolute top-0 left-0 w-full h-full bg-surface-alt object-cover"
161- />
162- ) : (
163- < div className = "absolute top-0 left-0 w-full h-full bg-surface-alt" />
164- ) }
125+ < video
126+ ref = { videoRef }
127+ autoPlay
128+ muted
129+ playsInline
130+ className = { `absolute top-0 left-0 w-full h-full bg-surface-alt ${ isVideoEnabled ? '' : 'hidden' } ` }
131+ />
132+ < video
133+ ref = { screenShareRef }
134+ autoPlay
135+ muted
136+ playsInline
137+ className = { `absolute top-0 left-0 w-full h-full bg-surface-alt ${ isScreenSharing ? '' : 'hidden' } ` }
138+ />
139+ < canvas
140+ ref = { canvasRef }
141+ width = { RESOLUTION_OPTIONS [ 'high' ] . width }
142+ height = { RESOLUTION_OPTIONS [ 'high' ] . height }
143+ className = { `absolute top-0 left-0 w-full h-full bg-surface-alt object-cover ${
144+ ! isScreenSharing || ! isVideoEnabled ? 'hidden' : ''
145+ } `}
146+ />
165147 </ div >
166148 ) ;
167149}
0 commit comments