-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
113 lines (85 loc) · 4.26 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
var libnice = require("libnice");
var WebSocket = require('ws');
var transform = require('sdp-transform');
var ws_uri = "";
if(process.argv[2]){
//quick and dirty; no validation
ws_uri = process.argv[2];
}else{
console.error("Required argument missing: node index.js <ws_uri>");
console.error("Example: node index.js wss://127.0.0.1:8443/helloworld");
process.exit();
}
//An audio-only SDP generated by Chrome.
//This contains some values we modify later on
var chromeSdp = "v=0\r\no=- 6531765081352225389 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE audio video\r\na=msid-semantic: WMS ZSXaL1I4ymOMSLQB4bzYQrRJ3uDk6Q3ww2nq\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:yASt\r\na=ice-pwd:y5tGa4TBBSnRAy7Gr8fjAEh7\r\na=fingerprint:sha-256 26:37:BF:39:10:F5:67:C5:A7:71:5A:91:BD:CF:9A:61:44:D0:5A:D9:32:06:FE:FA:0F:7B:84:42:EF:55:0C:F5\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:1116726908 cname:wPe25fuDNItpo6aG\r\na=ssrc:1116726908 msid:ZSXaL1I4ymOMSLQB4bzYQrRJ3uDk6Q3ww2nq 504c5016-033a-43c6-8f11-1c81ddf1c5d6\r\na=ssrc:1116726908 mslabel:ZSXaL1I4ymOMSLQB4bzYQrRJ3uDk6Q3ww2nq\r\na=ssrc:1116726908 label:504c5016-033a-43c6-8f11-1c81ddf1c5d6\r\n";
var agent = new libnice.NiceAgent();
agent.setStunServer("74.125.143.127:19302"); // stun.l.google.com
var stream = agent.createStream(1);
//Let libnice generate the ice-ufrag and ice-pwd values for this session
var credentials = stream.getLocalCredentials();
console.log("credentials", credentials);
//Parse the Chrome SDP to be able to modify it easily
var sdp = transform.parse(chromeSdp);
console.log('sdp:', sdp);
//change the ice-ufrag and ice-pwd values
sdp.media[0].iceUfrag = credentials.ufrag;
sdp.media[0].icePwd = credentials.pwd;
//write the modified SDP to a string so we can send it to the other end
var localSdp = transform.write(sdp);
stream.on('gatheringDone', function(candidates) {
console.log("gatheringDone", candidates);
var ws = new WebSocket(ws_uri, {
perMessageDeflate: false
});
ws.on('open', function open() {
console.log("websocket open");
ws.send(JSON.stringify({
"id":"start",
"sdpOffer":localSdp
}));
var candidates = stream.getLocalIceCandidates();
console.log("candidates", candidates);
for(var i=0; i<candidates.length; i++){
var candidateMessage = {
"id":"onIceCandidate",
"candidate":{
"candidate":candidates[i].substring(2), //strip of first 2 chars: a=
"sdpMid":"audio",
"sdpMLineIndex":0
}
};
ws.send(JSON.stringify(candidateMessage));
}
});
ws.on('message', function incoming(data) {
console.log("websocket data", data);
var parsedData = JSON.parse(data);
if(parsedData.id == 'iceCandidate'){
var candidate = parsedData.candidate.candidate;
console.log("adding remote candidate", candidate);
stream.addRemoteIceCandidate( "a="+candidate);
}
if(parsedData.id == 'startResponse'){
var remoteSdp = transform.parse(parsedData.sdpAnswer);
console.log('Remote sdp:', remoteSdp);
stream.setRemoteCredentials(remoteSdp.media[0].iceUfrag, remoteSdp.media[0].icePwd);
}
});
});
stream.on('stateChanged', function(component, state) {
console.log("stateChanged", component, state);
// state is a string
});
stream.on('receive', function(component, data) {
// data is a buffer
console.log("receive", component, data);
//echoing incoming data. This is where it all happens
stream.send(1, data);
});
stream.on('ready', function(component, data) {
// data is a buffer
console.log("ready", component, data);
});
//kick off candidate gathering
stream.gatherCandidates();