이전글 : NextJS, Mediasoup, socketIO를 이용한 화상 회의 구현 1 (클라이언트 device, transport 세팅)
버튼을 눌르면 media stream을 받아서 해당 media stream의 track의 값을 기준으로 produce메서드를 통해서 producer를 만들어야 한다. 이때 produce 메서드에 appData라는 것을 넣을 수 있는데 이 값에 producer에서 필요한 정보들을 넣을 수 있다. 이번 프로젝트의 경우에는 trackId, streamId, playerId 등을 넣었다.
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,
},
};
async const handleShare = () => {
const mediaStream: MediaStream = await getMediaStreamByType(type);
try {
const track = stream.getVideoTracks()[0];
const producer = await sendTransport.current?.produce({
track,
...videoParams,
appData: {trackId, streamId, playerId},
});
setProducers(prev => [...prev,producer]);
} catch(error) {
console.log('phandle share error', error);
}
}
sendTransport의 produce가 동작을 하게 된다면 이전의 코드인 produce 이벤트가 동작하게 된다.
produce 이벤트 안에는 socket으로 transport-send-produce 메시지를 보내고 이때 생성된 producer의 정보들이 들어온다. parameter에는 appData를 포함하여 서버의 producer와 매칭을 하기 위한 내용들이 포함돼있다.
여기서 사용하는 spaceId라던가 playerId라던가에 대한 내용은 프로젝트에서 사용하는 값으로 mediasoup 로직과는 직접적인 관련이 없다. 다만 여러가지 값을 특정하기 위해서 존재한다.
socket.on('transport-send-produce',
async ({parameter,playerId},callback) => {
const client = clients[playerId];
try {
const producer = await client[SEND_TRANSPORT_KEY].produce(parameter);
producer.on('transportclose',() => {
producer.close();
client.producers = client.producers.filter(
p => p.id !== producer.id
)
});
client.producers.push(producer);
callback({id: producer.id});
} catch(error) {
console.error('while produce send trnasport error', error);
}
});
여기까지 클라이언트1과 서버와 transport를 통해서 produce가 생성되는 과정을 살펴봤고 다음에 클라이언트2가 등장했을 경우에는 클라이언트1이 했던 행위를 produce를 실행하기 이전까지 동일하고 consume을 하는 과정이 필요한데 그 과정은 다음 글에서 작성을 이어나가겠다.