mediasoup은 결국에 하나의 transport에 여러 proudcer를 넣을 수 있다. 그래서 하나의 화면을 공유하는 것이 아니라 여러 개의 화면을 공유할 수 있다.
여러 개의 화면을 공유하기 위해서는 producer를 모을 수 있는 배열이 필요하고 mediasoup의 transport를 이용하여 produce메서드만 실행하면 여러 화면을 공유할 수 있다.
export default function VideoConference() {
const [producers,setProducers] = useState([]);
function addProducer(producer) {
setProducers(prev => [...prev,producer]);
}
}
간단하게 producers 상태를 만들고 여기에 공유를 할 경우에 produce를 추가할 것이다.
export default function ShareButton({onShare}) {
async function handleShare() {
const stream = await navigator.mediaDevice.getDisplayMedia({
video: {displaySurface:'window'},
audio: false,
});
onShare(stream);
}
return <button onClick={handleShare}>공유</button>
}
공유 버튼을 만들고 나서 stream을 만들고 난 뒤에 onShare의 인수로 제공하여 mediasoup을 위한 로직을 분리하였다.
mediasoup에서 기본적으로 transport는 만들어졌다고 가정하고 진행을 한다면
export const videoParams = {
// mediasoup params
encodings: [
{
rid: "r0",
maxBitrate: 100000,
scalabilityMode: "S1T3",
},
{
rid: "r1",
maxBitrate: 300000,
scalabilityMode: "S1T3",
},
{
rid: "r2",
maxBitrate: 900000,
scalabilityMode: "S1T3",
},
],
codecOptions: {
videoGoogleStartBitrate: 1000,
},
};
function handleCreateProducer(stream) {
try {
const videoTracks = stream.getVideoTracks();
const producerParams = {...videoParams};
const track = videoTracks[0];
const producer = await sendTransport.produce({
track,
...producerParams,
appData: {
trackId: track.id,
streamId: stream.id,
}
});
if(!producer) throw new Error('no producer...');
addProducer(producer);
} catch(error) {
console.error('handle share error',error);
}
}
mediasoup에서 제공하는 transport의 produce메서드를 이용해서 producer를 만들 수 있고 이 producer를 만들게 된다면 transport를 만들었을 때 등록한 transport.on('produce')이 내용을 통해서 서버와 통신을 하면 된다.
producers에 포함된 producer를 통해서 video에 담으면 된다.
export default function MediaItem({producer}) {
const {track} = producer;
const stream = new MediaStream([track]);
return <video
autoPlay
playsInline
ref={(videoRef) => {
if(!videoRef) return;
videoRef.srcObject = stream;
}}
/>
}