728x90

What is mediasoup?

  • SFU(Selective Forwarding Unit)
    • SFU는 오디오, 비디오 스트림을 엔드포인트로 부터 받고 다른 모든 사람들에게 미디어를 전달한다.
  • node.js Library
    • 서버 없이는 작동될 수 없으며 반드시 node.js 애플리케이션 내에서 임포트되어야한다.
  • Signaling agnostic
    • 💡 agnostic : '불가지론자, 불가지론의'. 뭐 이런 뜻이라는 데 그냥 '독립적인' 정도로 해석하면 될 것 같다.
    • 시그널링 프로토콜이 필요하지 않다.
  • 모든 존재하는 WebRTC 엔드포인트에 지원이 가능하다.

 

 

mediasoup :: Overview

Cutting Edge WebRTC Video Conferencing

mediasoup.org

 

SFU

  • 하나의 피어는 오직 하나의 스트림만을 보낸다.
  • 중앙에 있는 미디어수프 서버로부터 하나 이상의 스트림을 받는다.

 

MESH

  • $n^2$ 형태의 peer-to-peer 로 연결
  • 오버헤드 발생 우려
    • 미디어 스트림을 처리하는 CPU 사용 처리 뿐만 아니라 대역폭 내에서도 3개 이상의 Peer(사용자)를 사용하지 않는 것이 좋다.

 

  • mediasoup는 기본적으로 소비자(comsumer)와 생산자(producer)에 기반한다.
  • 생산자는 미디어 수프 라우터를 통해 미디어를 보내고 소비자도 역시 미디어 수프 라우터를 통해 미디어를 받는다.
  • 생산자와 소비자를 생성하기 위해 transport를 생성한다.
    • 이러한 transport도 라우터에서 생성된다.
  • 라우터는 방을 나타내는 데, 방은 여러 전송을 보낼 수 있으며 각 방에는 생산자 transport 와 소비자 transport가 있다.
  • 라우터는 worker로부터 생성되고 worker는 많은 라우터를 가질 수 있다.
    • worker는 단일 cpu 코어 내에서 실행되므로 cpu하나당 하나의 worker만 가질 수 있다.
    • 만약 4개의 cpu 코어가 있다면 미디어 수프 서버내의 worker 수는 4개로 제한해야한다.




Transport, Producer, Consumer




mediasoup Producer Consumer(1)

⭐️ 구조도 그림에 있는 번호와 아래 번호와 함께 달아둔 설명을 연결해서 봐주세요! ⭐️

  • 2 server-side Transport(LP, LC) , 2 client-side Transport(RP, RC)

 

🔗 용어 정리

  • RtpCapabilities : 미디어 수신 관련 정보
  • transport : 엔드포인트와 미디어수프 라우터 연결
  • getUserMedia : 미디어 스트림 정보를 가져온다.
  • connect() : server-side transport와 연결을 위한 정보 교환을 수행하는 transport event
  • produce() : 새로운 Produer에 대한 정보를 server-side Transport로 전송하는 transport event

 

  • RP(Router Producer)
  • LP(Local Producer)
  • RC(Router Consumer)
  • LC(Local Consumer)

 

  1. 각 클라이언트는 라우터의 rtpCapabilities를 서버에 요청을 한다.
  2. 새로운 디바이스 객체를 생성하고 rtpCapabilities통해 로드 메소드를 호출한다.
    • 이때, rtpCapabilities는 나중에 등장하는 deviceRtpCapabilities가 아님을 유의해야한다.
    • getUserMedia() 메소드를 통해 비디오 트랙 정보를 얻는다.
  3. 서버에 server-side Transport를 요청한다.
    • 요청이 들어오면 라우터는 server-side Transport를 생성한다.
  4. 서버는 server-side Transport파라미터를 클라이언트로 보낸다.
  5. 클라이언트는 받은 파라미터와 디바이스를 사용해 client-side Send Transport를 생성한다.
  6. client-side Send Transport가 생성되면 client-side Send Transport의 produce()를 호출한다.
    • 여기서 produce()는 client-side Send Transport의 connect 이벤트와 produce 이벤트를 발생시킨다.
  7. (1) connect 이벤트
    • return : 서버측으로 dtlsParameters를 보낸다.
    • 💡 DTLS Protocol
  8. 클라이언트로부터 dtlsParameters를 받고 server-side Transport에서 connect()를 호출한다.
    • ✨ Producer 클라이언트 - 서버 연결
  9. (2) produce 이벤트
    • return : 서버측으로 파라미터, 콜백 메소드, 에러 메소드를 보낸다.
  10. 클라이언트로부터 파라미터들을 받고 server-side Transport에서 produce()를 호출한다.
    • produce() 호출시, Producer가 생성된다.
    • ✨ Producer 생성
  11. 서버는 생성된 Producer의 producer id를 클라이언트로 보낸다.
  12. 👋 이 이후 Consumer 프로세스는 Producer 프로세스와 동일하게 이루어진다.
  13. server-side Transportclient-side Receive Transport를 만든다.
    • (Producer 프로세스의 1~5과정과 동일)
    • ↔️ client-side Send Transport 와 차이가 있음 !
  14. Consumer를 만들기 위해 rtpCapabilitiesproducer id를 서버로 보낸다.
  15. 서버는 rtpCapabilitiesproducer id를 받고 라우터가 미디어 수신이 가능한지 확인한다.
    • 확인이 완료되면 server-side Transport에서 consume()을 호출한다.
    • consume() : rtpParametersconsumer id 반환
  16. 이렇게 만들어진 consumer id와 다른 파라미터들을 클라이언트에 보낸다.
  17. 파라미터들을 클라이언트에 전달한 다음 client-side Receive Transport의 consume()을 호출한다.
    • 여기서 consume()은 client-side Receive Transport의 connect 이벤트를 발생시킨다.
    • connect 이벤트
      • return : 서버측으로 dtlsParameters를 보낸다.
  18. 클라이언트로부터 dtlsParameters를 받고 server-side Transport에서 connect()를 호출한다.
    • ✨ Consumer 클라이언트 - 서버 연결




mediasoup Producer Consumer(2)

  1. Producer Peer와 Consumer Peer에서 디바이스 객체를 생성한다. 각각 디바이스를 리턴한다.
  2. 라우터에서 'rtpCapabilities'를 가져와 클라이언트로 보내고 디바이스 로드 메소드를 호출 하고 'rtpCapabilities'로 해당 디바이스를 정보를 보낸다.
    • Producer와 Consumer 각각에 대해 Router Transport를 생성한다.
    • Router Transport를 생성하기 위한 옵션을 설정한다.
  3. Router Transport 두 개가 만들어진다.(Producer, Consumer)
    • Router Transport로 부터 여러 파라미터들을 가져와, 클라이언트로 보낸다.
    • 해당 파라미터들은 Local Send Transport, Local Receive Transport를 만드는 데에 사용된다. (Local Transport)
  4. Local Send Transport에서 produce() 메소드를 수행한다.
    • 이때 파라미터로 인코딩과 같은 정보를 함께 전달한다.
    • produce() 메소드는 producer를 반환한다.
    • produce() 메소드에 대한 호출은 connect, produce 이벤트를 발생시킨다.
      • connect 이벤트는 dtlsParameters를 반환하고 서버와의 연결을 수행한다.
  5. produce 이벤트는 'kind', rtpParameters, callback, errback을 반환한다.(errback : 에러가 발생하는 경우를 대비한 메소드)
    • 파라미터를 보내고 서버측에서 produce() 메소드를 호출한다.
    • 이렇게 되면 서버측에 Producer가 생성되고, Producer는 클라이언트로 producer id를 반환한다.
    • 콜백 메소드에 producer id를 전달하여 반환한다.
    • Local Transport에게 서버측으로 부터 producer id를 받았다는 걸 알린다.
    • Local Producer에게 producer id를 전달한다.

----------- ⬆️ 미디어 송신 -----------

  1. Consumer Client는 서버로부터 스트리밍 미디어를 소비한다.
    1. 라우터의 Consumer(rtp capabilities)가 이전 단계에서 받은 producer id로 부터 Producer를 특정하고 producer로 부터 받은 미디어를 수신할 수 있는지 확인한다.이 메소드는 서버사이드 consumer 객체를 리턴하고 이 consumer 객체로 부터 몇몇 파라미터들을 가져올 수 있다.
    2. 만약 수신이 가능하다면 Router Transport의 consumer 메소드를 호출한다.
    3. 'rtpCapabilities'를 device로 부터 추출하고 이를 서버로 보낸다.
  2. 이러한 파라미터 (consumer id, producer id, kind, rtpParameters)를 클라이언트에 보낸다.
    • Local Receive Transport로부터 connect 이벤트를 발생시킨다.서버측에서 connect 메소드를 호출하여 Router Transport와 연결을 한다.
    • 이 connect 이벤트는 'dtlsParameters'를 반환하고 이를 서버로 보낸다.
    • Local Receive Transport에서 consumer 메소드를 실행하고 클라이언트 측 Consumer를 생성한다.

----------- ⬆️ 미디어 수신 -----------




Peer Disconnection

  • 시나리오 1 : Producer가 연결을 끊을 때
  • 시나리오 2 : Consumer가 연결을 끊을 때

 

  • 시나리오 1
    • producer connection issue가 발생했음을 알린다.
    • 브라우저가 닫히고 연결 해제를 수행해야한다.
      • ⭐️ mediasoup는 자동으로 연결 해제를 수행하지 않는다.
      • 웹 소켓을 통해 모든 연결을 모니터링 하는 방법이 있다.
    • socket.io를 통해 연결 해제 이벤트를 수신하게 되면 producer Transport의 닫기 메소드를 호출해야한다.
    • producer Transport의 닫기 메소드를 호출하면 producer 자기 자신을 종료시킨다.
    • 서버 사이드 소비자의 닫기 메소드가 이벤트가 발생한다.
    • 서버 사이드 consumer Transport 의 닫기 이벤트를 발생시킨다.
    • 이후, 클라이언트의 Transport와 Consumer에게 닫기가 발생했음을 알린다.

 

  • 시나리오 2
    • consumer 클라이언트가 연결을 끊을 때 서버 측 disconnect 이벤트가 트리거된다.
    • 그런다음 서버 사이드 Transport와 Consumer에서 닫기 메소드를 호출한다.




Reference

 
728x90