-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
toby cabot
committed
Jul 22, 2013
0 parents
commit 09117f4
Showing
6 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* MIT License: https://webrtc-experiment.appspot.com/licence/ | ||
2013, Muaz Khan<muazkh>--[github.com/muaz-khan] | ||
Demo & Documentation: http://bit.ly/RTCPeerConnection-Documentation */ | ||
window.moz = !! navigator.mozGetUserMedia; | ||
var PeerConnection = function (options) { | ||
var PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection, | ||
SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription, | ||
IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate; | ||
|
||
// See https://gist.github.com/zziuni/3741933 for a list of public STUN servers | ||
var iceServers = { | ||
iceServers: [{ url: 'stun:stunserver.org' }] | ||
}; | ||
|
||
var optional = { | ||
optional: [] | ||
}; | ||
if (!moz) { | ||
// See http://www.webrtc.org/interop under "Constraints / configurations issues." | ||
optional.optional = [{ | ||
DtlsSrtpKeyAgreement: true | ||
} | ||
]; | ||
} | ||
|
||
var peerConnection = new PeerConnection(iceServers, optional); | ||
peerConnection.onicecandidate = function(event) { | ||
if (!event.candidate) return; | ||
options.onicecandidate(event.candidate); | ||
} | ||
peerConnection.onaddstream = function(event) { | ||
console.log('------------onaddstream'); | ||
options.onaddstream(event.stream); | ||
} | ||
|
||
var constraints = options.constraints || { | ||
optional: [], | ||
mandatory: { | ||
OfferToReceiveAudio: true, | ||
OfferToReceiveVideo: true | ||
} | ||
}; | ||
if (moz) constraints.mandatory.MozDontOfferDataChannel = true; | ||
|
||
return { | ||
createOffer: function (callback) { | ||
peerConnection.createOffer(function (sessionDescription) { | ||
peerConnection.setLocalDescription(sessionDescription); | ||
callback(sessionDescription); | ||
}, null, constraints); | ||
}, | ||
|
||
createAnswer: function (offerSDP, callback) { | ||
peerConnection.setRemoteDescription(new SessionDescription(offerSDP)); | ||
peerConnection.createAnswer(function (sessionDescription) { | ||
peerConnection.setLocalDescription(sessionDescription); | ||
callback(sessionDescription); | ||
}, null, constraints); | ||
}, | ||
|
||
setRemoteDescription: function (sdp) { | ||
console.log('--------adding answer sdp:'); | ||
console.log(sdp.sdp); | ||
|
||
sdp = new SessionDescription(sdp); | ||
peerConnection.setRemoteDescription(sdp); | ||
}, | ||
|
||
addICECandidate: function (candidate) { | ||
console.log("addICE: got candidate: " + candidate.candidate); | ||
peerConnection.addIceCandidate(new IceCandidate({ | ||
sdpMLineIndex: candidate.sdpMLineIndex, | ||
candidate: candidate.candidate | ||
})); | ||
}, | ||
|
||
addStream: function(stream) { | ||
console.log("stream provided, attaching..."); | ||
peerConnection.addStream(stream); | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
This is a *minimal* demo of WebRTC video calling between two browsers. | ||
Because the signalling layer isn't standardized, you'll need to run a | ||
small node.js server to pass signalling messages between the two | ||
browsers. The media connections are point-to-point, though, once the | ||
signalling has happened no server is required. | ||
|
||
This demo is based on Silvia Pfeiffer's WebRTC via Web Sockets demo, | ||
and Muaz Khan's WebRTC-Experiment websocket-over-nodejs demo. | ||
Silvia's demo became obsolete (it uses ROAP signalling while JSEP is | ||
now the standard) and Muaz's demo was more complex than I liked which | ||
made it difficult to figure out what the WebRTC API's were doing. | ||
Both of their code was very helpful to me, though! | ||
|
||
Silvia's Blog post: | ||
http://blog.gingertech.net/2012/06/04/video-conferencing-in-html5-webrtc-via-web-sockets/ | ||
|
||
Muaz's WebRTC Experiments web site: | ||
https://www.webrtc-experiment.com/ | ||
|
||
Muaz's WebSocket over Node.js demo: | ||
https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket-over-nodejs | ||
|
||
Installation: | ||
|
||
Install node.js from http://nodejs.org | ||
|
||
Install Node's websocket package: | ||
$ npm install websocket | ||
|
||
Install the node-static package to serve static files: | ||
$ npm install node-static | ||
|
||
Usage: | ||
|
||
Run the Node server: | ||
$ node websocket-server.js | ||
|
||
Point two browsers at http://your-server-address:1337/. You'll be | ||
prompted to allow the use of your camera and microphone. | ||
|
||
One of the browsers clicks "Call" and the call should be set up. | ||
|
||
To close the call just reload the page. Like I said: this is a | ||
minimal demo. | ||
|
||
Debugging the Node Server: | ||
install https://github.com/node-inspector/node-inspector | ||
run the node app in debug mode (will stop at the first line) | ||
$ node --debug-brk websocket-server.js | ||
then in another terminal | ||
$ node node_modules/node-inspector/bin/inspector.js | ||
- or - | ||
$ node_modules/.bin/node-inspector | ||
open chrome to http://127.0.0.1:8080/debug?port=5858 | ||
step once to go to the first line of the program |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* MIT License: https://webrtc-experiment.appspot.com/licence/ */ | ||
|
||
var call = function (config) { | ||
var | ||
peerConnection = PeerConnection(makePeerConfig()), | ||
webSocket = new WebSocket('ws://' + document.location.host + '/'); | ||
|
||
// configure the signalling WebSocket | ||
webSocket.onmessage = function (event) { | ||
console.log("received a message: " + event.data); | ||
onIncomingMessage(JSON.parse(event.data)); | ||
}; | ||
webSocket.push = webSocket.send; | ||
webSocket.send = function (data) { | ||
webSocket.push(JSON.stringify(data)); | ||
}; | ||
|
||
function onIncomingMessage(response) { | ||
// the other client has sent me an offer SDP | ||
if (response.offerSDP) { | ||
console.log("received offerSDP " + response.offerSDP + ", will answer"); | ||
peerConnection.addStream(config.localStream); | ||
peerConnection.createAnswer(response.offerSDP, function (sdp) { | ||
console.log("sending answer SDP"); | ||
webSocket.send({ | ||
answerSDP: sdp | ||
}); | ||
}); | ||
} | ||
|
||
// the other client has sent me an answer SDP | ||
if (response.answerSDP) { | ||
peerConnection.setRemoteDescription(response.answerSDP); | ||
} | ||
|
||
// the other client has sent me an ICE candidate | ||
if (response.candidate) { | ||
console.log("got a candidate message, passing to RTCPeerConnection"); | ||
peerConnection.addICECandidate({ | ||
sdpMLineIndex: response.candidate.sdpMLineIndex, | ||
candidate: response.candidate.candidate | ||
}); | ||
} | ||
} | ||
|
||
// PeerConnection.js's options structure | ||
function makePeerConfig() { | ||
return { | ||
onicecandidate: function (candidate) { | ||
console.log("onICE"); | ||
webSocket.send({ | ||
candidate: { | ||
sdpMLineIndex: candidate.sdpMLineIndex, | ||
candidate: candidate.candidate | ||
} | ||
}); | ||
}, | ||
onaddstream: function (stream) { | ||
console.log("onRemoteStream"); | ||
config.video['src'] = URL.createObjectURL(stream); | ||
} | ||
}; | ||
} | ||
|
||
return { | ||
initiateCall: function(localStream) { | ||
// attach the stream to the peer connection | ||
peerConnection.addStream(localStream); | ||
// create the offer SDP and send it when it's ready | ||
peerConnection.createOffer(function (sdp) { | ||
console.log("sending offer SDP"); | ||
webSocket.send({ | ||
offerSDP: sdp | ||
}) | ||
}); | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Example WebRTC Point-to-point Video</title> | ||
<style> | ||
#video { | ||
position: relative; | ||
} | ||
#local-video { | ||
left: 0; | ||
position: absolute; | ||
top: 0; | ||
z-index: 1; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<h1>Example WebRTC Point-to-point Video</h1> | ||
<table class="visible"> | ||
<tr><td><button id="call" onClick="callPeer.initiateCall(config.localStream)">Call</button></td></tr> | ||
</table> | ||
<div id="video"> | ||
<video id="remote-video" autoplay="true" controls="true" width="480" height="360"></video> | ||
<video id="local-video" autoplay="true" controls="true" muted="true" width="160" height="120"></video> | ||
</div> | ||
<script src="PeerConnection.js" type="text/javascript"></script> | ||
<script src="call.js" type="text/javascript"></script> | ||
<script type="text/javascript"> | ||
// temporary kludge to paper over browser differences | ||
navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; | ||
|
||
var config = { | ||
video: document.getElementById('remote-video'), | ||
}; | ||
|
||
navigator.getUserMedia({ | ||
audio: true, | ||
video: true | ||
}, | ||
function (localStream) { | ||
video = document.getElementById('local-video'); | ||
video['src'] = URL.createObjectURL(localStream); | ||
config.localStream = localStream; | ||
}, | ||
function (e) { console.error(e); } | ||
); | ||
|
||
var callPeer = call(config); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// adapted from: | ||
// http://blog.gingertech.net/2012/06/04/video-conferencing-in-html5-webrtc-via-web-sockets/ | ||
|
||
var WebSocketServer = require('websocket').server; | ||
var http = require('http'); | ||
var static = require('node-static'); | ||
var clients = []; | ||
|
||
var staticServer = new static.Server('.'); | ||
|
||
// set up node-static to serve static files in this directory, | ||
// i.e., http://localhost:1337/index.html | ||
var server = http.createServer(function(request, response) { | ||
request.addListener('end', function() { | ||
staticServer.serve(request, response); | ||
}).resume(); | ||
}); | ||
server.listen(1337, function() { | ||
console.log((new Date()) + " Server is listening on port 1337"); | ||
}); | ||
|
||
// create the server | ||
wsServer = new WebSocketServer({ | ||
httpServer: server | ||
}); | ||
|
||
function sendCallback(err) { | ||
if (err) console.error((new Date()) + "send() error: " + err); | ||
} | ||
|
||
// This callback function is called every time someone | ||
// tries to connect to the WebSocket server | ||
wsServer.on('request', function(request) { | ||
console.log((new Date()) + ' Connection from origin ' + request.origin + '.'); | ||
var connection = request.accept(null, request.origin); | ||
console.log((new Date()) + ' Connection remoteAddress ' + connection.remoteAddress); | ||
clients.push(connection); | ||
|
||
// This is the most important callback for us, we'll handle | ||
// all messages from users here. | ||
connection.on('message', function(message) { | ||
if (message.type === 'utf8') { | ||
// process WebSocket message | ||
console.log((new Date()) + ' Received Message ' + message.utf8Data); | ||
// broadcast message to all connected clients | ||
clients.forEach(function (outputConnection) { | ||
if (outputConnection != connection) { | ||
outputConnection.send(message.utf8Data, sendCallback); | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
connection.on('close', function(connection) { | ||
// close user connection | ||
console.log((new Date()) + " Peer disconnected."); | ||
for (var i = 0; i < clients.length; i++) { | ||
if (!clients[i].connected) | ||
clients.remove(i); | ||
} | ||
}); | ||
}); | ||
|
||
// Array Remove - By John Resig (MIT Licensed) | ||
Array.prototype.remove = function(from, to) { | ||
var rest = this.slice((to || from) + 1 || this.length); | ||
this.length = from < 0 ? this.length + from : from; | ||
return this.push.apply(this, rest); | ||
}; |