Skip to content

Instantly share code, notes, and snippets.

@hsnks100
Last active December 5, 2018 00:29
Show Gist options
  • Save hsnks100/54c6ea8744ef5b967e661e1f4bdedf8f to your computer and use it in GitHub Desktop.
Save hsnks100/54c6ea8744ef5b967e661e1f4bdedf8f to your computer and use it in GitHub Desktop.
WEBRTC문서

WEBRTC 2차 문서

여기서는 실제 turn, stun 등의 시그널링과 실제 화상통신에 대한 것을 정리하는 내용을 다룬다.

WEBRTC Signaling 개념

WEBRTC 는 p2p 통신을 하기 위해 사전에 미리 sdp 나 turn 서버를 서로 알고 있어야 한다.

어떠한 텍스트 정보를 전달할 수 있는 통신수단(예: 소켓, 웹소켓 등)의 종류는 어떤것이라도 상관없다.

여기서는 websocket 을 사용했다.

실제 보드 개발에는 socket 을 쓰면 될것이다.

이 서버는 단순히 접속을 하면 room 을 만들고 서로 준비가 된 상태에서 한 client가 broadcast 를 하게 되면, 나머지 client 에서 그 데이터를 받아서 joinRequest 를 보내면서 통신이 시작된다.

var fs = require('fs'); 
var _static = require('node-static');
var file = new _static.Server('./public');

var options = {
    key: fs.readFileSync('fake-keys/privatekey.pem'),
    cert: fs.readFileSync('fake-keys/certificate.pem')
};

var app = require('https').createServer(options, function(request, response) {
    request.addListener('end', function() {
        file.serve(request, response);
    }).resume();
});

var WebSocketServer = require('websocket').server;

new WebSocketServer({
    httpServer: app,
    autoAcceptConnections: false
}).on('request', onRequest);

var CHANNELS = { }; 
function onRequest(socket) {
    var origin = socket.origin + socket.resource;

    var websocket = socket.accept(null, origin);

    websocket.on('message', function(message) {
        if (message.type === 'utf8') {
            onMessage(JSON.parse(message.utf8Data), websocket);
        }
    });

    websocket.on('close', function() {
        truncateChannels(websocket);
    });
}

function onMessage(message, websocket) {
    //console.log("from client ...", message);
    if (message.open)
        onOpen(message, websocket);
    else
        sendMessage(message, websocket);
}

function onOpen(message, websocket) {
    var channel = CHANNELS[message.channel];

    if (channel)
        CHANNELS[message.channel][channel.length] = websocket;
    else
        CHANNELS[message.channel] = [websocket];
    //console.log("CHANNELS!!!!!!!!!!", CHANNELS);
}

function sendMessage(message, websocket) {
    message.data = JSON.stringify(message.data);
    var channel = CHANNELS[message.channel];
    if (!channel) {
        console.error('no such channel exists');
        return;
    }

    for (var i = 0; i < channel.length; i++) {
        if (channel[i] && channel[i] != websocket) {
            try {
                console.log(i, " 에게 ", message.data);
                channel[i].sendUTF(message.data);
            } catch(e) {
            }
        }
    }
} 

function swapArray(arr) {
    var swapped = [],
        length = arr.length;
    for (var i = 0; i < length; i++) {
        if (arr[i])
            swapped[swapped.length] = arr[i];
    }
    return swapped;
}

function truncateChannels(websocket) {
    for (var channel in CHANNELS) {
        var _channel = CHANNELS[channel];
        for (var i = 0; i < _channel.length; i++) {
            if (_channel[i] == websocket)
                delete _channel[i];
        }
        CHANNELS[channel] = swapArray(_channel);
        if (CHANNELS && CHANNELS[channel] && !CHANNELS[channel].length)
            delete CHANNELS[channel];
    }
} 
app.listen(12034); 
console.log('Please open SSL URL: https://localhost:12034/');

상단의 내용이 서버 내용의 끝이다.

p2p

image

두 브라우저가 통신을 하기위해 클라이언트 코드가 필요하다.

위 흐름을 구현한 코드.

<button id="start-broadcasting" class="setup">Start Transmitting Yourself!</button>
<div id="videos-container">
    <video width="470" id="remoteView" autoplay></video>
    <video width="470" id="localView" autoplay></video> 
</div>
<script>

var channel = location.href.replace( /\/|:|#|%|\.|\[|\]/g , '');
var websocket = new WebSocket('wss://' + document.domain + ':12034');
websocket.onopen = function() {
    websocket.push(JSON.stringify({
        open: true,
        channel: channel
    }));
};
var pc;
var isFirefox = !!navigator.mozGetUserMedia;
var isChrome = !!navigator.webkitGetUserMedia;
var STUN = {
    url: isChrome ? 'stun:stun.l.google.com:19302' : 'stun:23.21.150.121'
}; 
var TURN = {
    url: 'turn:[email protected]:80',
    credential: 'homeo'
}; 
var iceServers = {
    iceServers: [STUN]
}; 
if (isChrome) {
    if (parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 28)
        TURN = {
            url: 'turn:turn.bistri.com:80',
            credential: 'homeo',
            username: 'homeo'
        };

    iceServers.iceServers = [STUN, TURN];
} 
var optionalArgument = {
    optional: [{
        DtlsSrtpKeyAgreement: true
    }]
};

function start() {
    pc = new RTCPeerConnection(iceServers, optionalArgument); 
    pc.onicecandidate = function (evt) {
        console.log("onicecandidate");
        if (evt.candidate) {
            websocket.send({
                candidate: evt.candidate
            })
        }
    };
    pc.onnegotiationneeded = function () {
        console.log("onnegotiationneeded");
        pc.createOffer(localDescCreated, logError);
    }
    pc.onaddstream = function (evt) {
        console.log("onaddstream");
        var removeView = document.getElementById("remoteView");
        remoteView.src = URL.createObjectURL(evt.stream);
    };
    navigator.getUserMedia({
        'audio': true,
        'video': true
    }, function (stream) {
        var localView = document.getElementById("localView");
        var video = localView;
        video.src = URL.createObjectURL(stream);
        video.controls = true;
        video.muted = true;
        pc.addStream(stream);
    }, logError);
}

function localDescCreated(desc) {
    console.log("localDescCreated");
    pc.setLocalDescription(desc, function () {
        console.log("setLocalDescCreated CallBack");
        websocket.send({
            sdp: pc.localDescription
        });
    }, logError);
}

function logError(error) {
    log(error.name + ': ' + error.message);
}
websocket.onmessage = function(e) {
    var message = JSON.parse(e.data);
    if(message.broadcast) {
        websocket.send({
            joinRequest: true,
        });
        window.alert("it will join them");
        start();
    }
    if(message.joinRequest) {
        start();
        window.alert("they join us"); 
    } 
    if (message.sdp) {
        console.log("sdp 받았다.");
        pc.setRemoteDescription(new RTCSessionDescription(message.sdp), function () {
            // if we received an offer, we need to answer
            if (pc.remoteDescription.type == 'offer') {
                console.log("createAnswer");
                pc.createAnswer(localDescCreated, logError);
            }
        }, logError);
    }
    if(message.candidate) {
        console.log("candidate!!!", message);
        pc.addIceCandidate(new RTCIceCandidate(message.candidate));
    }
};
websocket.push = websocket.send;
websocket.send = function(data) {
    websocket.push(JSON.stringify({
        data: data,
        channel: channel
    }));
}; 
document.querySelector('#start-broadcasting').onclick = function() {
    websocket.send({broadcast:true}); 
};


</script> 

로그 결과

pc1

onnegotiationneeded
localDescCreated
setLocalDescCreated Callback
onicecandidate [7]
sdp 받았다.
candidate!!!
sdp 받았다.
createAnswer
onaddstream
localDescCreated
setLocalDescCreated Callback

pc2

sdp 받았다.
candidate!!![6]
createAnswer
onaddstream
localDescCreated
setLocalDescCreated CallBack
onicecandidate
onnegotiationneeded
localDescCreated
setLocalDescCreated CallBack
sdp 받았다.

server

0 ' 에게 ' '{"broadcast":true}'
1 ' 에게 ' '{"joinRequest":true}'
1 ' 에게 ' '{"sdp":{"type":"offer","sdp":"v=0\\r\\no=- 2448330732196048433 2 IN IP4 127.0.0.1\\r\\ns=-\\r\\nt=0 0\\r\\na=group:BUNDLE audio video\\r\\na=msid-semantic: WMS B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH\\r\\nm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126\\r\\nc=IN IP4 0.0.0.0\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=ice-ufrag:XhEn\\r\\na=ice-pwd:nbtxJI5UNjyL0IQ52EOQ8cCg\\r\\na=ice-options:trickle\\r\\na=fingerprint:sha-256 BB:9B:A9:90:33:E9:4F:07:7E:58:0A:9D:09:13:E1:9D:A1:CE:85:1A:FB:D2:5D:81:CA:74:6F:C2:43:39:66:0D\\r\\na=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:4099229577 cname:KxMjmPUWeatN6Kzu\\r\\na=ssrc:4099229577 msid:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH e90476d3-2275-4fee-a0cd-5c7e5f859fb3\\r\\na=ssrc:4099229577 mslabel:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH\\r\\na=ssrc:4099229577 label:e90476d3-2275-4fee-a0cd-5c7e5f859fb3\\r\\nm=video 9 UDP/TLS/RTP/SAVPF 96 98 100 102 127 97 99 101 125\\r\\nc=IN IP4 0.0.0.0\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=ice-ufrag:XhEn\\r\\na=ice-pwd:nbtxJI5UNjyL0IQ52EOQ8cCg\\r\\na=ice-options:trickle\\r\\na=fingerprint:sha-256 BB:9B:A9:90:33:E9:4F:07:7E:58:0A:9D:09:13:E1:9D:A1:CE:85:1A:FB:D2:5D:81:CA:74:6F:C2:43:39:66:0D\\r\\na=setup:actpass\\r\\na=mid:video\\r\\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\\r\\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\\r\\na=extmap:4 urn:3gpp:video-orientation\\r\\na=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\\r\\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\\r\\na=sendrecv\\r\\na=rtcp-mux\\r\\na=rtcp-rsize\\r\\na=rtpmap:96 VP8/90000\\r\\na=rtcp-fb:96 ccm fir\\r\\na=rtcp-fb:96 nack\\r\\na=rtcp-fb:96 nack pli\\r\\na=rtcp-fb:96 goog-remb\\r\\na=rtcp-fb:96 transport-cc\\r\\na=rtpmap:98 VP9/90000\\r\\na=rtcp-fb:98 ccm fir\\r\\na=rtcp-fb:98 nack\\r\\na=rtcp-fb:98 nack pli\\r\\na=rtcp-fb:98 goog-remb\\r\\na=rtcp-fb:98 transport-cc\\r\\na=rtpmap:100 H264/90000\\r\\na=rtcp-fb:100 ccm fir\\r\\na=rtcp-fb:100 nack\\r\\na=rtcp-fb:100 nack pli\\r\\na=rtcp-fb:100 goog-remb\\r\\na=rtcp-fb:100 transport-cc\\r\\na=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\\r\\na=rtpmap:102 red/90000\\r\\na=rtpmap:127 ulpfec/90000\\r\\na=rtpmap:97 rtx/90000\\r\\na=fmtp:97 apt=96\\r\\na=rtpmap:99 rtx/90000\\r\\na=fmtp:99 apt=98\\r\\na=rtpmap:101 rtx/90000\\r\\na=fmtp:101 apt=100\\r\\na=rtpmap:125 rtx/90000\\r\\na=fmtp:125 apt=102\\r\\na=ssrc-group:FID 809685964 3334537262\\r\\na=ssrc:809685964 cname:KxMjmPUWeatN6Kzu\\r\\na=ssrc:809685964 msid:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH 2e5d5bb5-895e-497b-97dd-99e101895177\\r\\na=ssrc:809685964 mslabel:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH\\r\\na=ssrc:809685964 label:2e5d5bb5-895e-497b-97dd-99e101895177\\r\\na=ssrc:3334537262 cname:KxMjmPUWeatN6Kzu\\r\\na=ssrc:3334537262 msid:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH 2e5d5bb5-895e-497b-97dd-99e101895177\\r\\na=ssrc:3334537262 mslabel:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH\\r\\na=ssrc:3334537262 label:2e5d5bb5-895e-497b-97dd-99e101895177\\r\\n"}}'
1 ' 에게 ' '{"candidate":{"candidate":"candidate:2437072876 1 udp 2122260223 192.168.1.2 54332 typ host generation 0 ufrag XhEn network-id 1","sdpMid":"audio","sdpMLineIndex":0}}'
1 ' 에게 ' '{"candidate":{"candidate":"candidate:2437072876 1 udp 2122260223 192.168.1.2 53379 typ host generation 0 ufrag XhEn network-id 1","sdpMid":"video","sdpMLineIndex":1}}'
1 ' 에게 ' '{"candidate":{"candidate":"candidate:3753982748 1 tcp 1518280447 192.168.1.2 9 typ host tcptype active generation 0 ufrag XhEn network-id 1","sdpMid":"audio","sdpMLineIndex":0}}'
1 ' 에게 ' '{"candidate":{"candidate":"candidate:3753982748 1 tcp 1518280447 192.168.1.2 9 typ host tcptype active generation 0 ufrag XhEn network-id 1","sdpMid":"video","sdpMLineIndex":1}}'
1 ' 에게 ' '{"candidate":{"candidate":"candidate:941443129 1 udp 1686052607 119.203.5.62 54332 typ srflx raddr 192.168.1.2 rport 54332 generation 0 ufrag XhEn network-id 1","sdpMid":"audio","sdpMLineIndex":0}}'
1 ' 에게 ' '{"candidate":{"candidate":"candidate:941443129 1 udp 1686052607 119.203.5.62 53379 typ srflx raddr 192.168.1.2 rport 53379 generation 0 ufrag XhEn network-id 1","sdpMid":"video","sdpMLineIndex":1}}'
0 ' 에게 ' '{"sdp":{"type":"answer","sdp":"v=0\\r\\no=- 7934811631185428798 2 IN IP4 127.0.0.1\\r\\ns=-\\r\\nt=0 0\\r\\na=group:BUNDLE audio video\\r\\na=msid-semantic: WMS\\r\\nm=audio 59683 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126\\r\\nc=IN IP4 192.168.1.22\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=candidate:514002099 1 udp 2122260223 192.168.1.22 59683 typ host generation 0 network-id 1\\r\\na=ice-ufrag:hVSq\\r\\na=ice-pwd:KPenDaJMEF/PUqHVws+WQLKy\\r\\na=fingerprint:sha-256 EF:F8:CD:07:C8:44:E8:78:9D:69:00:4A:28:E1:17:44:FE:9A:20:5F:D9:00:AD:F2:85:38:A5:36:88:6C:18:D4\\r\\na=setup:active\\r\\na=mid:audio\\r\\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\\r\\na=recvonly\\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\\nm=video 9 UDP/TLS/RTP/SAVPF 96 98 100 102 127 97 99 101 125\\r\\nc=IN IP4 0.0.0.0\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=ice-ufrag:hVSq\\r\\na=ice-pwd:KPenDaJMEF/PUqHVws+WQLKy\\r\\na=fingerprint:sha-256 EF:F8:CD:07:C8:44:E8:78:9D:69:00:4A:28:E1:17:44:FE:9A:20:5F:D9:00:AD:F2:85:38:A5:36:88:6C:18:D4\\r\\na=setup:active\\r\\na=mid:video\\r\\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\\r\\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\\r\\na=extmap:4 urn:3gpp:video-orientation\\r\\na=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\\r\\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\\r\\na=recvonly\\r\\na=rtcp-mux\\r\\na=rtcp-rsize\\r\\na=rtpmap:96 VP8/90000\\r\\na=rtcp-fb:96 ccm fir\\r\\na=rtcp-fb:96 nack\\r\\na=rtcp-fb:96 nack pli\\r\\na=rtcp-fb:96 goog-remb\\r\\na=rtcp-fb:96 transport-cc\\r\\na=rtpmap:98 VP9/90000\\r\\na=rtcp-fb:98 ccm fir\\r\\na=rtcp-fb:98 nack\\r\\na=rtcp-fb:98 nack pli\\r\\na=rtcp-fb:98 goog-remb\\r\\na=rtcp-fb:98 transport-cc\\r\\na=rtpmap:100 H264/90000\\r\\na=rtcp-fb:100 ccm fir\\r\\na=rtcp-fb:100 nack\\r\\na=rtcp-fb:100 nack pli\\r\\na=rtcp-fb:100 goog-remb\\r\\na=rtcp-fb:100 transport-cc\\r\\na=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\\r\\na=rtpmap:102 red/90000\\r\\na=rtpmap:127 ulpfec/90000\\r\\na=rtpmap:97 rtx/90000\\r\\na=fmtp:97 apt=96\\r\\na=rtpmap:99 rtx/90000\\r\\na=fmtp:99 apt=98\\r\\na=rtpmap:101 rtx/90000\\r\\na=fmtp:101 apt=100\\r\\na=rtpmap:125 rtx/90000\\r\\na=fmtp:125 apt=102\\r\\n"}}'
0 ' 에게 ' '{"candidate":{"candidate":"candidate:514002099 1 udp 2122260223 192.168.1.22 59683 typ host generation 0 ufrag hVSq network-id 1","sdpMid":"audio","sdpMLineIndex":0}}'
0 ' 에게 ' '{"sdp":{"type":"offer","sdp":"v=0\\r\\no=- 7934811631185428798 3 IN IP4 127.0.0.1\\r\\ns=-\\r\\nt=0 0\\r\\na=group:BUNDLE audio video\\r\\na=msid-semantic: WMS jtp6GtnFckLUocKIin4MT3PydrljbA14xGgl\\r\\nm=audio 59683 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126\\r\\nc=IN IP4 192.168.1.22\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=candidate:514002099 1 udp 2122260223 192.168.1.22 59683 typ host generation 0 network-id 1\\r\\na=ice-ufrag:hVSq\\r\\na=ice-pwd:KPenDaJMEF/PUqHVws+WQLKy\\r\\na=fingerprint:sha-256 EF:F8:CD:07:C8:44:E8:78:9D:69:00:4A:28:E1:17:44:FE:9A:20:5F:D9:00:AD:F2:85:38:A5:36:88:6C:18:D4\\r\\na=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:2162542293 cname:RHwVAqg7NxlDh2Ll\\r\\na=ssrc:2162542293 msid:jtp6GtnFckLUocKIin4MT3PydrljbA14xGgl 55cb3c32-2a54-4580-93d1-54fec125f40d\\r\\na=ssrc:2162542293 mslabel:jtp6GtnFckLUocKIin4MT3PydrljbA14xGgl\\r\\na=ssrc:2162542293 label:55cb3c32-2a54-4580-93d1-54fec125f40d\\r\\nm=video 9 UDP/TLS/RTP/SAVPF 96 98 100 102 127 97 99 101 125\\r\\nc=IN IP4 0.0.0.0\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=ice-ufrag:hVSq\\r\\na=ice-pwd:KPenDaJMEF/PUqHVws+WQLKy\\r\\na=fingerprint:sha-256 EF:F8:CD:07:C8:44:E8:78:9D:69:00:4A:28:E1:17:44:FE:9A:20:5F:D9:00:AD:F2:85:38:A5:36:88:6C:18:D4\\r\\na=setup:actpass\\r\\na=mid:video\\r\\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\\r\\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\\r\\na=extmap:4 urn:3gpp:video-orientation\\r\\na=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\\r\\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\\r\\na=sendrecv\\r\\na=rtcp-mux\\r\\na=rtcp-rsize\\r\\na=rtpmap:96 VP8/90000\\r\\na=rtcp-fb:96 ccm fir\\r\\na=rtcp-fb:96 nack\\r\\na=rtcp-fb:96 nack pli\\r\\na=rtcp-fb:96 goog-remb\\r\\na=rtcp-fb:96 transport-cc\\r\\na=rtpmap:98 VP9/90000\\r\\na=rtcp-fb:98 ccm fir\\r\\na=rtcp-fb:98 nack\\r\\na=rtcp-fb:98 nack pli\\r\\na=rtcp-fb:98 goog-remb\\r\\na=rtcp-fb:98 transport-cc\\r\\na=rtpmap:100 H264/90000\\r\\na=rtcp-fb:100 ccm fir\\r\\na=rtcp-fb:100 nack\\r\\na=rtcp-fb:100 nack pli\\r\\na=rtcp-fb:100 goog-remb\\r\\na=rtcp-fb:100 transport-cc\\r\\na=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\\r\\na=rtpmap:102 red/90000\\r\\na=rtpmap:127 ulpfec/90000\\r\\na=rtpmap:97 rtx/90000\\r\\na=fmtp:97 apt=96\\r\\na=rtpmap:99 rtx/90000\\r\\na=fmtp:99 apt=98\\r\\na=rtpmap:101 rtx/90000\\r\\na=fmtp:101 apt=100\\r\\na=rtpmap:125 rtx/90000\\r\\na=fmtp:125 apt=102\\r\\na=ssrc-group:FID 3759801015 1863437275\\r\\na=ssrc:3759801015 cname:RHwVAqg7NxlDh2Ll\\r\\na=ssrc:3759801015 msid:jtp6GtnFckLUocKIin4MT3PydrljbA14xGgl b3a1e4d9-898f-4d05-81bd-d0d6b1cdc14b\\r\\na=ssrc:3759801015 mslabel:jtp6GtnFckLUocKIin4MT3PydrljbA14xGgl\\r\\na=ssrc:3759801015 label:b3a1e4d9-898f-4d05-81bd-d0d6b1cdc14b\\r\\na=ssrc:1863437275 cname:RHwVAqg7NxlDh2Ll\\r\\na=ssrc:1863437275 msid:jtp6GtnFckLUocKIin4MT3PydrljbA14xGgl b3a1e4d9-898f-4d05-81bd-d0d6b1cdc14b\\r\\na=ssrc:1863437275 mslabel:jtp6GtnFckLUocKIin4MT3PydrljbA14xGgl\\r\\na=ssrc:1863437275 label:b3a1e4d9-898f-4d05-81bd-d0d6b1cdc14b\\r\\n"}}'
1 ' 에게 ' '{"sdp":{"type":"answer","sdp":"v=0\\r\\no=- 2448330732196048433 3 IN IP4 127.0.0.1\\r\\ns=-\\r\\nt=0 0\\r\\na=group:BUNDLE audio video\\r\\na=msid-semantic: WMS B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH\\r\\nm=audio 54332 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126\\r\\nc=IN IP4 119.203.5.62\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=candidate:2437072876 1 udp 2122260223 192.168.1.2 54332 typ host generation 0 network-id 1\\r\\na=candidate:3753982748 1 tcp 1518280447 192.168.1.2 9 typ host tcptype active generation 0 network-id 1\\r\\na=candidate:941443129 1 udp 1686052607 119.203.5.62 54332 typ srflx raddr 192.168.1.2 rport 54332 generation 0 network-id 1\\r\\na=ice-ufrag:XhEn\\r\\na=ice-pwd:nbtxJI5UNjyL0IQ52EOQ8cCg\\r\\na=ice-options:trickle\\r\\na=fingerprint:sha-256 BB:9B:A9:90:33:E9:4F:07:7E:58:0A:9D:09:13:E1:9D:A1:CE:85:1A:FB:D2:5D:81:CA:74:6F:C2:43:39:66:0D\\r\\na=setup:passive\\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:4099229577 cname:KxMjmPUWeatN6Kzu\\r\\na=ssrc:4099229577 msid:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH e90476d3-2275-4fee-a0cd-5c7e5f859fb3\\r\\na=ssrc:4099229577 mslabel:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH\\r\\na=ssrc:4099229577 label:e90476d3-2275-4fee-a0cd-5c7e5f859fb3\\r\\nm=video 53379 UDP/TLS/RTP/SAVPF 96 98 100 102 127 97 99 101 125\\r\\nc=IN IP4 119.203.5.62\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=candidate:2437072876 1 udp 2122260223 192.168.1.2 53379 typ host generation 0 network-id 1\\r\\na=candidate:3753982748 1 tcp 1518280447 192.168.1.2 9 typ host tcptype active generation 0 network-id 1\\r\\na=candidate:941443129 1 udp 1686052607 119.203.5.62 53379 typ srflx raddr 192.168.1.2 rport 53379 generation 0 network-id 1\\r\\na=ice-ufrag:XhEn\\r\\na=ice-pwd:nbtxJI5UNjyL0IQ52EOQ8cCg\\r\\na=ice-options:trickle\\r\\na=fingerprint:sha-256 BB:9B:A9:90:33:E9:4F:07:7E:58:0A:9D:09:13:E1:9D:A1:CE:85:1A:FB:D2:5D:81:CA:74:6F:C2:43:39:66:0D\\r\\na=setup:passive\\r\\na=mid:video\\r\\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\\r\\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\\r\\na=extmap:4 urn:3gpp:video-orientation\\r\\na=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\\r\\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\\r\\na=sendrecv\\r\\na=rtcp-mux\\r\\na=rtcp-rsize\\r\\na=rtpmap:96 VP8/90000\\r\\na=rtcp-fb:96 ccm fir\\r\\na=rtcp-fb:96 nack\\r\\na=rtcp-fb:96 nack pli\\r\\na=rtcp-fb:96 goog-remb\\r\\na=rtcp-fb:96 transport-cc\\r\\na=rtpmap:98 VP9/90000\\r\\na=rtcp-fb:98 ccm fir\\r\\na=rtcp-fb:98 nack\\r\\na=rtcp-fb:98 nack pli\\r\\na=rtcp-fb:98 goog-remb\\r\\na=rtcp-fb:98 transport-cc\\r\\na=rtpmap:100 H264/90000\\r\\na=rtcp-fb:100 ccm fir\\r\\na=rtcp-fb:100 nack\\r\\na=rtcp-fb:100 nack pli\\r\\na=rtcp-fb:100 goog-remb\\r\\na=rtcp-fb:100 transport-cc\\r\\na=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\\r\\na=rtpmap:102 red/90000\\r\\na=rtpmap:127 ulpfec/90000\\r\\na=rtpmap:97 rtx/90000\\r\\na=fmtp:97 apt=96\\r\\na=rtpmap:99 rtx/90000\\r\\na=fmtp:99 apt=98\\r\\na=rtpmap:101 rtx/90000\\r\\na=fmtp:101 apt=100\\r\\na=rtpmap:125 rtx/90000\\r\\na=fmtp:125 apt=102\\r\\na=ssrc-group:FID 809685964 3334537262\\r\\na=ssrc:809685964 cname:KxMjmPUWeatN6Kzu\\r\\na=ssrc:809685964 msid:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH 2e5d5bb5-895e-497b-97dd-99e101895177\\r\\na=ssrc:809685964 mslabel:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH\\r\\na=ssrc:809685964 label:2e5d5bb5-895e-497b-97dd-99e101895177\\r\\na=ssrc:3334537262 cname:KxMjmPUWeatN6Kzu\\r\\na=ssrc:3334537262 msid:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH 2e5d5bb5-895e-497b-97dd-99e101895177\\r\\na=ssrc:3334537262 mslabel:B6GweMac79bGvdfnNYjVoLxufXP6nbq1s4JH\\r\\na=ssrc:3334537262 label:2e5d5bb5-895e-497b-97dd-99e101895177\\r\\n"}}'

소켓이 할 일

위 로그를 보면 결국 소켓은 json 으로 되어있는 candidate 정보와 sdp 정보만 전달해주면 된다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment