WebRTC 화면공유를 구현해보자.
<div onClick={onClickShare}> 화면공유 </div>
const stream = await navigator.mediaDevices.getDisplayMedia();
// 페이지 내의 화면공유 종료 버튼이 아닌
// 크롬 자체의 공유중지 버튼을 눌렀을때
// 즉, 공유된 비디오가 종료되었을때 호출시킬 부분
stream.getVideoTracks()[0].onended = () => {
onClickShareExit();
}
// 화면공유된 stream과 기존 카메라 stream이 replace 됨에 따라
// 기존 카메라 stream을 따로 담아두었다.
shareStreamRef.current = localStreamRef.current;
if (shareVideoRef.current) {
shareVideoRef.current.srcObject = localVideoRef.current.srcObject;
}
localStreamRef.current = stream;
if (localVideoRef.current) {
localVideoRef.current.srcObject = stream;
}
let keys = Object.keys(rpcRef.current);
// 기존 1:N 연결을 구현하면서 RtcPeerConnection의 관리를
// '나'를 뺀 다른 유저들만 rpcRef에 담아서 관리를 했는데
// 아무 유저도 들어오지 않았을때 화면공유를 먼저 실행한 경우에
// 화면공유의 stream이 아닌 기존 카메라 stream이 다른 유저에게 노출되어
// 아무도 없는경우에 peerConnection을 추가적으로 담아주었다.
if (keys.length === 0) {
const pc = createPeerConnection('mypc', 'shareVideo');
rpcRef.current = { ...rpcRef.current, [username]: pc };
if (shareStreamRef.current) {
rpcRef.current[username]
.getSenders()
.find((s) => s?.track?.kind === 'video')
?.replaceTrack(shareStreamRef.current?.getTracks()[1]);
}
} else {
for (let i = 0; i < keys.length; i++) {
const sender = rpcRef.current[keys[i]].getSenders().find((s) => s?.track?.kind === 'video');
let videoTrack = stream.getVideoTracks()[0];
sender?.replaceTrack(videoTrack);
}
}
<div onClick={onClickShareExit}>화면공유 종료</div>
const onClickShareExit = () => {
let keys = Object.keys(rpcRef.current);
for(let i = 0; i < keys.length; i++) {
const sender = rpcRef.current[keys[i]].getSenders().find((s) => s?.track?.kind === 'video');
let videoTrack = stream.getVideoTracks()[0];
if (videoTrack) {
let rpcKeys = Object.keys(rpcRef.current);
for ( let j = 0; j < rpcKeys.length; j++) {
if (shareStreamRef.current) {
sender?.replaceTrack(shareStreamRef.current?.getTracks()[1]);
}
}
}
}
}
내 카메라 영상과 화면공유 영상이 Replace 되는것만 아닌,
카메라영상과 화면공유영상 2개다 나오는 방법도 생각해보자.