WebRTC는 개인간 연결(Peer to Peer)을 기본으로 하기 때문에

실행되는 단말기(PC, 휴대폰등)가 공인 IP를 가지거나 같은 네트워크(공유기) 안에서 서로 인식 할 수 있어야 한다.

하나는 공유기 안에 있고, 다른 하나는 공유기 밖에 있다면 통신을 할 수 없다.

즉, 앞서서 정리한 화상채팅용 WebRTC 예제는 같은 공유기 내에서만 실행된다.

 

이 경우 각 단말기는 공인 IP를 가진 서버(Server)를 경유해서 통신해야 하고,

coturn서버는 WebRTC가 이렇게 통신할 수 있도록 중계 서버 역할을 해주는 오픈 소스 프로그램이다.

(이런 서버를 Turn 서버라고 한다. Turn / Stun의 개념은 인터넷으로 쉽게 찾을 수 있다.)

 

coturn 서버의 설치 절차는 간단하고 쉽지만 (설치 자료를 쉽게 찾을 수 있다),

리눅스에서만 사용할 수 있고,

외부에서 접근하기 위해 공인 IP를 가진 서버에 설치해야 하기 때문에 공유기를 사용하는 환경(집)에서는 한계가 있다. 

 

따라서, 여기에서는 coturn 설치 절차나 사용 방법을 정리하지 않고,

다음과 같이 공유기(집)를 사용하는 환경에서 coturn 서버를 설치해서 운영하기 위해 필요한 것들을(링크자료) 간단하게 정리한다.

  1. WSL 설치: Linux 설치를 위해
  2. 공유기 사용시 포트포워딩: 공인 IP 사용
  3. coturn 설치 후 테스트
  4. 예제와 연동

공인 IP를 가진 리눅스 서버가 있는 경우 1번과 2번은 넘어가도 무방하다.

 

1. WSL 설치

coturn을 사용하기 위해서는 리눅스가 필요한데,

Windows 10 에서는 WSL(Windows Subsystem for Linux)로 쉽게 설치해서 사용할 수 있다.

도커(Docker), VirtualBox 같은 가상화 소프트웨어를 사용해도 좋지만,

개인적인 호기심과 저사양 노트북을 쓰는 관계로 WSL을 사용해서 coturn 서버를 구축했다.

WSL의 설치는 여기에서 제공하는 내용을 따라서 진행하면 된다.

Ubuntu 설치시 로그인을 요청하는데, 계정이 없다면 로그인 창을 그냥 닫아도 설치된다.

이 내용의 하단에 있는 도커는 설치 하지 않아도 되고, WSL로 우분투(UBUNTU)를 설치한다.

 

WSL의 단점은 WSL로 설치한 운영체제의 IP가 재부팅 할 때 마다 변경된다는 것이다.

이 문제는 이 글에서 정리한 스크립트를 실행해서 해결한다.

 

WSL로 우분투를 설치한 경우 텔넷(telnet)이 기본으로 설치되어 있지 않다.

개인적으로 윈도우즈 콘솔(cmd, Terminal) 화면을 좋아하지 않아서, WSL등으로 리눅스를 실행하고 텔넷으로 접속해서 사용하는 것을 선호한다.

이경우 SSH등을 지원하게 설치해서(apt install openssh-server) 사용하는 것이 좋다.


2. 공유기 사용시 포트포워딩

다음으로, 외부에서 WSL로 설치한 리눅스에 접속할 수 있도록 지정해야 한다.

[공유기 포트포워딩] 인터넷을 검색해보면 쉽게 자료를 구할 수 있다.

사용하는 공유기에 따라 설정이 다르기 때문에 제조사를 포함해서 검색하면 변경 방법을 찾을 수 있다.

 

Coturn 서버외에 화상 채팅을 사용하려는 사용자들이 접속해서 채팅을 시작할 수 있도록 도와주는 웹 서버도 외부에서 접속해야 한다.

이 웹 서버(WerbRTC 예제 참조)도 같이 리눅스 서버에서 실행시키고 외부에서 접근할 수 있게 한다.

그리고 다음과 같이 웹 서버에서 사용하는 3000과 443 포트를 지정하고,

Coturn 서버에서 사용하는 3478과 5349 포트를 지정해 준다.

다음 리스트에서 포트 외에 지정된 [내부 IP 주소]는 WSL이 실행된 노트북(PC)의 내부 IP이다.


포트 포워딩이 잘 되었는지 확인하려면, NodeJS로 만든 WebRTC 예제를 다운 받아서 리눅스에 설치한다.

NodeJS를 설치하고 WebRTC 예제를 복사해서 실행하면 된다.

이 예제를 내부 IP가 아닌 공인 IP로 접속할 수 있으면 포트 포워딩이 잘 이루어진 것이다.

coturn 서버를 설치하고 잘 실행되는지 확인하려면 WebRTC 예제가 있어야 한다.

 

자신의 외부(공인) IP는 다음과 같이 포털에서 ip로 검색하면 된다.

 

3. coturn 설치 후 테스트

 

Coturn 설치는 인터넷 자료가 많으니 검색해 보거나, 다음 자료를 참고하면 된다.

          buttercoconut.xyz/247/

          meetrix.io/blog/webrtc/coturn/installation.html

          www.omegaduck.com/2019/08/12/sturn-turn-%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%84%B1/

설치시 완성된 서비스를 제공하는 것이 아니기 때문에 SSL(TLS)을 설치하지 않아도 되고,

도메인도 사용할 필요 없이 공인 IP만 지정해서 사용한다.


Coturn 설치 후 설치가 잘 되었는지, turnutils_uclient 를 이용하여 다음과 같이 확인한다.

     turnutils_uclient -t -u 계정 -w 비밀번호 공인IP

공인 IP 대신에 내부 IP를 지정해서, coturn 서버는 잘 설치되었는데, 포트 포워딩이나 방화벽 문제로 외부에서 접속이 안되는지 확인하는 하는 용도로도 사용할 수 있다.

또는 ICE 사이트에서 다음 그림과 같이 확인 할 수 있다.

설치한 coturn 서버 정보를 입력한 후에 [Gather candidates]를 누르면, 설치가 제대로 된 경우 그림과 비슷한 결과를 얻을 수 있다.

위 그림과 다른 결과가 나온다면 coturn 설정이나 방화벽 설정 등을 다시 확인해야 한다.

 

4. 예제와 연동

앞서 정리한 WebRTC 예제를 설치하고

설치한 Turn 서버 정보를 입력기 위해, main.js 파일에서 다음과 같이 수정한다.


var pcConfig = {
  'iceServers': [
          {"urls":["turn:공인IP:3478?transport=tcp"],"username":"계정","credential":"비밀번호"}
  ]
};


function createPeerConnection() {
  try {
    pc = new RTCPeerConnection(pcConfig);
~ 생략 ~~
}

설치한 coturn 서버의 정보를 pcConfig 변수에 지정하고, 이 pcConfig를 WebRTC를 실행할때(new RTCPeerConnection) 지정한다.

 

이 WebRTC 예제는 구글 예제를 기반으로 작성한 것으로, 구글의 WebRTC 설명용으로 작성된 코드로 짐작되지만 사용하지 않는 코드가 있다.

예로 main.js 파일에서 requestTurn로 검색되는 코드는 사용하지 않는 코드로 Turn 서버 접속에 문제를 만들 수 있다.

코드를 확인해서 삭제하는 것이 좋다.

 

이제 하나는 공유기 안에서 WebRTC 서버에 접속하고, 하나는 휴대폰으로(둘다 휴대폰) 접속해서 화상 통화가 잘 실행되는지 확인한다.

 

 

WebRTC는 구글에서 공유한 웹 기반 커뮤니케이션 라이브러리로, 별도의 설치 없이 웹 브라우저에서 화상채팅을 할 수 있는 기능을 제공한다.

WebRTC는 화상채팅, 음성채팅 등을 쉽게 제작할 수 있도록 도와주며,몇 번의 검색만으로 다음과 같이 다양한 설명과 예제 소스를 구할 수 있다.

      WebRTC 개념 및 각종 개념 설명

      화상채팅 예제

      WebRTC 각종 예제

대부분이 개념 설명과 코드 사용법을 중심으로 설명했는데,

여기에서는 개념 설명 없이 구글에서 제공하는 예제에 여러 가지 기능을 추가하는 방식으로 정리한다.

WebRTC는 제법 어려운(낯선) 내용들이 많고,

NodeJS, SSL, Soeket.IO, HTML, CSS 등의 부가적인 것에 대해서도 알아야 한다.

여기에서 간단하게 예제를 구현해 보면서 WebRTC 개발에 대한 재미를 느낀 뒤에,

본격적으로 관련된 깊이 있는 내용들을 찾아보면 좋을 것이다.

하지만, 최소한의 기본 개념은 있어야 하니,

WebRTC 개념 및 각종 개념에 대한 설명은 한번 쯤 읽어보고 다음 내용을 따라 하는 것이 좋다.

 

  1. 화상 채팅 예제로 익히는 WebRTC - 기본 예제
  2. 화상 채팅 예제로 익히는 WebRTC - 기능 추가
  3. WebRTC 외부에서 사용하기 – coturn

 

구글의 WebRTC 예제는 다음과 같이 기초부터 하나씩 기능을 추가하여 6가지 단계로 구성되어 있다.

  • 1단계는 카메라에서 비디오를 추출하는 예제,
  • 2단계는 RTCPeerConnection을 이용하여 대화상대에게 비디오를 제공하는 예제 (네트워크없이)
  • 3단계는 RTCDataChannel을 이용하여 데이터를 주고 받는 예제
  • 4단계는 서버를 이용하여 메시지를 주고 받는 예제 (signaling)
  • 5단계는 네트워크 상에서 비디오를 주고 받는 예제
  • 6단계는 이미지(데이터)를 공유(제공)하는 예제 이다.

1~3 단계는 네트워크로 상대와 연결하는 것 없이 혼자 실행하는 것으로

다운로드 받은 파일을 탐색기에서 실행해서(웹 브라우저로) 확인할 수 있다.

해당 예제의 설명서에는 크롬(Chrome)의 플러그인인 Web Server를 설치해서 사용하는 방법을 설명하는데,

1~3 단계는 그냥 파일로 실행하며 관련 코드를 확인하고 인터넷으로 해당 설명을 찾아보는 것으로 충분할  것 같다.

4~6단계는 네트워크를 기반으로 하는 예제이기 때문에 NodeJS를 설치해서 웹으로 실행해야 한다.

 

3단계와 6단계는 데이터를 주고 받는 RTCDataChannel에 대한 것으로, 

처음 시작하는 사람에게는 RTCPeerConnection 만으로도 충분이 어렵기 때문에 여기서는 정리하지 않는다.

2단계에서 사용된 RTCPeerConnection은 Peer라는 단어에서 알 수 있겠지만

대화 상대 둘이서 직접 연결해서 대화에 필요한 이미지를 주고 받도록 하는 클래스로

WebRTC로 화상채팅을 구현하기 위해서 꼭 알아야 하는 클래스이다.

 

정리하면,

카메라에서 비디오를 추출하고(getUserMedia - 1단계), 

대화 상대를 찾아서 (signaling - 4단계)

네트워크로 연결하여 (RTCPeerConnection - 2단계)

비디오를 주고 받는 예제로 위 단계를 종합한 예제가 5단계의 예제이다.

즉, 5단계의 예제를 실행하면,

두 대의 장치에서 이미지를 주고 받으며 화상채팅이 되는 것을 볼 수 있다.

따라서, 여기에서는 이 5단계의 예제에 기능을 추가하는 방식을 정리한다.


주의: 예제는 크롬 브라우저에서만 작동한다. 

IE, Edge(이전 버전, 최신 edge는 크롬기반으로 작동한다)를 제외하고는 WebRTC를 지원하지만, 

예제는 크롬에서만 작동한다. 다른 웹 브라우저에서 실행하려면 별도의 처리가 필요하다.

 

이 외에도 구글의 예제는 몇 가지 부족한 것 들이 있다.

먼저 WebRTC는 기본적으로 네트워크 연결시 SSL이 있어야 한다.

localhost로 간단하게 비디오 화면을 가져오는 것 외에,

네트워크로 연결해서 데이터를 주고 받으며 화상 채팅을 하려면 SSL이 있어야 한다.

 

두 번째, 대화 상대를 찾기 위해 사용하는 서버가 한번만 연결 하도록 작성되어서,

한번 채팅을 하고 나면 계속 서버를 재가동해야 한다.

프로그램을 조금이라도 수정하고 확인하려면 계속 서버를 재가동해야 한다.

 

마지막으로, 해당 예제는 이미지만 주고 받는 화상채팅으로 오디오는 제공되지 않는다.

 

이상의 3가지 기능을 보강하는 방법은 코드 몇 줄만 추가하면 되는 것으로

이렇게 기능을 보강하다 보면 WebRTC 예제(코드)와 친해지고 개발 능력을 향상 시킬 수 있을 것이다.

 

본격적으로 이상의 부족한 부분을 보강을 하기 전에,

구글 예제 중 5단계 예제부터 실행 한다.

 

먼저 Github에서 소스를 다운 받아서 적절한 디렉토리에 설치한다.

git 명령어로 설치하거나 [Download ZIP]을 선택해서 압축 파일을 받아서 설치한다.

주의: 서버가 NodeJS로 구축되어 있기 때문에 NodeJS를 설치한다.

NodeJS는 홈페이지에서 자신의 운영체제에 맞추어 다운로드 받아서 실행하면 된다.

 

콘솔창(CMD)에서 예제 5(step-05)가 있는 디렉토리로 이동해서 파일을 확인하고

npm i (install) 명령어로 예제 실행에 필요한 라이브러리들을 설치한다.

실행이 끝나면 탐색기에서 node_modules 폴더에 라이브러리들이 설치된 것을 확인할 수 있다.

 

콘솔창에서 node index.js 을 실행해서 웹 서버를 실행한다.

아무런 메시지도 없이 다음과 같이 커서가 깜박이면 제대로 실행된 것이다.

 

크롬을 실행해서 주소창에 http://localhost:8080을 입력한다.

다음 그림과 같이 카메라 사용 권한 요청화면에서 [허용]을 선택한다.

 

그림과 같이 자신의 모습이(?) 웹 브라우저에 나타나는 것을 볼 수 있다. 

하지만 다음과 같이 다른 컴퓨터나 휴대폰으로 접속하면, 화면이 나타나지 않는다.

    http://서버 IP:8080

참고: 서버 IP는 NodeJS를 실행한 컴퓨터의 콘솔창에서 ipconfig or ifconfig를 입력하면 확인할 수 있다.

 

localhost가 아닌 IP를 사용하는 경우에는 자신의 컴퓨터에서도 화면이 나타나지 않는다.

카메라에서 이미지를 못가지고 오는 것으로, SSL을 통하지 않으면 카메라(WebRTC)를 이용할 수 없다.

이제, 이러한 문제들을 해결하고, 기능을 추가하는 방법에 대해서 정리한다 (다음 페이지).

 

참고사항: step-05 폴더에 있는 5 단계 예제의 주요 파일은 다음과 같다.

다음 파일들을 모두 수정하니, 어떤 파일인지, 어떤 코드가 있는지 알고 있어야 한다.

  • index.js - NodeJS로 실행한 웹 서버 및 Signaling
  • index.html - 사용자가 웹으로 접근했을때, 보여주는 웹페이지. 화상채팅 화면.
    • js/main.js - index.html 파일에는 간단한 html 태그만 있고, RTCPeerConnection과 같은 실제 화상채팅을 하는 클라이언트 코드가 모두 여기 있다.
    • css/main.css - index.html 에서 사용할 디자인 내용이 작성되어 있다.

 

 

 

  1. 화상 채팅 예제로 익히는 WebRTC - 기본 예제
  2. 화상 채팅 예제로 익히는 WebRTC - 기능 추가
  3. WebRTC 외부에서 사용하기 – coturn

 

여기에서는 앞서 정리한 구글 WebRTC 예제에 다음 4가지 사항을 추가한다.

  1. SSL 적용
  2. 서버 기능 보강
  3. 오디오 추가
  4. 조금 나은 디자인

기존 예제에 추가된 소스는 GitHub에서 받을 수 있다.

 

먼저, NodeJS에 SSL을 적용하기 위해, SSL을 생성한다.

SSL은 HTTP를 암호화 해서 사용하기 위한 것으로 자세한 것은 찾아보길 바라고,

제대로 된 SSL은 유료로 구매해야 하지만

여기서는 개발을 위해 제공되는 OpenSSL로 간단하게 만들어서 사용한다.

OpenSSL을 설치하는 방법은 여기에서 정리하지 않으니 찾아보고 설치한다.



OpenSSL로 개인키(private.pem) 파일을 생성한다.

         openssl genrsa 1024 > private.pem

그리고, 개인키와 쌍이 되는 공개키를(public.pem) 다음과 같이 생성한다.

         openssl req -x509 -new -key private.pem > public.pem

탐색기로 개인키(private.pem)와 공개키(public.pem) 파일이 생성된 것을 확인 할 수 있다.

 

공개키를 생성하면, 국가, 도시 등의 여러 가지 값을 입력하라고 한다.

개발용 SSL이니 아무 값이나 입력하면 된다.

 참고: 여기서는 간단하게 키만 생성해서 사용하고, 제대로된 사설 인증서를 만드는 방법은 검색해서 익혀두면 유용하다.

 

생성한 인증서 파일을 구글 예제 폴더에 복사한다.

index.js 파일과 같은 폴더에 복사하고, index.js 파일을 적당한 편집기로 수정한다.

index.js는 다음과 같이 8080 포트의 http로 접속하도록 작성되어 있다.

var http = require('http');
var socketIO = require('socket.io');

var fileServer = new(nodeStatic.Server)();
var app = http.createServer(function(req, res) {
  fileServer.serve(req, res);
}).listen(8080);

이 내용을 다음과 같이 앞서 생성한 키 파일을 이용해서 https, 3000포트로 접속하도록 수정한다.

//var http = require('http');
var socketIO = require('socket.io');

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('./private.pem'),
  cert: fs.readFileSync('./public.pem')
};

var fileServer = new(nodeStatic.Server)();
let app = https.createServer(options, (req,res)=>{
  fileServer.serve(req, res);
}).listen(3000);

console.log('Started chating server...');

기존에는 http://127.0.0.1:8080으로 접속했고,

이제는 https://127.0.0.1:3000으로 접속하면 된다.

그리고, "Started chating server..." 문장을 출력해서 서버가 가동된 사실을 알 수 있도록 한다.

주의: 실제로는 127.0.0.1로 접속하지 않고, 서버(PC)에 할당된 사설 IP(예: 192.168.35.154)나 공인 IP로 접속한다.

 

콘솔창에서 node index.js를 입력해서 실행하면, 다음과 같이 서버가 실행된 것을 알 수 있다.

PC나 휴대폰의 크롬 브라우저로 https://서버IP:3000으로 접속하면 다음과 같은 경고창이 실행된다.

정상 SSL이 아니라는 의미로, 웹 페이지 하단의 [고급] 버튼을 선택한다.

다음 페이지에서 "192.168.35.154(안전하지 않음)(으)로 이동"을 선택해서 서버 접속을 계속한다.

다음과 같이 PC와 휴대폰으로 접속하면, 비디오(만) 화상채팅이 실행된다.

 

두 번째 예제 보강 작업으로 서버 기능을 보강한다.

구글 예제에서 socket.io를 이용해 구현한 네트워크 연결 부분은 아주 기초적이고 단순한 구조로

두 대의 클라이언트에서 실행된 WebRTC가 서로 RTCPeerConnection로 연결할 수 있도록 도와 주는 역할을 한다(signaling).

 

현재의 예제는 채팅을 종료(웹브라우저를 닫거나 갱신-F5)하면 다시 채팅을 할 수 없다.

서버를 재가동하고 다시 접속해야만 한다.

주의: 서버 파일(index.js) 대부분과 클라이언트(main.js)의 네트워크 연결 관련 부분의 코드는 모두 socket.io로 작성되었다. socket.io에 대해서 잘 모른다면 socketio nodejs로 검색해서 관련 자료를 읽어보는 것이 좋다.

socketio nodejs 채팅방으로 검색 결과의 예제와 여기서 사용된 예제가 비슷한 것이 많으니 관련 내용을 읽어보고 구글 예제를 보강해 보는 것도 좋다.

 

다음 코드는 클라이언트의 각종 message를 받아서 전달(broadcast)하는 기존 코드(회색)에

message가 bye이면 채팅방(foo)을 비우는(leave) 코드를 추가한 것이다.

즉, 화상 채팅 중에 한 사람이라도 채팅방을 나가면(bye) 채팅방을 비우도록 한 것이다.

  socket.on('message', function(message) {
    log('Client said: ', message);
    
    if (message==="bye" && socket.rooms['foo']) {
        io.of('/').in('foo').clients((error, socketIds) => {
            if (error) throw error;

            socketIds.forEach(socketId => {
                io.sockets.sockets[socketId].leave('foo');
            });
        });
    }
    socket.broadcast.emit('message', message);
  });

다음 코드에서 확인 할 수 있지만,

다시 빈 채팅방에 입장한 순서로 연결해서 화상 채팅을 하게 된다.

참고: bye라는 메시지는 클라이언트(main.js 파일)에서 웹 브라우저를 닫거나 해당 채팅 웹 페이지를 떠날 때(onbeforeunload 이벤트시) 채팅 종료를 알리도록 작성된 메시지이다.

채팅방 이름인 foo는 클라이언트에 변수명으로 고정되어 있다 (구글 예제에서 그렇게 작성) .

제대로 된 채팅 프로그램이면 채팅방 이름이 bye란 메시지와 같이 전송되게 했을 것이다.

추가로 구현하면 예제를 이해하는데 도움이 될 것이다.

 

추가적으로 create or join 메시지의 기존 코드에 다음과 같이(빨간색),

첫 사용자가 입장하면 채팅방을 생성한다는 의미로 created,

두번째 사용자가 입장했다는 의미로 joined를 콘솔창에 출력하도록 한다.

  socket.on('create or join', function(room) {
    log('Received request to create or join room ' + room);

    var clientsInRoom = io.sockets.adapter.rooms[room];
    var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
    log('Room ' + room + ' now has ' + numClients + ' client(s)');

    if (numClients === 0) {
      socket.join(room);
      log('Client ID ' + socket.id + ' created room ' + room);
      socket.emit('created', room, socket.id);
      console.log('created');
    } else if (numClients === 1) {
      log('Client ID ' + socket.id + ' joined room ' + room);
      io.sockets.in(room).emit('join', room);
      socket.join(room);
      socket.emit('joined', room, socket.id);
      io.sockets.in(room).emit('ready');
      console.log('joined');
    } else { // max two clients
      socket.emit('full', room);
    }
  });

위 코드는 이해를 하고 있는 것이 좋을 것 같아서 간단하게 정리한다.

create or join 메시지시 파라미터(room)에 채팅방 이름이(foo)이 같이 전송되어 온다.

해당 채팅방의 정보(clientsInRoom) 중에서 사용자 수가 0명이면 (numClients === 0),

해당 접속자(socket)를 지정된 채팅방(room)의 생성자로 참여(join)시키고,

해당 접속자에게 created란 메시지를 전달한다(emit).

해당 접속자는 메시지를 수신하면 방 생성자 또는 방장 등의 의미를 가지도록 설정한다.

다시 다른 사용자가 접속하면 접속자수는 현재 1이기 때문에 (numClients === 1),

해당 접속자에게 joined란 메시지와 이제 화상 채팅을 실행할 준비를(ready) 하라고 메시지를 전달한다(emit).

 

서버를 재가동하고, 다시 접속하면 화상 채팅을 할 수 있다.

이제 서버 재가동없이 한 사람이 채팅을 종료하고 다시 접속(둘다)하면 화상 채팅을 다시 할 수 있다.

양쪽에서 웹 페이지 갱신(F5)을 하면 확인 할 수 있다.

 

참고: 다소 어렵지만 한사람이 채팅방을 나가면, 채팅방을 비우기 보다는 남은 사람은 그대로 두고 새로 입장하는 사람과 채팅할 수 있도록 하는 것이 좋다.

 

세번째로 오디오가 전송 되도록 한다.

오디오가 전송되도록 하기 위해서

클라이언트에서(main.js) WebRTC가 비디오 정보를 가지고 오도록 하는 다음의 기존 코드를 수정한다.

audio가 false로 되어 있다.

navigator.mediaDevices.getUserMedia({
  audio: false,
  video: true
})
.then(gotStream)
.catch(function(e) {
  alert('getUserMedia() error: ' + e.name);
});

화상 채팅을 위해 비디오 정보를 가지고 오는 getUserMedia의 파라미터에 지정된 audio 옵션을 다음과 같이 true로 지정한다.

  const mediaOption = {
    audio: true,
    video: {
      mandatory: {
        maxWidth: 160,
        maxHeight: 120,
        maxFrameRate: 5,
      },
      optional: [
        { facingMode: 'user' },
      ],
    },
  };
  
navigator.mediaDevices.getUserMedia(mediaOption)

오디오 설정외에 인터넷에서 검색한 비디오의 다양한 옵션도 추가로 작성하였다.

추가한 옵션은 이름에서 어느 정도 의미를 알 수 있을 것이고, 자세한 내용은 여기서 정리하지 않는다.

 

다시 채팅을 시작하면, 오디오가 전송되는 것을 확인할 수 있다.

다만, 두 개의 클라이언트가 가까이 있는 경우 심한 잡음(?)을 들을 수 있다.

 

이제 마지막으로 조금더 그럴듯하게 디자인을 변경해 본다.

디자인을 변경하기 위해서는 CSS를 알아야 한다.

자세한 내용은 정리하지 않으니 따로 찾아보고,

index.html 파일의 head에 다음과 같이 메타 태그를(빨간색) 추가한다.

이 코드는 모바일 화면을 위해 추가하는 것이다.

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
  <title>Realtime communication with WebRTC</title>
  <link rel="stylesheet" href="/css/main.css" />

</head>

css/main.css 파일의 내용을 다음과 같이 수정한다.

body {
  font-family: sans-serif;
}

#videos {
  width: 100%;
  max-width: 500px;
}

#localVideo {
  max-width: 100%;
  width: 100%;
  float:left;
  border: 1px solid;
}

#remoteVideo {
  max-width: 100%;
  width: 100%;
  float:left;
  border: 1px solid;
  display: none;
}

.localVideoInChatting {
  width: 100px !important;
  position: absolute;
}
.remoteVideoInChatting {
  display: inline-block !important;
}

위 CSS에서 localVideoInChattingremoteVideoInChatting 클래스(CSS의 클래스)를 기억해야 한다.

이 CSS의 내용은 채팅을 시작하기 전에는 내 화면(#localVideo)만 크게 보이고(width:100%),

상대 화면(#remoteVideo)은 보이지 않도록(display: none;)하는 것이다.

 

그러다 화상채팅이 시작되면(handleRemoteStreamAdded - 다음 코드)

내 화면(#localVideo)에 localVideoInChatting 클래스를 추가하여(add) 내 화면을 작게 만들고,

상대 화면(#remoteVideo)은 remoteVideoInChatting 클래스를 추가하여 크게 잘 보이도록 한다.

이 기능을 위해 다음 코드의 빨간색으로 표시된 부분을 추가하면 된다.

function handleRemoteStreamAdded(event) {
  console.log('Remote stream added.');
  remoteStream = event.stream;
  remoteVideo.srcObject = remoteStream;

  remoteVideo.classList.add("remoteVideoInChatting");
  localVideo.classList.add("localVideoInChatting");
}

function handleRemoteHangup() {
  remoteVideo.classList.remove("remoteVideoInChatting");
  localVideo.classList.remove("localVideoInChatting");
    
  console.log('Session terminated.');
  stop();
  isInitiator = false;
}

대화가 종료되면(handleRemoteHangup)

추가한 클래스들을 제거(remove)하여 원래데로 되돌린다.

 

이상으로 구글의 WebRTC 예제에 4가지를 추가하여 제법 그럴듯한 화상채팅 프로그램을 만들었다.

기존 예제에 추가된 소스는 GitHub에서 받을 수 있다.

 

제대로 화상채팅 프로그램을 만들기 위해서는 NodeJS Socket.IO, CSS를 알아야 하고,

WebRTCRTCPeerConnection를 알아야 하는 것을 알 수 있다.

그리고 signaling, STUN, TURN등의 용어를 사용하지 않았지만

예제 코드에 사용되어 있으니 확인하면서 알아 두어야 한다.

 

제대로된 화상채팅을 만들려면, 아직 많은 기능을 구현해야한다 (특히, 채팅방).

하나씩 기능을 추가하면서 제대로된 화상채팅 프로그램을 제작하다 보면 WebRTC에 대해서 잘 알게 되고

멋진 프로그램을 제작하게 될 것이다.

 

그리고 WebRTC를 이용하면,

화상채팅 외에 여러 명이 채팅 하는 컨퍼런스, 방송 등 미디어와 관련된 많은 것을 구현할 수 있다.

사용해보진 않았지만 WebRTC 기반의 Janus, Licode, Medooza, Jitsi 등을 이용하면 더 쉽게 구현할 수 있다고 한다.

 

 

+ Recent posts