Technical WebRTC

WebRTC로 화상채팅 만들기-2편 WebRTC 프로토콜과 소스작성

안녕하세요.오늘은 WebRTC 프로토콜에 대해 설명하기로 합니다
먼저 아래 주의사항을 읽기 바랍니다. 

  • Note

WebRTC는 대부분의 Web Browser에서 지원됩니다.PC에서는 Google Chrome, Firefox, Edge 브라우저 모두 사용 가능합니다.다만 Mobile에서ios의 모든 브라우저는 지원을 하지 않습니다. (애플 스마트폰에서 지원하지 않음)또한 각 브라우저별로 API가 조금씩 다릅니다.그래서 현재는 WebRTC와 함께 adapter.js라는 API를 많이 사용합니다.adapter.js는 브라우저별로 나누어진 WebRTC의 소스들을 하나로 통합해줍니다.adapter.js의 설명은 아래 링크에서 더 자세히 보면 됩니다.https://www.evernote.com/l/AO5b-A4OpNhLlb6PekfSGqgCriKv80NDWmY/
먼저 프로토콜을 알기전에 핵심이 되는 단어에 대해 알아봅시다


1. Caller 와 Callee 는 무엇인가?

  • Caller : 처음 서버에 연결되어 가상의 공간(개념적 공간)을 생성하는 pc(사용자)
  • Callee : Caller가 만든 가상의 공간에 접속하여 활동하는 pc(사용자)

[ Caller와 Callee의 접속 ]

2. Caller와 Callee의 큰 흐름

  • 사용자 연결 : 두 사용자를 동일한 토큰을 이용하여 연결
  • 시그널링 시작 : 별도 서버를 이용하여 두 사용자의 연결 설정을 조율
  • Candidate 발견 : 두 개의 브라우저가 연결되는 과정( ICE 프로토콜을 이용하여 연결된다 )
  • 미디어 세션 협상
  • RTCPeerConnection 시작

참조 : WebRTC 프로그래밍 : 실시간 P2P 통신 애플리케이션 개발(롬 맨슨 지음 | 류영선 옮김)
그럼이제 소스에 대해 알아보도록 합시다WebRTC 소스의 어려운점은 수많은 Event와 Handler들로 인해 실질적인 소스의 순서를 알기 어렵다는 것에 있습니다.이를 Caller와 Callee의 입장에서 순서대로 분할하여 보여 드립니다.

2-1. Caller의 소스순서
물리적으로 카메라, 오디오등의 미디어 장비와 연결이 가능한지 확인한다

  • getUserMedia : 전송할 MediaStream을 연다 ( 음성, 비디오 )

Caller와 Callee의 연결 협상을 한다

  • Sinaling 서버에 연결
  • RTCPeerConnection 생성 : 네트워크 연결 객체를 생성한다
  • RTCPeerConnection.addTrack  : 로컬 비디오 스트림을  전송 네트워크에 연결시킨다
    • 이 부분이 addStream으로 작성되어 있는 소스가 있는데 이전 버전 소스이다
  • RTCPeerConnection.createOffer : 수신자(Callee)에게 연결을 제공한다
  • RTCPeerConnection.setLocalDescription : 로컬 전송 규격을 설정한다(파일 사이즈, 규격 등등)
    • => 이때 Description이 설정되면 Sinaling 서버를 통해 Description 정보를 보낸다 ( send signal : video-offer )
  • Signaling 서버를 통해 callee의 비디오가 설정되었다는 시그널이 온다 ( receive signal : video-answer )
    • => RTCPeerConnection.setRemoteDescription : Callee에서 어떤 규격을 통해서 연결되었는지 설정된다

ICE 프로토콜을 통해 생성된 SDP 정보가 수신된다 ( 이때 STUN 서버는 Caller와 Callee의 정보를 모두 가지고 있게된다 )

  • 이때쯤이면 ICE Protocol을 통해 Caller와 Callee의 연결 협상이 완료된다. 연결 정보가 수신되면 icecandidate 이벤트가 발생한다
  • SDP 정보를 Sinaling 서버를 통해 Callee에게 전달한다
    • send signal : new-ice-candidate
  • Callee의 SDP 정보가 수신된다 ( receive signal : new-ice-candidate )
    • RTCPeerConnection.addIceCandidate() : Caller-> Callee 연결이 생성된다

2-2. Callee의 소스순서
Caller와 Callee의 연결 협상을 한다

  • Sinaling 서버에 연결
  • RTCPeerConnection 생성 : 네트워크 연결 객체를 생성한다
  • Sinaling서버를 통해 SDP Offer를 수신한다 ( receive signal : video-offer )
    • RTCPeerConnection.setRemoteDescription : 수신된 정보를 이용해 RTCSessionDescription을 생성하고,
    • 이를 원격접속 설정한다
  • getUserMedia 를 통해 로컬 MediaSteam을 연다
  • RTCPeerConnection.addTrack : 로컬 비디오 스트림을 전송 네트워크에 연결시킨다
  • RTCPeerConnection.CreateAnswer : Caller에게 보낼 SDP 응답을 생성한다
    • 생성된 SDP 응답값을 Sinaling 서버를 통해 Caller에게 보낸다
    • signal : video-answer
  • RTCPeerConnection.setLocalDescription : 로컬 전송 정보를 설정한다
  • 로컬 정보 설정이 완료되면 Singnaling 서버를 통해 SDP 정보를 보낸다 ( send sigal : video-answer )

ICE 프로토콜을 통해 SDP 정보가 생성된다 ( 이때 STUN 서버는 Caller와 Callee의 정보를 모두 가지고 있게된다 )

  • Singaling 서버를 통해 receive signal : new-ice-candidate가 들어온다
    • 수신한 SDP 정보를 이용해 RTCIceCandidate 객체를 생성한다
  • RTCPeerConnection.addIceCandidate : Caller와의 연결을 생성한다
  • ICE Protocol을 통해 icecandidate 이벤트가 발생한다
    • candidate를 수신하고 signaling서버를 통해 send signal : new-ice-candidate 메시지를 보낸다

참조 : https://codelabs.developers.google.com/codelabs/webrtc-web/#0

2-3. 메시지에는 어떤 전송값이 들어가 있는가?
signal을 보면 video-offer, video-answer, new-ice-candidate가 있습니다.그럼 이 전송값들에는 어떤 정보가 들어가 있을까요?

  • video-offer, video-answer

got message {“token”:”#1″,”type”:”new_description”,”sdp”:{“type”:”offer”,”sdp”:”v=0\r\no=- 5767942783542651475 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\na=msid-semantic: WMS 9a701O3gl70nhZ5vrFMArHsJtse8UQo0QRzv\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111 103 9 0 8 105 13 110 113 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:dZzU\r\na=ice-pwd:xZ1T2cz0GUtVxXI9iw3dAMeN\r\na=ice-options:trickle\r\na=fingerprint:sha-256 81:B8:DC:AD:23:CB:8D:A8:C6:3E:88:35:3A:37:67:24:68:D4:14:3F:01:D7:2F:65:BA:8B:A0:EB:E1:8D:DB:DA\r\na=setup:actpass\r\na=mid:0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:3 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:5 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=sendrecv\r\na=msid:9a701O3gl70nhZ5vrFMArHsJtse8UQo0QRzv cd18e2da-575a-48b3-886b-abae43ce1cd1\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:103 ISAC/16000\r\na=rtpmap:9 G722/8000\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:105 CN/16000\r\na=rtpmap:13 CN/8000\r\na=rtpmap:110 telephone-event/48000\r\na=rtpmap:113 telephone-event/16000\r\na=rtpmap:126 telephone-event/8000\r\na=ssrc:1661837337 cname:8cwoDnki7oAqiYL1\r\na=ssrc:1661837337 msid:9a701O3gl70nhZ5vrFMArHsJtse8UQo0QRzv cd18e2da-575a-48b3-886b-abae43ce1cd1\r\na=ssrc:1661837337 mslabel:9a701O3gl70nhZ5vrFMArHsJtse8UQo0QRzv\r\na=ssrc:1661837337 label:cd18e2da-575a-48b3-886b-abae43ce1cd1\r\nm=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 127 104\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:dZzU\r\na=ice-pwd:xZ1T2cz0GUtVxXI9iw3dAMeN\r\na=ice-options:trickle\r\na=fingerprint:sha-256 81:B8:DC:AD:23:CB:8D:A8:C6:3E:88:35:3A:37:67:24:68:D4:14:3F:01:D7:2F:65:BA:8B:A0:EB:E1:8D:DB:DA\r\na=setup:actpass\r\na=mid:1\r\na=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:13 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:12 urn:3gpp:video-orientation\r\na=extmap:2 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:11http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\na=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\na=extmap:8http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07\r\na=extmap:9http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\na=extmap:3 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:5 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=sendrecv\r\na=msid:9a701O3gl70nhZ5vrFMArHsJtse8UQo0QRzv 504871a8-8ff7-49c4-8689-e7170808ca5f\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:96 VP8/90000\r\na=rtcp-fb:96 goog-remb\r\na=rtcp-fb:96 transport-cc\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtpmap:97 rtx/90000\r\na=fmtp:97 apt=96\r\na=rtpmap:98 VP9/90000\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-fb:98 transport-cc\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=fmtp:98 profile-id=0\r\na=rtpmap:99 rtx/90000\r\na=fmtp:99 apt=98\r\na=rtpmap:100 H264/90000\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 transport-cc\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:101 rtx/90000\r\na=fmtp:101 apt=100\r\na=rtpmap:102 red/90000\r\na=rtpmap:127 rtx/90000\r\na=fmtp:127 apt=102\r\na=rtpmap:104 ulpfec/90000\r\na=ssrc-group:FID 4276199393 4079328641\r\na=ssrc:4276199393 cname:8cwoDnki7oAqiYL1\r\na=ssrc:4276199393 msid:9a701O3gl70nhZ5vrFMArHsJtse8UQo0QRzv 504871a8-8ff7-49c4-8689-e7170808ca5f\r\na=ssrc:4276199393 mslabel:9a701O3gl70nhZ5vrFMArHsJtse8UQo0QRzv\r\na=ssrc:4276199393 label:504871a8-8ff7-49c4-8689-e7170808ca5f\r\na=ssrc:4079328641 cname:8cwoDnki7oAqiYL1\r\na=ssrc:4079328641 msid:9a701O3gl70nhZ5vrFMArHsJtse8UQo0QRzv 504871a8-8ff7-49c4-8689-e7170808ca5f\r\na=ssrc:4079328641 mslabel:9a701O3gl70nhZ5vrFMArHsJtse8UQo0QRzv\r\na=ssrc:4079328641 label:504871a8-8ff7-49c4-8689-e7170808ca5f\r\n”}}

  • new-ice-candidate

{“token”:”#1″,”type”:”new_ice_candidate”,”candidate”:{“candidate”:”candidate:2858526953 1 udp 2122260223 192.168.0.21 41568 typ host generation 0 ufrag dZzU network-id 1 network-cost 10″,”sdpMid”:”0″,”sdpMLineIndex”:0}}


위의 내용을 그림으로 정리하면 아래와 같습니다.참조 :  https://developer.mozilla.org/ko/docs/Web/API/WebRTC_API/Signaling_and_video_calling

2 comments

댓글 남기기

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.

%d 블로거가 이것을 좋아합니다: