diff --git a/app.js b/app.js index abad4ac..208eb25 100644 --- a/app.js +++ b/app.js @@ -75,7 +75,7 @@ config = Object.assign({ }, config) // Constants -const port = parseInt(config.Streaming.port) +const port = parseInt(config.Streaming.port, 10) const streamServer = config.Streaming.streamServer const streamServerHost = config.Streaming.serverHost const streamAppName = streamServer.match(/\/([\w-_]+)\/$/)[1] @@ -426,7 +426,7 @@ app.get('/', (req, res) => { // Dashboard app.get('/dashboard', authed, (req, res) => { const stream = cache.streamers[req.user.uuid] - res.render('dashboard.html', { stream: stream.key, server: 'rtmp://' + streamServerHost + '/live/' }) + res.render('dashboard.html', { server: 'rtmp://' + streamServerHost + '/live/' }) }) // Stats @@ -464,8 +464,8 @@ app.get('/dashboard/data', authed, async (req, res) => { key: stream.key, uuid: req.user.uuid, live: data.live_at != null, - live_at: new Date(parseInt(data.live_at)), - last_stream: new Date(parseInt(data.last_stream)) + live_at: new Date(parseInt(data.live_at, 10)), + last_stream: new Date(parseInt(data.last_stream, 10)) }) }) @@ -552,8 +552,8 @@ app.get('/api/channel/:name', async (req, res) => { delete data.user_uuid data.live = data.live_at != null - data.live_at = new Date(parseInt(data.live_at)) - data.last_stream = new Date(parseInt(data.last_stream)) + data.live_at = new Date(parseInt(data.live_at, 10)) + data.last_stream = new Date(parseInt(data.last_stream, 10)) data.links = links || [] data.viewers = Object.keys(cache.viewers[name] || {}).length data.source = streamServer + name + '.m3u8' diff --git a/package.json b/package.json index 17d26fe..b613936 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "watch": "webpack -w --mode=development --log-level=debug", + "watch": "webpack -w --mode=development", "build": "webpack --mode=production", "start": "node app.js", "serve": "NODE_ENV=\"development\" node app.js" diff --git a/src/css/player.css b/src/css/player.css index 2a6f5a4..65c27e5 100644 --- a/src/css/player.css +++ b/src/css/player.css @@ -66,6 +66,10 @@ body { width: 40px; cursor: pointer; padding: 4px; + text-align: center; +} +.controls .button:hover { + background-color: #005193; } .flex-divider { flex-grow: 1; diff --git a/src/dashboard.js b/src/dashboard.js index 20f2ed6..4c7feda 100644 --- a/src/dashboard.js +++ b/src/dashboard.js @@ -51,13 +51,18 @@ function updateLinkList (k) { }) } -function dashboard (k) { +function dashboard () { + let key; + let shown = false; $.get('/dashboard/data', function (res) { if (res.error) { window.location.href = '/' return } + // Set key from request + key = res.key + const fullURL = window.location.origin + '/watch/' + res.name const sourceURL = window.location.origin + '/live/' + res.name + '.m3u8' $('#myStream').attr('src', fullURL) @@ -66,12 +71,33 @@ function dashboard (k) { $('#stream_live').text(res.live ? 'Yes' : 'No') }) - $('#show_key').click(function (e) { - e.preventDefault() - $('#show_key').html(k) + $('#keybox').val('A'.repeat(36)) + $('#show_key').on('click', function (e) { + if (shown) { + $('#keybox').val('A'.repeat(36)) + $('#keybox').attr('type', 'password') + $(this).text('Reveal Key') + } else { + $('#keybox').val(key) + $('#keybox').attr('type', 'text') + $(this).text('Hide Key') + } + shown = !shown }) - $('.go-page').click(function (e) { + $('#copy_key').on('click', function (e) { + const i = $('').attr('value', key) + $(this).append(i) + $(this).attr('title', 'Click to copy to clipboard') + i[0].select() + i[0].setSelectionRange(0, key.length) + document.execCommand('copy') + $(i).remove() + $(this).text('Copied!') + setTimeout(() => $(this).text('Copy'), 1000) + }) + + $('.go-page').on('click', function (e) { const el = $(this) $('.go-page').removeClass('active') el.addClass('active') @@ -80,7 +106,7 @@ function dashboard (k) { }) }) - $('#add-link').submit(function (e) { + $('#add-link').on('submit', function (e) { e.preventDefault() const name = $('input[name="name"]').val() const url = $('input[name="url"]').val() diff --git a/src/index.js b/src/index.js index 55fa131..bf316d7 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ +/* global STREAM_KEY */ import 'bootstrap' import dashboard from './dashboard.js' -if (window.STREAM_KEY) dashboard(window.STREAM_KEY) +if (window.location.pathname.startsWith('/dashboard')) dashboard() diff --git a/src/player.js b/src/player.js index ce172b7..36e5d41 100644 --- a/src/player.js +++ b/src/player.js @@ -32,26 +32,6 @@ let errored = false let live = false let ws -function GET (url, istext) { - return new Promise((resolve, reject) => { - var xmlHttp = new XMLHttpRequest() - - xmlHttp.onreadystatechange = function () { - if (xmlHttp.readyState === 4 && xmlHttp.status === 200) { - resolve(xmlHttp.responseText) - } else if (xmlHttp.readyState === 4 && xmlHttp.status >= 400) { - const err = new Error(xmlHttp.status) - err.request = xmlHttp - reject(err) - } - } - - xmlHttp.open('GET', url, true) - istext && (xmlHttp.responseType = 'text') - xmlHttp.send(null) - }) -} - function clampAddition (val) { let volume = vid.volume @@ -391,6 +371,7 @@ function updateLinks (srcs) { if (!links) { links = document.createElement('div') links.className = 'right button' + links.setAttribute('title', 'Links') links.id = 'links' links.innerHTML = '' overlay.getElementsByClassName('controls')[0].insertBefore(links, fullscreenbtn) @@ -431,22 +412,23 @@ function updateLinks (srcs) { } function getStreamStatus () { - GET('/api/channel/' + STREAM_NAME).then((data) => { - const jd = JSON.parse(data) - if (jd.error) { + fetch('/api/channel/' + STREAM_NAME) + .then(data => data.json()) + .then((jd) => { + if (jd.error) { + errored = true + return alert(jd.error) + } + + if (jd.links) updateLinks(jd.links) + if (ws) ws.send('viewers ' + STREAM_NAME) + + if (jd.live && !vidReady) loadSource() + liveStatus(jd.live) + }, (e) => { errored = true - return alert(jd.error) - } - - if (jd.links) updateLinks(jd.links) - if (ws) ws.send('viewers ' + STREAM_NAME) - - if (jd.live && !vidReady) loadSource() - liveStatus(jd.live) - }, (e) => { - errored = true - liveStatus(false) - }) + liveStatus(false) + }) if (!errored) setTimeout(getStreamStatus, 8000) } diff --git a/templates/dashboard.html b/templates/dashboard.html index 21253cd..e719fd7 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -1,9 +1,6 @@ - + - @@ -47,6 +44,7 @@ +

Information

@@ -67,15 +65,6 @@
-
-
- -
-
- Show Stream Key -
-
-
@@ -93,6 +82,17 @@
+ +
+
+ +
+
+ + + +
+

Metrics

diff --git a/templates/index.html b/templates/index.html index 3c21857..3bbdb40 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,5 +1,5 @@ - + diff --git a/templates/player.html b/templates/player.html index c263abb..0ca7ee1 100644 --- a/templates/player.html +++ b/templates/player.html @@ -1,5 +1,5 @@ - + IcyTV - {{ name }} @@ -20,19 +20,27 @@
offline
- +
-
-
+
+ +
+
0:00
-
-
+
+ +
+
+ +
diff --git a/webpack.config.js b/webpack.config.js index ad1a3b6..2158821 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -16,8 +16,9 @@ module.exports = { plugins: [ new CopyPlugin({ patterns: [{ - from: 'src/css/*.css', - to: 'css' + from: '*', + to: 'css', + context: 'src/css/' }, { from: 'node_modules/bootstrap/dist/css/bootstrap.min.css',