diff --git a/index.js b/index.js index 0b592fe..39426ea 100644 --- a/index.js +++ b/index.js @@ -41,15 +41,13 @@ io.on('connection', function(socket) { socket.join(room); log('Client ID ' + socket.id + ' created room ' + room); socket.emit('created', room, socket.id); - } else if (numClients === 2) { + } else { log('Client ID ' + socket.id + ' joined room ' + room); // io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready', room); socket.broadcast.emit('ready', room); - } else { // max two clients - socket.emit('full', room); } }); diff --git a/public/apps/2/README.md b/public/apps/2/README.md new file mode 100644 index 0000000..79f1c71 --- /dev/null +++ b/public/apps/2/README.md @@ -0,0 +1,12 @@ +## 1 - Polling app + +This is a simple app to convert a selfie to gif. You can share this gif using WebRTC. + +## Resource +- [1](https://hacks.mozilla.org/2013/07/the-making-of-face-to-gif/) + +## Exercise + +- Implement different CSS filters + - A complete list of CSS filters to be applied can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter). +- Implement filters on the streaming video and then capture the selfie diff --git a/public/apps/2/css/main.css b/public/apps/2/css/main.css new file mode 100644 index 0000000..73e8c0d --- /dev/null +++ b/public/apps/2/css/main.css @@ -0,0 +1,13 @@ +body { + font-family: sans-serif; +} + +canvas { + max-width: 100%; + width: 320px; +} + +video { + max-width: 100%; + width: 320px; +} diff --git a/public/apps/2/index.html b/public/apps/2/index.html new file mode 100644 index 0000000..4736f78 --- /dev/null +++ b/public/apps/2/index.html @@ -0,0 +1,28 @@ + + + + Polling + + + + +

Have you coded/worked with WebRTC?

+ +
+ Yes + No + +
+ +
+

Results

+
+
+ + + + + + + + diff --git a/public/apps/2/js/main.js b/public/apps/2/js/main.js new file mode 100644 index 0000000..1af5f6c --- /dev/null +++ b/public/apps/2/js/main.js @@ -0,0 +1,45 @@ +'use strict'; + +var configuration = null; +var peerConn; +var dataChannel; + +var trail = document.getElementById('trail'); +var sendBtn = document.getElementById('send'); +sendBtn.addEventListener('click', sendAnswer); +var isInitiator; +var room = window.location.hash.substring(1); +if (!room) { + room = window.location.hash = randomToken(); +} + +function getAnswer() { + const yes = document.getElementById("yes").checked; + const no = document.getElementById("no").checked; + if (yes) { return 'yes'; } + return 'no'; +} + +function sendAnswer() { + var answer = getAnswer(); + dataChannel.send(answer); +} + +function render(data) { + var p = document.createElement("p"); + p.innerHTML = data; + if (data === 'yes') { + p.style.color = 'green'; + } else { + p.style.color = 'red' + } + trail.appendChild(p); +} + +function randomToken() { + return Math.floor((1 + Math.random()) * 1e16).toString(16).substring(1); +} + +function logError(err) { + console.log(err.toString(), err); +} diff --git a/public/apps/2/js/peerConnection.js b/public/apps/2/js/peerConnection.js new file mode 100644 index 0000000..ebee0a9 --- /dev/null +++ b/public/apps/2/js/peerConnection.js @@ -0,0 +1,87 @@ +/**************************************************************************** +* WebRTC peer connection and data channel +****************************************************************************/ +function signalingMessageCallback(message) { + if (message.type === 'offer') { + console.log('Got offer. Sending answer to peer.'); + peerConn.setRemoteDescription(new RTCSessionDescription(message), function() {}, + logError); + peerConn.createAnswer(onLocalSessionCreated, logError); + + } else if (message.type === 'answer') { + console.log('Got answer.'); + peerConn.setRemoteDescription(new RTCSessionDescription(message), function() {}, + logError); + + } else if (message.type === 'candidate') { + peerConn.addIceCandidate(new RTCIceCandidate({ + candidate: message.candidate + })); + + } else if (message === 'bye') { + // TODO: cleanup RTC connection? + } +} + +function createPeerConnection(isInitiator, config) { + console.log('Creating Peer connection as initiator?', isInitiator, 'config:', + config); + peerConn = new RTCPeerConnection(config); + +// send any ice candidates to the other peer +peerConn.onicecandidate = function(event) { + console.log('icecandidate event:', event); + if (event.candidate) { + sendMessage({ + type: 'candidate', + label: event.candidate.sdpMLineIndex, + id: event.candidate.sdpMid, + candidate: event.candidate.candidate + }); + } else { + console.log('End of candidates.'); + } +}; + +if (isInitiator) { + console.log('Creating Data Channel'); + dataChannel = peerConn.createDataChannel('photos'); + onDataChannelCreated(dataChannel); + + console.log('Creating an offer'); + peerConn.createOffer(onLocalSessionCreated, logError); +} else { + peerConn.ondatachannel = function(event) { + console.log('ondatachannel:', event.channel); + dataChannel = event.channel; + onDataChannelCreated(dataChannel); + }; +} +} + +function onLocalSessionCreated(desc) { + console.log('local session created:', desc); + peerConn.setLocalDescription(desc, function() { + console.log('sending local desc:', peerConn.localDescription); + sendMessage(peerConn.localDescription); + }, logError); +} + +function onDataChannelCreated(channel) { + console.log('onDataChannelCreated:', channel); + + channel.onopen = function() { + console.log('CHANNEL opened!!!'); + }; + + channel.onmessage = receiveData(); +} + +function receiveData() { + var buf, count; + + return function onmessage(event) { + render(event.data); + return; + } + }; diff --git a/public/apps/2/js/signalingServer.js b/public/apps/2/js/signalingServer.js new file mode 100644 index 0000000..6d798f6 --- /dev/null +++ b/public/apps/2/js/signalingServer.js @@ -0,0 +1,42 @@ +var socket = io.connect(); + +socket.on('ipaddr', function(ipaddr) { + console.log('Server IP address is: ' + ipaddr); +}); + +socket.on('created', function(room, clientId) { + isInitiator = true; +}); + +socket.on('joined', function(room, clientId) { + isInitiator = false; + createPeerConnection(isInitiator, configuration); +}); + +socket.on('full', function(room) { + alert('Room ' + room + ' is full. We will create a new room for you.'); + window.location.hash = ''; + window.location.reload(); +}); + +socket.on('ready', function() { + createPeerConnection(isInitiator, configuration); +}); + +socket.on('log', function(array) { + console.log.apply(console, array); +}); + +socket.on('message', function(message) { + signalingMessageCallback(message); +}); + +socket.emit('create or join', room); + +if (location.hostname.match(/localhost|127\.0\.0/)) { + socket.emit('ipaddr'); +} + +function sendMessage(message) { + socket.emit('message', message); +}