반응형

이전 두 포스팅에서는 


1. Janus-Gateway API 분석

2. Audiobridge API 분석


을 설명했었다. 이번 포스팅에서는 Chrome Browser에서 audiobridge 를 이용하는 방법에 대해서 코드를 중심으로 설명한다.


 이전 포스팅에서 spec 중심으로 간단한 javascript 코드를 예를 들어 설명했는데, 이번 포스팅은 실제 사용 가능한 javascript 코드를 예를 들어 설명하도록 하겠다. 다음은 상기 1,2 에서 실제 WebRTC 연결 설정까지 필요한 프로토콜을 구현한 코드이다.


 이 코드는 HTML 상에서 <script> 태그로 삽입하면 이후 jwsp 객체로 이용 가능하다. 기본적으로 websocket을 연결하고 메시지 송/수신 처리를 하고 있다. ws.onmessage 함수 내부에서 janus 에 설정되는 값을 가지고 janus에서 수신되는 메시지를 처리한다. 특히 create 와 attach 부분은 내부적으로 session_id 와 handle_id들을 관리하기 위해서 별도 처리를 하였다.

 plugin에 대한 처리는 jwsp.plugin 객체에 plugin 에 맞는 처리 명령어를 추가하도록 하였다. API 는 promise 기반으로 동작하도록 하였다. (tricle 과 같은 송신후 처리가 필요 없는 경우는 제외)


다음은 이 코드를 이용해서 audiobridge plugin에 join하는 html 이다. 페이지를 로딩하면 

1. websocket 접속

2. session_id 생성

3. audiobridge plugin에 attach

4. 5555 id를 가진 room 에 join (미리 5555 id로 room 을 생성해야 한다.)

5. getUserMedia 및 setLocalDescription 

6. Offer 생성 및 전송

7. Answer 수신 및 setRemoteDescription

99. 5. 이후 중간중간 생성되는 ice candidate 전송


순서로 동작한다. console.log 에 번호를 따라가면 자세한 연동 플로우를 파악할수 있을 것이다.


 다음은 실제 console.log 에 출력되는 값들이다.

1. connect websocket server addr:wss://XXX.XX.XXX.XXX/api


2. create session_id

[BROWSER>JANUS] MSG:{"janus":"create","transaction":"YzG8HZ4JZaNB"}

[JANUS>BROWSER] MSG:{"janus":"success","transaction":"YzG8HZ4JZaNB","data":{"id":7850187439976962}}


3. attach plugin

[BROWSER>JANUS] MSG:{"janus":"attach","opaqueId":"janus.plugin.audiobridgeE5WEkAFnWGPu",

"session_id":7850187439976962,

"plugin":"janus.plugin.audiobridge","transaction":"BBdkbyfPKswP"}

[JANUS>BROWSER] MSG:{"janus":"success","session_id":7850187439976962,

"transaction":"BBdkbyfPKswP","data":{"id":8004289983754311}}


4. attach janus.plugin.audiobridge success. start_keepalive

[BROWSER>JANUS] MSG:{"janus":"keepalive","session_id":7850187439976962,"transaction":"KDBewOC3wWf2"}


5. join room janus.plugin.audiobridge

[BROWSER>JANUS] MSG:{"janus":"message","session_id":7850187439976962,"handle_id":8004289983754311,"body":{"request":"join","room":5555},"transaction":"Tq3J0ZJNJA9M"}

[JANUS>BROWSER] MSG:{"janus":"ack","session_id":7850187439976962,"transaction":"KDBewOC3wWf2"}

[JANUS>BROWSER] MSG:{"janus":"ack","session_id":7850187439976962,"transaction":"Tq3J0ZJNJA9M"}

[JANUS>BROWSER] MSG:{"janus":"event","session_id":7850187439976962,"sender":8004289983754311,

"transaction":"Tq3J0ZJNJA9M",

"plugindata":{"plugin":"janus.plugin.audiobridge","data":{"audiobridge":"joined","room":5555,"id":825883797328149,

"participants":[{"id":7638826293839044,"display":"7966363071364335=2964878381274535","muted":false}]}}}


6. join room janus.plugin.audiobridge success. getUserMedia


7. Creating PeerConnection


8. Created SDP offer

[BROWSER>JANUS] MSG:{"janus":"message","session_id":7850187439976962,"handle_id":8004289983754311,

"body":{"request":"configure","muted":false},

"jsep":{"type":"offer","sdp":"v=0\r\no=- 2668916796041335774 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE audio\r\n

a=msid-semantic: WMS ZsTzZlO4IIDHnliYFi8FvUVNB9DA0URpNiQJ\r\n

m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126\r\n

c=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:tb/3\r\na=ice-pwd:DiMMmeZyJePx1Ah1UZUBSzx4\r\n

a=fingerprint:sha-256 58:54:4A:8B:27:5C:7A:0E:FE:6A:46:81:6F:A5:4C:6A:0A:32:C7:9A:0C:DA:D6:11:27:DA:3F:87:2B:DB:D0:CA\r\n

a=setup:actpass\r\na=mid:audio\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=sendrecv\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:104 ISAC/32000\r\na=rtpmap:9 G722/8000\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:106 CN/32000\r\na=rtpmap:105 CN/16000\r\na=rtpmap:13 CN/8000\r\na=rtpmap:110 telephone-event/48000\r\na=rtpmap:112 telephone-event/32000\r\na=rtpmap:113 telephone-event/16000\r\na=rtpmap:126 telephone-event/8000\r\na=ssrc:3514774571 cname:K0Iw7XgZpWO15zg6\r\n

a=ssrc:3514774571 msid:ZsTzZlO4IIDHnliYFi8FvUVNB9DA0URpNiQJ 87c4436f-c27e-4e31-a66f-b3c26bf525bb\r\n

a=ssrc:3514774571 mslabel:ZsTzZlO4IIDHnliYFi8FvUVNB9DA0URpNiQJ\r\n

a=ssrc:3514774571 label:87c4436f-c27e-4e31-a66f-b3c26bf525bb\r\n"},"transaction":"u8Q4BNf9wgLG"}


99. local icecandidate:candidate:2209869070 1 udp 2122260223 172.20.52.150 63589 typ host generation 0 ufrag tb/3 network-id 2

[BROWSER>JANUS] MSG:{"janus":"trickle","session_id":7850187439976962,"handle_id":8004289983754311,"candidate":{"candidate":"candidate:2209869070 1 udp 2122260223 172.20.52.150 63589 typ host generation 0 ufrag tb/3 network-id 2","sdpMid":"audio","sdpMLineIndex":0},"transaction":"c9SIVisUPIy0"}

audiobridge.html:55 99. local icecandidate:candidate:77142221 1 udp 2122194687 192.168.137.1 63590 typ host generation 0 ufrag tb/3 network-id 1

[BROWSER>JANUS] MSG:{"janus":"trickle","session_id":7850187439976962,"handle_id":8004289983754311,"candidate":{"candidate":"candidate:77142221 1 udp 2122194687 192.168.137.1 63590 typ host generation 0 ufrag tb/3 network-id 1","sdpMid":"audio","sdpMLineIndex":0},"transaction":"IJ8QsgPneG5d"}

[JANUS>BROWSER] MSG:{"janus":"ack","session_id":7850187439976962,"transaction":"c9SIVisUPIy0"}

[JANUS>BROWSER] MSG:{"janus":"ack","session_id":7850187439976962,"transaction":"IJ8QsgPneG5d"}

[JANUS>BROWSER] MSG:{"janus":"ack","session_id":7850187439976962,"transaction":"u8Q4BNf9wgLG"}


[JANUS>BROWSER] MSG:{"janus":"event","session_id":7850187439976962,"sender":8004289983754311,"transaction":"u8Q4BNf9wgLG","plugindata":{"plugin":"janus.plugin.audiobridge","data":{"audiobridge":"event","result":"ok"}},"jsep":{"type":"answer","sdp":"v=0\r\no=- 2668916796041335774 2 IN IP4 XXX.XX.XXX.XXX\r\ns=Room 5555\r\nt=0 0\r\na=group:BUNDLE audio\r\na=msid-semantic: WMS janus\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111\r\nc=IN IP4 XXX.XX.XXX.XXX\r\na=sendrecv\r\na=mid:audio\r\na=rtcp-mux\r\na=ice-ufrag:TJg2\r\na=ice-pwd:zJpJvWZNCBbf4jocBBkR76\r\na=ice-options:trickle\r\na=fingerprint:sha-256 08:CB:6B:0B:30:F0:11:A7:E7:6F:3C:14:56:5C:2F:FC:7B:82:28:53:2C:01:21:F3:3B:8B:F3:FA:A2:F6:12:3B\r\na=setup:active\r\na=rtpmap:111 opus/48000/2\r\na=fmtp:111 maxplaybackrate=16000; stereo=0; sprop-stereo=0; useinbandfec=0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=ssrc:2668784176 cname:janusaudio\r\na=ssrc:2668784176 msid:janus janusa0\r\na=ssrc:2668784176 mslabel:janus\r\na=ssrc:2668784176 label:janusa0\r\na=candidate:1 1 udp 2013266431 XXX.XX.XXX.XXX 49361 typ host\r\na=candidate:2 1 udp 2013266431 172.17.0.1 46967 typ host\r\n"}}

9. offer success and answer received


10. Set Remove Description Success

Add Remote Stream URL: blob:https://XXX.XX.XXX.XXX/bc7a1bfc-d243-4dd6-95af-4c516612706b


99. local icecandidate:candidate:3442741758 1 tcp 1518280447 172.20.52.150 9 typ host tcptype active generation 0 ufrag tb/3 network-id 2

[BROWSER>JANUS] MSG:{"janus":"trickle","session_id":7850187439976962,"handle_id":8004289983754311,"candidate":{"candidate":"candidate:3442741758 1 tcp 1518280447 172.20.52.150 9 typ host tcptype active generation 0 ufrag tb/3 network-id 2","sdpMid":"audio","sdpMLineIndex":0},"transaction":"Rmee3bmPytUQ"}

audiobridge.html:55 99. local icecandidate:candidate:1243276349 1 tcp 1518214911 192.168.137.1 9 typ host tcptype active generation 0 ufrag tb/3 network-id 1

[BROWSER>JANUS] MSG:{"janus":"trickle","session_id":7850187439976962,"handle_id":8004289983754311,"candidate":{"candidate":"candidate:1243276349 1 tcp 1518214911 192.168.137.1 9 typ host tcptype active generation 0 ufrag tb/3 network-id 1","sdpMid":"audio","sdpMLineIndex":0},"transaction":"juqOo1WPExYz"}

[JANUS>BROWSER] MSG:{"janus":"ack","session_id":7850187439976962,"transaction":"Rmee3bmPytUQ"}

[JANUS>BROWSER] MSG:{"janus":"ack","session_id":7850187439976962,"transaction":"juqOo1WPExYz"}

[JANUS>BROWSER] MSG:{"janus":"webrtcup","session_id":7850187439976962,"sender":8004289983754311}

[JANUS>BROWSER] MSG:{"janus":"media","session_id":7850187439976962,"sender":8004289983754311,"type":"audio","receiving":true}

[JANUS>BROWSER] MSG:{"janus":"event","session_id":7850187439976962,"sender":8004289983754311,"plugindata":{"plugin":"janus.plugin.audiobridge","data":{"audiobridge":"event","room":5555,"leaving":7638826293839044}}}

[BROWSER>JANUS] MSG:{"janus":"keepalive","session_id":7850187439976962,"transaction":"XQVz3zE6DBAX"}

[JANUS>BROWSER] MSG:{"janus":"ack","session_id":7850187439976962,"transaction":"XQVz3zE6DBAX"}

[BROWSER>JANUS] MSG:{"janus":"keepalive","session_id":7850187439976962,"transaction":"nVldzS071ybE"}

[JANUS>BROWSER] MSG:{"janus":"ack","session_id":7850187439976962,"transaction":"nVldzS071ybE"} 


 Janus-Gateway에서 webrtcup event가 발생하면 webrtc channel이 생성된 것이고, media event가 발생하면 media가 전송되고 있음을 알려준다.


반응형
Posted by alias
,