WebRTC 란
WebRTC(Web Real-Time Communication)은 웹 애플리케이션과 사이트가 중간자 없이 브라우저 간에 오디오나 영상 미디어를 포착하고 마음대로 스트림할 뿐 아니라, 임의의 데이터도 교환할 수 있도록 하는 기술입니다. WebRTC를 구성하는 일련의 표준들은 플러그인이나 제 3자 소프트웨어 설치 없이 종단 간 데이터 공유와 화상 회의를 가능하게 합니다.
이를 위하여 WebRTC는 상호 연관된 API와 프로토콜로 구성되어 함께 작동합니다. 이 문서에서는 WebRTC의 기본을 이해하고, 설정하며, 데이터와 미디어 연결을 위해 사용할 수 있게 도와줄 것입니다.
WebRTC를 사용하는 이유
Zoom sdk, Jitsi 오픈소스들은 방대하고 문서화도 잘 되어있습니다. 하지만 초보자가 사용하기에는 무거운 소스라는 생각이 들었습니다. 저의 목적은 줌 같은 애플리케이션을 제작하여 서비스하는 것이 목적이 아니라 얼굴, 음성 데이터를 활용하는 것이 목적입니다. 그래서, 소켓 프로그래밍 같은 네트워크를 고려하지 않더라도 쉽게 온라인 화상 환경을 구축할 필요가 있었고 이 WebRTC를 접하게 되었습니다.
기술이해
미디어 장치를 읽어 들일 수 있어야 합니다.
navigator.mediaDevices 객체에 있는
getUsesMedia()
또는enemerateDevices()
를 호출합니다.미디어 장치의 비디오 및 오디오를 캡처한다.
getDisplayMedia()
로 화면을 표시하려는 곳을 엽니다. (예: 애플리케이션, 브라우저, 모니터, 윈도우 창)MediaStream.getTracks()
를 호출하여 비디오 및 오디오의 모든 트랙을 검색 할 수 있습니다.피어 간 연결하기
피어는 클라이언트를 의미합니다. 그리고 각 피어는 모두 ICE 서버를 지원해야 합니다. 각 피어간의 연결하기 위한 작업을 시그널링으로 정의합니다.
RTCPeerConnection 객체로 시그널링을 처리합니다.
송신 측: RTCPeerConnection 객체 생성 ->
createOffer()
호출 ->setLocalDescription()
으로 세션에 대한 설명을 생성할 수 있음.수신 측: RTCPeerConnection 객체 생성 전
setRemoteDescription()
로 수신 된 오퍼를 설정합니다. 그 후,createAnswer()
로 수신 된 오퍼에 대한 답변을 작성합니다. 위와 마찬가지로setLocalDescription()
으로 작성합니다.이렇게 송,수신측 각각
setRemoteDescription()
과setLocalDescription()
으로 서로 각 피어의 기능을 알게 된 것입니다. 이제 ICE후보를 수집하여 다른 피어로 전송합니다. 이 부분은 간단하게 이벤트리스너를 추가하는 방식으로 구현 가능합니다.peerConnection.addEventListener('icecandidate', event => {...})
그 후, 시그널링채널을 통해 본인 피어의 ICE 후보를 원격 피어로 전송합니다.
signalingChannel.send({'new-ice-candidate': event.candidate})
보내는 것 뿐아니라, 상대 피어의 ICE 후보를 받아야 합니다. 이를 위해선iceCandidate 메세지를 비동기로 받아서
peerConnection.addIceCandidate(message.iceCandidate)
로 등록해줍니다.각 ICE 후보가 접수 되면 피어의 연결 상태가 변경됩니다. 이는
connectionstatechange
이벤트를 수신하여 감지합니다.
정리
오늘은 WebRTC를 사용하는 이유와 간략히 어떤 방식으로 P2P를 구현할 수 있는지 살펴 봤습니다. 이를 잘 활용하면 비디오, 음성데이터를 추출하여 aws S3에 전송하거나, 다중 화상 미팅을 구현 할 수 있습니다. 다음에는 이론적인 설명말고 실질적인 코드로 포스팅을 해보겠습니다.