미디어 스트림과 WebRTC
작년 부캠 그룹 프로젝트에서 우리 팀이 만든 프리뷰를 리팩토링해보기로 결정했다. 이번에는 안 해본 것들 위주로 개선해보려고 했다. 특히 멘토님이 조언해주신 네트워크 관련된 최적화에 도전해보고 싶다고 생각했다.
리팩토링하려고 도메인 지식에 대해서 리마인드해봤다. 6주라는 짧은 시간에 만들어야했기 때문에 도메인 지식에 대한 학습이 미흡했기도 했고, 이번에 제대로 공부해보는게 좋을 것 같아 다시 학습하기로 결정했다.
미디어 스트림
미디어 스트림은 오디오나 비디오 같은 미디어 데이터를 스트리밍하는 기술이다. WebRTC 관련 API 중 MediaStream API를 사용하여 구현할 수 있다.
하나의 미디어 스트림 객체에는 트랙이라는 것이 존재하는데, 오디오 트랙, 비디오 트랙 등이 있다.
미디어 스트림에는 하나의 입력과 하나의 출력을 가진다. getUserMedia() 같은 API로 가져온 사용자의 미디어 장치를 입력 출처로 사용하고,
WebRTC
WebRTC는 Web Realtime Communication이라는 뜻으로, 브라우저 간 오디오나 영상 미디어를 포착하고 스트림할 수 있게 해주는 기술이다. 꼭 미디어 데이터가 아니어도 임의의 데이터도 교환할 수 있다.
현재 프로젝트에 구현되어있는 기능 중 마이크 on&off시 다른 peer 들에게 알리는 기능이 있다. 이 기능은 데이터 채널을 사용해서 서로의 미디어 장치 상태를 교환하는 방식으로 구현되어있다.
특별한 드라이버나 플러그인 없이 웹 API만으로 피어 커넥션을 만들 수 있다는 점이 가장 큰 장점인 것 같다.
특정 두 명이 서로 화상 통화를 한다고 가정했을 때, 두 피어 간의 커넥션은 RTCPeerConnection 인터페이스를 통해 이루어진다. 피어 간에 커넥션이 수립이 되면 해당 커넥션에 미디어 스트림 객체를 연결하여 서로 미디어를 전송하고 받을 수 있다.
WebRTC 중 개인적으로 어렵다고 느낀 부분은 커넥션 수립 과정이었다. offer, answer, sdp 등 다소 생소한 개념들이 많이 나오기 때문이다.
간단하게 설명하면 offer는 연결을 제안하는 과정, answer는 제안을 수락할지 말지에 대한 것, sdp는 서로의 연결 과정에서 필요한 데이터 (코덱 정보, 화질 등)이다.
연결 과정
WebRTC는 피어 간 직접 통신을 위한 기술이지만, 초기 연결을 위해 서로를 찾는 메커니즘은 포함되어 있지 않다. (전화번호를 알아야 전화를 할 수 있는 것처럼) 그래서 서로를 찾을 수 있도록 해주는 몇가지 도구들이 있다.
- 시그널링 서버
- 피어들이 SDP와 ICE 후보를 교환할 수 있도록 해주는 중간 매개체 역할
- STUN 서버
- NAT 뒤에 있는 진짜 IP 주소를 확인해주는 목적
- TURN 서버
- 직접 연결이 불가능한 경우, 방화벽이 있을 경우 중개 서버 역할
이런 도구들을 사용해서 연결하는 과정은 다음과 같다.
- 서로는 시그널링 서버를 통해 서로를 식별한다.
- 서로 연결하고자 한다면, 시그널링 서버를 중개해 offer를 보내고, answer를 진행하며 서로 sdp를 교환한다.
- ice candidate를 진행한다. ice는 네트워크 상에서 서로 연결하기 위한 최적의 경로를 찾기 위한 프레임워크이다.
- 최적의 연결 경로를 발견하면, 서로 peerConnection이 수립된다.
- 커넥션 수립 이후부터는 미디어 스트림이나 임의의 데이터를 중간자 없이 송수신할 수 있게 된다.
