WebRTC

WebRTC Wikipedia

  • WebRTC ( Web Real-Time Communication )는 애플리케이션 프로그래밍 인터페이스 (API) 를 통해 웹 브라우저 및 모바일 애플리케이션 에 실시간 통신 (RTC)을 제공하는 무료 오픈 소스 프로젝트입니다. 플러그인을 설치 하거나 기본 앱을 다운로드할 필요 없이 직접 P2P 통신을 허용하여 오디오 및 비디오 통신이 웹 페이지 내에서 작동하도록 합니다.
  • WebRTC 이정표에는 최초의 브라우저 간 화상 통화(2013년 2월), 최초의 브라우저 간 데이터 전송(2014년 2월)이 포함되며 2014년 7월 현재 Google 행아웃은 WebRTC를 사용하는 "종류"였습니다

Google I/O 2013 Presentation

  • And one of the reasons is that WebRTC fills a critical gap in the web platform, where previously, a native proprietary app like Skype could do something the web just couldn't. But now we've turned that around and changed that so we have a web of connected WebRTC devices that can communicate in realtime just by loading a web page

위 내용들을 통해 WebRTC 는 이전에 웹에서 하기 어려웠던 브라우저 간 통신을 구현하고 이를 API로 제공해 주었다는 걸 알 수 있습니다. 덕분에 브라우저를 통해 미디어를 제공하는 기능을 개발하기 쉽게 되었고 다양한 미디어 서비스가 등장할 수 있었던 것 같아요.

Pion을 사용하게 된 계기

위에서 보았듯이 WebRTC는 브라우저간 통신이 주요 기능입니다. 따라서 공식홈페이지 를 가보면 주로 브라우저간 통신 위주로 javascript를 예시로 들며 문서가 쓰여졌다는 것을 알 수 있어요. 그런데 우리는 구현하고자 하는 것이 달랐습니다. 우리는 Windows, Mac, Android, iOS 기기의 화면을 브라우저에서 보여주고자 했습니다. 그리고 이 화면전송은 해당 플랫폼의 브라우저에서 시작되는 것이 아니라 내부 프로그램을 통해 시작되기를 희망했습니다. 즉 브라우저와 브라우저가 아닌 브라우저와 응용프로그램 간에 통신을 구현해야 했습니다.

그러면 이걸 어떻게 구현해야할까요? 원하는 응용프로그램을 개발하고 내부에 WebRTC 라이브러리를 넣어야했습니다. WebRTC의 소스코드는 libwebrtc 로 구글에서 개발하고 있습니다. 이 라이브러리는 c++ 로 구현되어있어서 호출하려면 해당 c++ API를 호출해야 했어요. 그렇다면 응용프로그램도 c++로 개발해야했어요. (물론 Language interoperability를 제공하는 언어들도 있었지만, 쉽지 않을 길이라 생각했습니다. ) 응용프로그램을 c++로 만든다는 것은 개발에 시간이 오래걸리고 추후 유지보수가 쉽지 않을 것으로 판단했거든요.

그런데 WebRTC는 프로토콜일 뿐인데, 이걸 다른 언어로 구현한 건 없을까? 생각하며 검색을 이어 나가던 중 pion/webrtc을 발견했습니다. 순수 go로 구현된 WebRTC이고 이해하기 쉬운 Guide를 제공하고 유연한 API를 제공해요. Pion을 사용했을 때 다른 경로를 통해서 획득한 codec의 스트림을 전송하기도 용이했습니다. 그리고 pion/webrtc/examples/rtp-to-webrtc 예제는 처음 시작하며 이해하기도 좋았습니다. 또 pion개발자를 인터뷰한 내용이 있는데요. 개발자가 겪은 이 여정도 저를 설득하기에 충분했습니다.

화면 전송

Pion을 사용한다고 해도 내가 원하는 대상과 P2P연결 맺기, 연결을 맺은 후 화면을 브라우저에 알맞은 타임스탬프로 보내고 보여주는 과정은 쉽지 않았습니다. 이 과정에서 WebRTCforTheCurious.com 의 도움을 많이 받았습니다. 다른 곳에서는 깊게 설명하지 않는 내용을 자세히 정리해 놓아서 연결부터 Media, Data전송이 어떻게 이루어지는지 알 수 있었어요. 아래가 일부 내용을 가져온 것인데요. 이 내용을 읽고 저는 WebRTC사용하는데 어려움을 겪는게 당연하다는걸 느낄 수 있었습니다

💡
WebRTC 프로토콜은 다른 기술의 모음입니다.
WebRTC 프로토콜은 설명하는 데 책 전체가 필요한 엄청난 주제입니다. 그러나 시작하기 위해 이를 네 단계로 나눕니다.
1. 시그널링
2. 연결 중
3. 확보
4. 의사 소통
이러한 단계는 순차적이므로 후속 단계가 시작되려면 이전 단계가 100% 성공해야 합니다.

go 응용프로그램에서 사용한 Pion video 전송 코드는 아래와 같습니다.

아래와 같이 RTP(Real-time Transport Protocol)를 전송해주는 videoTrack을 만들고

peer.videoTrack, err = webrtc.NewTrackLocalStaticRTP(webrtc.RTPCodecCapability{
		MimeType:  webrtc.MimeTypeVP8,
		ClockRate: 90000,
}, "video", "pion")

각각의 플랫폼에서 VP8, H.264등으로 인코딩 된 화면 버퍼가 넘어온다면, 이 버퍼를 packetizer에게 넘겨주어 RTPPacket을 생성하고, videoTrack에 RTPPacket을 전송하여 브라우저에게 화면 버퍼를 전송했습니다. 이렇게 video Transceiver를 등록한 브라우저에게 화면을 전송할 수 있었습니다.
RTP(실시간 전송 프로토콜)는 미디어를 전달하는 프로토콜입니다. 동영상을 실시간으로 전달할 수 있도록 설계되었습니다. 자세한 내용은 WebRTCforTheCurious.com 를 참고하면 패킷의 포맷과 각 필드들이 어떤 역할을 하는지 알 수 있습니다. 해당 헤더의 필드들이 Pion rtc.Packet 에도 정의되어있으므로 비교해보시면 좀 더 쉽게 이해할 수 있습니다.

func (s *Streamer) OnSurface(timeStamp uint32, data []byte) {
	packets := s.packetizer.Packetize(data, 0)

	for _, p := range packets {
		p.Timestamp = timeStamp
		if err := s.mediaPeer.videoTrack.WriteRTP(p); err != nil {
			log.Inst.Error("streamer.OnSurface failed to write RTP", zap.Error(err))
			return
		}
	}
}

데이터 전송

화면전송 이외에도 브라우저와 응용프로그램 사이에 특정한 정보들을 주고받고 싶었습니다. 이럴 때 WebRTC DataChannel 을 사용했습니다. DataChannel을 통해 주고받는 메시지는 Datagram Transport Layer Security (DTLS)를 통해 암호화되는데요. 이런 부분들도 pion이 잘 처리해주어 데이터 전송에서는 어려움이 없었습니다.

아래는 브라우저에서 createDataChannel() 을 통해 dataChannel 생성을 요청했을 때 pion이 적용된 응용프로그램에서 처리하는 로직의 예시인데요.

peerConnection에 onDataChannel 콜백을 등록해서 메시지를 출력하거나 byte[] 전송하였습니다.

peerConnection.OnDataChannel(func(d *webrtc.DataChannel) {
	// Register text message handling
	d.OnMessage(func(msg webrtc.DataChannelMessage) {
		fmt.Printf("Message from DataChannel '%s': '%s'\n", d.Label(), string(msg.Data))
        d.Send([]byte("Hello"))
	})
})

이상 Pion을 통한 WebRTC에 대해 살펴보았는데요. WebRTC는 브라우저와 P2P 통신채널을 생성하고 화면과 임의의 데이터를 전송할 수 있는 API를 제공해 주었습니다. 이 때 브라우저와 브라우저간이 아닌 브라우저와 응용프로그램 사이에 통신을 하기 위해 Pion을 사용하였고 구현 과정에서 프로토콜에 대한 이해부족으로 어려움들이 있었는데요. WebRTCforTheCurious.com 의 도움으로 프토토콜에 대한 이해를 하여 성공적으로 구현할 수 있었습니다.

WebRTC 기술을 통해서 Dogu는 조직 내의 기기를 원격에서 제어할 수 있는 기능을 만들었습니다. 또한 기기를 분류하여 특정 기기에 원하는 테스트 스크립트를 실행하는 Batch Test기능도 개발했습니다. WebRTC로 구현된 Android, iOS, Windows, macOS 원격제어 및 관리에 대해 궁금하시다면 https://dogutech.io/ 를 한 번 방문해보세요.