Created
June 25, 2015 22:38
-
-
Save palfrey/947f6ec7f456182e2917 to your computer and use it in GitHub Desktop.
Dalek Video files
This file contains hidden or 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
| "use strict"; | |
| var selfEasyrtcid = ""; | |
| var otherClients = []; | |
| var state = "observer"; | |
| var calling = false; | |
| function getClient(rtcid) { | |
| if (!_.has(otherClients, rtcid)) { | |
| otherClients[rtcid] = {"contacted" : null, state : null, id: rtcid, feed: null}; | |
| console.log("OtherClients (after add): " + _.keys(otherClients)); | |
| } | |
| return otherClients[rtcid]; | |
| } | |
| function contactClient(key) { | |
| var client = getClient(key); | |
| if (client.contacted == null) { | |
| console.log(key + " is a new client"); | |
| } | |
| if (client.contacted != state) { | |
| console.log("Informing " + key + " of our state"); | |
| easyrtc.sendDataWS(key, 'query', state, function(ackMesg) { | |
| if( ackMesg.msgType === 'error' ) { | |
| console.log(ackMesg.msgData.errorText); | |
| } | |
| else { | |
| client.contacted = state; | |
| } | |
| }); | |
| } | |
| } | |
| function getPilot() { | |
| var pilots = _.filter(_.values(otherClients), function(client) { | |
| //console.log("client: " + client); | |
| return client.state == "pilot"; | |
| }); | |
| var count = _.size(pilots); | |
| console.log("otherClients: " + _.keys(otherClients)); | |
| console.log(pilots); | |
| console.log("Got " + count + " pilots"); | |
| if (count == 0) { | |
| if (state == "pilot") { | |
| return {}; // self | |
| } | |
| else { | |
| return null; | |
| } | |
| } | |
| if (count == 1 && state != "pilot") { | |
| return pilots[0]; | |
| } | |
| return null; | |
| } | |
| function setup() { | |
| //easyrtc.enableDebug(true); | |
| easyrtc.setOnError( function(errEvent) { console.log(errEvent.errorText);}); | |
| var localFilter = easyrtc.buildLocalSdpFilter( { | |
| audioRecvBitrate:20, videoRecvBitrate:30 | |
| }); | |
| var remoteFilter = easyrtc.buildRemoteSdpFilter({ | |
| audioSendBitrate: 20, videoSendBitrate:30 | |
| }); | |
| easyrtc.setSdpFilters(localFilter, remoteFilter); | |
| easyrtc.setRoomOccupantListener(otherClientsCallback); | |
| /*easyrtc.enableAudio(false); | |
| easyrtc.enableVideo(false); | |
| easyrtc.setAutoInitUserMedia(false);*/ | |
| easyrtc.setStreamAcceptor( function(callerEasyrtcid, stream) { | |
| var client = getClient(callerEasyrtcid); | |
| console.log("Incoming stream from "+ callerEasyrtcid + " who is a " + client.state); | |
| var video; | |
| if (client.state == "pilot") { | |
| video = document.getElementById('pilotView'); | |
| $("#pilotControls").hide(); | |
| $("#pilotView").show(); | |
| } | |
| else if (client.state == "dalek") | |
| video = document.getElementById('dalekView'); | |
| else { | |
| return; | |
| } | |
| easyrtc.setVideoObjectSrc(video, stream); | |
| }); | |
| easyrtc.setAcceptChecker( function(callerEasyrtcid, acceptor){ | |
| var client = getClient(callerEasyrtcid); | |
| console.log("Incoming call from "+ callerEasyrtcid + " who is a " + client.state); | |
| acceptor(true); | |
| }) | |
| easyrtc.setOnStreamClosed( function (callerEasyrtcid) { | |
| console.log("Closed stream from " + callerEasyrtcid); | |
| easyrtc.setVideoObjectSrc(document.getElementById('pilotView'), ""); | |
| }); | |
| easyrtc.setPeerListener( function(sendersEasyrtcid, msgType, msgData, targeting) { | |
| if( msgType === 'query' ) { | |
| console.log( sendersEasyrtcid + ' is a ' + msgData); | |
| getClient(sendersEasyrtcid).state = msgData; | |
| contactClient(sendersEasyrtcid); | |
| if (!calling && msgData == "pilot" && (state != "dalek")) {//|| $("#pilotView").is(":hidden"))) { | |
| console.log("Calling " + sendersEasyrtcid); | |
| calling = true; | |
| easyrtc.call( | |
| sendersEasyrtcid, | |
| function(easyrtcid) { console.log("completed call to " + easyrtcid);}, | |
| function(errorCode, errorText) { calling = false; console.log("err:" + errorText);}, | |
| function(accepted, bywho) { | |
| calling = false; | |
| console.log((accepted?"accepted":"rejected")+ " by " + bywho); | |
| $("#pilotControls").hide(); | |
| $("#pilotView").show(); | |
| } | |
| ); | |
| } | |
| if (!calling && msgData == "dalek") { | |
| console.log("Calling " + sendersEasyrtcid); | |
| calling = true; | |
| easyrtc.call( | |
| sendersEasyrtcid, | |
| function(easyrtcid) { calling=false; console.log("completed call to " + easyrtcid);}, | |
| function(errorCode, errorText) { console.log("err:" + errorText);}, | |
| function(accepted, bywho) { | |
| calling = false; | |
| console.log((accepted?"accepted":"rejected")+ " by " + bywho); | |
| } | |
| ); | |
| } | |
| } | |
| else { | |
| console.log("Got a " + msgType + " from " + sendersEasyrtcid); | |
| } | |
| }); | |
| easyrtc.setServerListener( function(msgType, msgData, targeting){ | |
| console.log("The Server sent the following message " + JSON.stringify(msgData)); | |
| }); | |
| //$(".bordered").height(240).width(320); | |
| $("#pilotControls").hide(); | |
| $("#dalekControls").hide(); | |
| } | |
| function connect() { | |
| setup(); | |
| easyrtc.initMediaSource( | |
| function(){ | |
| easyrtc.connect("Dalek", loginSuccess, loginFailure); | |
| },loginFailure); | |
| } | |
| function dalek() { | |
| setup(); | |
| state = "dalek"; | |
| easyrtc.setUsername("Dalek"); | |
| easyrtc.initMediaSource( | |
| function(){ // success callback | |
| easyrtc.connect("Dalek", loginSuccess, loginFailure); | |
| }, | |
| loginFailure | |
| ); | |
| } | |
| function pilotMode() { | |
| state = "pilot"; | |
| console.log("Setting state to pilot"); | |
| easyrtc.disconnect(); | |
| easyrtc.myEasyrtcid = null; // clear so we can set username again | |
| /*easyrtc.enableAudio(true); | |
| easyrtc.enableVideo(true);*/ | |
| easyrtc.initMediaSource( | |
| function(){ | |
| $("#pilotControls").hide(); | |
| $("#pilotView").show(); | |
| $("#dalekControls").show(); | |
| $("#pilotView").prop('muted', true); | |
| var selfVideo = document.getElementById("pilotView"); | |
| easyrtc.setVideoObjectSrc(selfVideo, easyrtc.getLocalStream()); | |
| easyrtc.connect("Dalek", loginSuccess, loginFailure); | |
| /*_.each(_.keys(otherClients), function(key) { | |
| contactClient(key); | |
| });*/ | |
| }, | |
| loginFailure | |
| ); | |
| } | |
| function otherClientsCallback (roomName, data) { | |
| var oldKeys = _.keys(otherClients); | |
| console.log("Clients: " + _.keys(data)); | |
| console.log("Old keys: " + oldKeys); | |
| for(var key in data) { | |
| contactClient(key); | |
| } | |
| _.each(oldKeys, function(key) { | |
| if (!_.has(data, key)) { | |
| console.log("Can't find " + key + " any more"); | |
| delete otherClients[key]; | |
| } | |
| }); | |
| var pilot = getPilot(); | |
| if (pilot == null) { | |
| $("#pilotControls").show(); | |
| $("#pilotView").hide(); | |
| } | |
| } | |
| function loginSuccess(easyrtcid) { | |
| selfEasyrtcid = easyrtcid; | |
| console.log("Logged in as " + easyrtcid); | |
| var iam = document.getElementById("iam"); | |
| if (iam != null) | |
| iam.innerHTML = "I am " + easyrtc.cleanId(easyrtcid); | |
| } | |
| function loginFailure(errorCode, message) { | |
| easyrtc.showError(errorCode, message); | |
| } | |
| function sparkSetup() { | |
| $("#spark-failure").hide(); | |
| $("#spark-connecting").show(); | |
| var token = 'SPARK_TOKEN_FROM_TOKENS_PY'; | |
| var dalekRemote = "SPARK_CORE_ID"; | |
| var relays = []; | |
| spark.on('login', function() { | |
| console.log("Logged in to Spark") | |
| spark.getDevice(dalekRemote, function(err, device) { | |
| console.log(device); | |
| $("#spark-connecting").hide(); | |
| if (!device.connected) { | |
| $("#spark-failure").show(); | |
| } | |
| var on = function(i) { | |
| console.log("D" + i + ",HIGH"); | |
| device.callFunction('digitalwrite', 'D' + i +',HIGH'); | |
| }; | |
| var off = function(i) { | |
| console.log("D" + i + ",LOW"); | |
| device.callFunction('digitalwrite', 'D' + i + ',LOW'); | |
| }; | |
| // 1 - forward left | |
| // 0 - forward right | |
| // 2 - backwards right | |
| // 3 - backwards left | |
| $('#forward').mousedown(function() { | |
| on(0); | |
| on(1); | |
| }).mouseup(function() { | |
| off(0); | |
| off(1); | |
| }); | |
| $('#backwards').mousedown(function() { | |
| on(2); | |
| on(3); | |
| }).mouseup(function() { | |
| off(2); | |
| off(3); | |
| }); | |
| $('#left').mousedown(function() { | |
| on(1); | |
| on(3); | |
| }).mouseup(function() { | |
| off(1); | |
| off(3); | |
| }); | |
| $('#right').mousedown(function() { | |
| on(0); | |
| on(2); | |
| }).mouseup(function() { | |
| off(0); | |
| off(2); | |
| }); | |
| $('#allstop').click(function() { | |
| for (var i=0;i<4;i++) { | |
| off(i); | |
| } | |
| }) | |
| }); | |
| }); | |
| spark.login({ accessToken: token }); | |
| } |
This file contains hidden or 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
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!--skip--> | |
| <title>Dalek Chat</title> | |
| <!--show--> | |
| <!-- Assumes global locations for socket.io.js and easyrtc.js --> | |
| <script src="/socket.io/socket.io.js"></script> | |
| <script type="text/javascript" src="/easyrtc/easyrtc.js"></script> | |
| <script type="text/javascript" src="/easyrtc/labs/easyrtc_rates.js"></script> | |
| <script type="text/javascript" src="dalek.js"></script> | |
| <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script> | |
| <script type="text/javascript" src="http://underscorejs.org/underscore-min.js"></script> | |
| <script type="text/javascript" src="screenfull.js"></script> | |
| <script src="//cdn.jsdelivr.net/sparkjs/0.4.1/spark.min.js"></script> | |
| <!-- Latest compiled and minified CSS --> | |
| <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> | |
| <!-- Optional theme --> | |
| <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css"> | |
| <!-- Latest compiled and minified JavaScript --> | |
| <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> | |
| <style> | |
| .bordered { | |
| border:1px solid black; | |
| display: inline-block; | |
| } | |
| video { | |
| margin-top: 4px; /* weird additional padding */ | |
| } | |
| </style> | |
| <script type="text/javascript"> | |
| $( document ).ready(function() { | |
| document.getElementById('button').addEventListener('click', function () { | |
| if (screenfull.enabled) { | |
| screenfull.request(); | |
| } else { | |
| // Ignore or do something else | |
| } | |
| }); | |
| $( window ).resize(function() { | |
| console.log("Window size: " + window.innerWidth + " x " + window.innerHeight); | |
| $("#pilotView") | |
| .height(window.innerHeight - 8) | |
| .width(window.innerWidth - 8); | |
| }); | |
| document.addEventListener(screenfull.raw.fullscreenchange, function () { | |
| if (screenfull.isFullscreen) { | |
| $("#button").hide(); | |
| } | |
| else { | |
| $("#button").show(); | |
| } | |
| }); | |
| }); | |
| </script> | |
| </head> | |
| <body onload="connect();sparkSetup();"> | |
| <!--hide--> | |
| <div class="container-fluid"> | |
| <!-- Main Content --> | |
| <h1>Dalek Chat</h1> | |
| <!--show--> | |
| <a class="btn btn-default" href="#" role="button" id="button">Fullscreen</a> | |
| <div class="row"> | |
| <div class="col-xs-12" id="connectControls"> | |
| <div id="iam">Not yet connected...</div> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div class="col-xs-6"> | |
| <video autoplay="autoplay" id="dalekView" class="bordered" width="100%"></video> | |
| </div> | |
| <div class="col-xs-6"> | |
| <div id="pilotControls" class="bordered" hidden> | |
| No Dalek pilot currently. <a class="btn btn-default" href="#" role="button" onclick="pilotMode();">Become the Dalek pilot</a> | |
| </div> | |
| </div> | |
| <div class="col-xs-6"> | |
| <video autoplay="autoplay" id="pilotView" class="bordered" width="100%"></video> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div class="col-md-6 col-md-offset-6" id="dalekControls"> | |
| <div class="alert alert-danger" role="alert" id="spark-failure">Can't connect to the Dalek controls, so none of these buttons will do anything</div> | |
| <div class="alert alert-warning" role="alert" id="spark-connecting">Connecting to Dalek controls (nothing below here will work until this is done)</div> | |
| <button class="btn btn-default" type="submit" id="forward"><span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span></button> | |
| <button class="btn btn-default" type="submit" id="backwards"><span class="glyphicon glyphicon-arrow-down" aria-hidden="true"></span></button> | |
| <button class="btn btn-default" type="submit" id="left"><span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span></button> | |
| <button class="btn btn-default" type="submit" id="right"><span class="glyphicon glyphicon-arrow-right" aria-hidden="true"></span></button> | |
| <button class="btn btn-default" type="submit" id="allstop">All Stop</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!--show--> | |
| </body> | |
| </html> |
This file contains hidden or 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
| { | |
| "name" : "dalek_server", | |
| "version" : "0.1", | |
| "author" : "Tom Parker <palfrey@lshift.net>", | |
| "description" : "Dalek!", | |
| "private" : true, | |
| "scripts": { | |
| "start" : "node server.js" | |
| }, | |
| "dependencies" : { | |
| "easyrtc" : "1.0.x", | |
| "express" : "*", | |
| "socket.io" : "0.9.x", | |
| "ssl-root-cas": "^1.1.4" | |
| }, | |
| "engines": { | |
| "node" : ">=0.8" | |
| } | |
| } |
This file contains hidden or 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
| (function () { | |
| 'use strict'; | |
| var isCommonjs = typeof module !== 'undefined' && module.exports; | |
| var keyboardAllowed = typeof Element !== 'undefined' && 'ALLOW_KEYBOARD_INPUT' in Element; | |
| var fn = (function () { | |
| var val; | |
| var valLength; | |
| var fnMap = [ | |
| [ | |
| 'requestFullscreen', | |
| 'exitFullscreen', | |
| 'fullscreenElement', | |
| 'fullscreenEnabled', | |
| 'fullscreenchange', | |
| 'fullscreenerror' | |
| ], | |
| // new WebKit | |
| [ | |
| 'webkitRequestFullscreen', | |
| 'webkitExitFullscreen', | |
| 'webkitFullscreenElement', | |
| 'webkitFullscreenEnabled', | |
| 'webkitfullscreenchange', | |
| 'webkitfullscreenerror' | |
| ], | |
| // old WebKit (Safari 5.1) | |
| [ | |
| 'webkitRequestFullScreen', | |
| 'webkitCancelFullScreen', | |
| 'webkitCurrentFullScreenElement', | |
| 'webkitCancelFullScreen', | |
| 'webkitfullscreenchange', | |
| 'webkitfullscreenerror' | |
| ], | |
| [ | |
| 'mozRequestFullScreen', | |
| 'mozCancelFullScreen', | |
| 'mozFullScreenElement', | |
| 'mozFullScreenEnabled', | |
| 'mozfullscreenchange', | |
| 'mozfullscreenerror' | |
| ], | |
| [ | |
| 'msRequestFullscreen', | |
| 'msExitFullscreen', | |
| 'msFullscreenElement', | |
| 'msFullscreenEnabled', | |
| 'MSFullscreenChange', | |
| 'MSFullscreenError' | |
| ] | |
| ]; | |
| var i = 0; | |
| var l = fnMap.length; | |
| var ret = {}; | |
| for (; i < l; i++) { | |
| val = fnMap[i]; | |
| if (val && val[1] in document) { | |
| for (i = 0, valLength = val.length; i < valLength; i++) { | |
| ret[fnMap[0][i]] = val[i]; | |
| } | |
| return ret; | |
| } | |
| } | |
| return false; | |
| })(); | |
| var screenfull = { | |
| request: function (elem) { | |
| var request = fn.requestFullscreen; | |
| elem = elem || document.documentElement; | |
| // Work around Safari 5.1 bug: reports support for | |
| // keyboard in fullscreen even though it doesn't. | |
| // Browser sniffing, since the alternative with | |
| // setTimeout is even worse. | |
| if (/5\.1[\.\d]* Safari/.test(navigator.userAgent)) { | |
| elem[request](); | |
| } else { | |
| elem[request](keyboardAllowed && Element.ALLOW_KEYBOARD_INPUT); | |
| } | |
| }, | |
| exit: function () { | |
| document[fn.exitFullscreen](); | |
| }, | |
| toggle: function (elem) { | |
| if (this.isFullscreen) { | |
| this.exit(); | |
| } else { | |
| this.request(elem); | |
| } | |
| }, | |
| raw: fn | |
| }; | |
| if (!fn) { | |
| if (isCommonjs) { | |
| module.exports = false; | |
| } else { | |
| window.screenfull = false; | |
| } | |
| return; | |
| } | |
| Object.defineProperties(screenfull, { | |
| isFullscreen: { | |
| get: function () { | |
| return !!document[fn.fullscreenElement]; | |
| } | |
| }, | |
| element: { | |
| enumerable: true, | |
| get: function () { | |
| return document[fn.fullscreenElement]; | |
| } | |
| }, | |
| enabled: { | |
| enumerable: true, | |
| get: function () { | |
| // Coerce to boolean in case of old WebKit | |
| return !!document[fn.fullscreenEnabled]; | |
| } | |
| } | |
| }); | |
| if (isCommonjs) { | |
| module.exports = screenfull; | |
| } else { | |
| window.screenfull = screenfull; | |
| } | |
| })(); |
This file contains hidden or 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
| // Load required modules | |
| var http = require("http"); // http server core module | |
| var express = require("express"); // web framework external module | |
| var io = require("socket.io"); // web socket external module | |
| var easyrtc = require("easyrtc"); // EasyRTC external module | |
| var https = require('https'); | |
| var path = require('path'); | |
| var fs = require('fs'); | |
| // Setup and configure Express http server. Expect a subfolder called "static" to be the web root. | |
| var httpsApp = express(); | |
| httpsApp.use(express.static(__dirname + "/static/")); | |
| require('ssl-root-cas') | |
| .inject() | |
| .addFile(path.join(__dirname, 'my-private-root-ca.crt.pem')); | |
| options = { | |
| key: fs.readFileSync(path.join(__dirname, 'my-server.key.pem')) | |
| , cert: fs.readFileSync(path.join(__dirname, 'my-server.crt.pem')) | |
| }; | |
| // Start Express http server on port 8080 | |
| var httpsServer = https.createServer(options, httpsApp).listen(8081); | |
| var httpApp = express(); | |
| httpApp.get(/^(.+)$/, function(req, res) { | |
| var contents = fs.readFileSync('static/http.html').toString(); | |
| contents = contents.replace("$ADDRESS", req.hostname); | |
| res.send(contents); | |
| }); | |
| http.createServer(httpApp).listen(8080); | |
| // Start Socket.io so it attaches itself to Express server | |
| var socketServer = io.listen(httpsServer, {"log level":1}); | |
| var myIceServers = [ | |
| {"url":"stun:stun.l.google.com:19302"} | |
| ]; | |
| easyrtc.setOption("appIceServers", myIceServers); | |
| // Start EasyRTC server | |
| var rtc = easyrtc.listen(httpsApp, socketServer); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment