Mediasoup 여러 화면 공유

이진호·2024년 1월 22일
0

최종프로젝트

목록 보기
11/18
post-thumbnail
post-custom-banner

mediasoup은 결국에 하나의 transport에 여러 proudcer를 넣을 수 있다. 그래서 하나의 화면을 공유하는 것이 아니라 여러 개의 화면을 공유할 수 있다.

여러 개의 화면을 공유하기 위해서는 producer를 모을 수 있는 배열이 필요하고 mediasoup의 transport를 이용하여 produce메서드만 실행하면 여러 화면을 공유할 수 있다.

producer 상태값 관리

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

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')이 내용을 통해서 서버와 통신을 하면 된다.

producer render component

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;
    	}}
      />
}
profile
dygmm4288
post-custom-banner

0개의 댓글