From 047ae8de9db5984d7ff17a52217d02d87c9640d1 Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech Date: Thu, 3 Oct 2019 18:34:22 +0200 Subject: [PATCH] Previous tests --- work/index.html | 18 ------ work/index.js | 44 +++++++++++++++ work/js/main.js | 2 - work/lib/getIpAddresses.js | 20 +++++++ work/package.json | 9 +++ work/{ => public}/css/main.css | 3 +- work/public/favicon.ico | Bin 0 -> 31806 bytes work/public/index.html | 33 +++++++++++ work/{ => public}/js/lib/adapter.js | 0 work/public/js/main.js | 82 ++++++++++++++++++++++++++++ 10 files changed, 189 insertions(+), 22 deletions(-) delete mode 100644 work/index.html create mode 100644 work/index.js delete mode 100644 work/js/main.js create mode 100644 work/lib/getIpAddresses.js create mode 100644 work/package.json rename work/{ => public}/css/main.css (57%) create mode 100644 work/public/favicon.ico create mode 100644 work/public/index.html rename work/{ => public}/js/lib/adapter.js (100%) create mode 100644 work/public/js/main.js diff --git a/work/index.html b/work/index.html deleted file mode 100644 index 3ada2ba..0000000 --- a/work/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - Realtime communication with WebRTC - - - - - - - -

Realtime communication with WebRTC

- - - - diff --git a/work/index.js b/work/index.js new file mode 100644 index 0000000..5cc75d3 --- /dev/null +++ b/work/index.js @@ -0,0 +1,44 @@ +const nodeStatic = require('node-static') +const http = require('http') +const socketIO = require('socket.io') +const getIpAddresses = require('./lib/getIpAddresses') + +const clients = [] +const port = process.env.PORT || 3478 +const fileServer = new(nodeStatic.Server)('./public') + +const onServerStart = () => { + console.clear() + console.info( + [ + '', + ...getIpAddresses().map(addr => `http://${addr}:${port}`), + '', + ].join('\n'), + ) +} + +const app = http.createServer(function(req, res) { + fileServer.serve(req, res) +}).listen(port, onServerStart) +const io = socketIO.listen(app) + +const broadcastQueue = () => { + clients.forEach((client, index) => { + client.emit('queue', `${index+1}/${clients.length}`) + }) +} + +io.sockets.on('connection', (socket) => { + clients.push(socket) + console.log(`+ new connection (${clients.length})`) + broadcastQueue() + + socket.on('disconnect', function() { + const i = clients.indexOf(socket) + console.log(`- disconnected (#${i+1}/${clients.length})`) + clients.splice(i, 1) + + broadcastQueue() + }) +}) diff --git a/work/js/main.js b/work/js/main.js deleted file mode 100644 index eb109ab..0000000 --- a/work/js/main.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict'; - diff --git a/work/lib/getIpAddresses.js b/work/lib/getIpAddresses.js new file mode 100644 index 0000000..6a15f47 --- /dev/null +++ b/work/lib/getIpAddresses.js @@ -0,0 +1,20 @@ +let os = require('os') + +/** + * @returns {Array.} list of IPv4 of the server + */ +const getIpAddresses = () => { + let addresses = [] + let ifaces = os.networkInterfaces() + for (let dev in ifaces) { + ifaces[dev].forEach(function(details) { + if (details.family === 'IPv4' && details.address !== '127.0.0.1') { + addresses.push(details.address) + } + }) + } + + return addresses +} + +module.exports = getIpAddresses diff --git a/work/package.json b/work/package.json new file mode 100644 index 0000000..f77ba84 --- /dev/null +++ b/work/package.json @@ -0,0 +1,9 @@ +{ + "name": "webrtc-codelab", + "version": "0.0.1", + "description": "WebRTC codelab", + "dependencies": { + "node-static": "^0.7.11", + "socket.io": "^2.3.0" + } +} diff --git a/work/css/main.css b/work/public/css/main.css similarity index 57% rename from work/css/main.css rename to work/public/css/main.css index 8edd6b7..7153fe6 100644 --- a/work/css/main.css +++ b/work/public/css/main.css @@ -3,6 +3,5 @@ body { } video { - max-width: 100%; - width: 320px; + width: 100%; } diff --git a/work/public/favicon.ico b/work/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..68d529850c046b3e21024d313518cd661a3b4e54 GIT binary patch literal 31806 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 U$==VGfq{X+)78&qol`;+0B_>&x&QzG literal 0 HcmV?d00001 diff --git a/work/public/index.html b/work/public/index.html new file mode 100644 index 0000000..bdac9a3 --- /dev/null +++ b/work/public/index.html @@ -0,0 +1,33 @@ + + + + + + WebRTC Screen streaming + + + + + + + +

WebRTC Screen streaming

+

+ Status: +

+
+ + + +
+
+ + + + + + + + + + diff --git a/work/js/lib/adapter.js b/work/public/js/lib/adapter.js similarity index 100% rename from work/js/lib/adapter.js rename to work/public/js/lib/adapter.js diff --git a/work/public/js/main.js b/work/public/js/main.js new file mode 100644 index 0000000..935f164 --- /dev/null +++ b/work/public/js/main.js @@ -0,0 +1,82 @@ +const $video = document.querySelector('#video') +const $onBroadcastStart = document.querySelector('#onBroadcastStart') +const $onStop = document.querySelector('#onStop') + +let localStream +let peerConnection + +const socket = io.connect(); + +socket.emit('ping', 'hello world'); + +socket.on('queue', length => { + log(`Queued #${length}`) +}); + +const log = status => { + console.log(status) + document.querySelector('#status').textContent = status +} + +const startLocalStream = () => { + navigator.mediaDevices.getDisplayMedia({ + audio: false, + video: true + }) + .then((stream) => { + log('Received media stream') + localStream = stream + $video.srcObject = stream + }) + .catch((e) => { + console.log(e) + alert('error: ' + e.name) + }) +} + + +const onBroadcastStart = () => { + log('Starting local stream') + startLocalStream() +} + +const onStop = () => { + log('Stopping') + + if (localStream) { + localStream.getTracks().forEach(track => track.stop()) + } + + if (peerConnection) { + peerConnection.close() + peerConnection = null + } +} + +// WEB RTC + +const ontrack = function(event) { + $video.srcObject = event.streams[0]; + $onStop.disabled = false; +}; + +function createPeerConnection() { + try { + peerConnection = new RTCPeerConnection(null); + peerConnection.onicecandidate = onicecandidate; + peerConnection.ontrack = ontrack; + peerConnection.onremovestream = onremovestream; + console.log('Created RTCPeerConnnection'); + } catch (e) { + console.log('Failed to create PeerConnection, exception: ' + e.message); + alert('Cannot create RTCPeerConnection object.'); + return; + } +} + + +// bind buttons +$onBroadcastStart.onclick = onBroadcastStart +$onStop.onclick = onStop + +log('Ready') -- GitLab