diff --git a/control/config.js b/control/config.js index d69deec..fef7398 100644 --- a/control/config.js +++ b/control/config.js @@ -4,8 +4,8 @@ const configFile = path.join(__dirname, '..', 'config.json') const defvals = { api: { - host: '0.0.0.0', - port: 7005, + host: '0.0.0.0', + port: 7005, mount: '/api' }, rtmp: { @@ -19,14 +19,26 @@ const defvals = { }, liquidsoap: { fallback: '', - bitrate: 2000, - entry: 'liq/view.liq' + entry: 'liq/view.liq', + output: { + bitrate: 2000, + width: 1280, + height: 720, + samplerate: 25 + } }, calendar: { googleKey: '', calendar: '', interval: 60, timeFrame: 120000, + schedule: { + width: 300, + height: 400, + background: 'rgba(0,126,255,0.8)', + font: 'sans-serif', + fontColor: '#fff' + } } } @@ -34,10 +46,13 @@ function getKeys (obj, vals) { let keys = {} for (let key in obj) { - if (key === 'rtmp') { + if (key === 'calendar') { + keys['calendar.width'] = vals.calendar.schedule.width + keys['calendar.height'] = vals.calendar.schedule.height + } else if (key === 'rtmp') { keys['rtmp.url'] = 'rtmp://' + vals.rtmp.host + vals.rtmp.mount keys['rtmp.key'] = vals.rtmp.key - } else if (typeof vals[key] == 'object') { + } else if (typeof vals[key] === 'object') { let ks = getKeys(defvals[key], vals[key]) for (let i in ks) { keys[key + '.' + i] = ks[i] diff --git a/control/index.js b/control/index.js index 2b6a8ff..9eb3afc 100644 --- a/control/index.js +++ b/control/index.js @@ -9,10 +9,15 @@ liq.start() let scheduler = new Scheduler(config.calendar) scheduler.startTimers() + scheduler.runner = function (event) { liq.queue(event.descriptor) } +scheduler.reload = function (calendar) { + liq.sendCommand('schedule.reload').catch((e) => console.error('Failed to reload schedule:', e.message)) +} + // User input handler rl.on('line', function (line) { let argv = line.split(' ') @@ -46,6 +51,19 @@ rl.on('line', function (line) { console.log('Refreshing scheduler..') scheduler.calendarFetch().catch((e) => console.error('Calendar fetch failed!', e.stack)) break + case 'reload': + console.log('Reloading configuration..') + config.read().then( + () => { + console.log('Configuration reloaded successfully.') + + // Restart scheduler + scheduler.stopTimers() + scheduler.startTimers() + }, + (e) => console.error('Configuration reload failed:', e.stack) + ) + break default: console.log('Unknown command.') } diff --git a/control/liquidsoap.js b/control/liquidsoap.js index 0b6ca00..fdff3a4 100644 --- a/control/liquidsoap.js +++ b/control/liquidsoap.js @@ -62,7 +62,7 @@ class Liquidsoap { queue (item) { if (typeof item !== 'object') item = [item] - + let q = [] for (let i in item) { q.push('queue.push smart:' + item[i]) diff --git a/control/schedule.js b/control/schedule.js index eed4965..2c35d02 100644 --- a/control/schedule.js +++ b/control/schedule.js @@ -18,16 +18,19 @@ function dateFormat (date, yr) { } class Drawer { - constructor (w, h) { - this.canvas = c.createCanvas(w, h) + constructor () { + this.canvas = c.createCanvas(config.calendar.schedule.width, config.calendar.schedule.height) this.ctx = this.canvas.getContext('2d') } - draw (cal) { + async draw (cal) { let ctx = this.ctx + let font = config.calendar.schedule.font + let fontColor = config.calendar.schedule.fontColor + ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) - ctx.fillStyle = 'rgba(0,126,255,0.8)' + ctx.fillStyle = config.calendar.schedule.background ctx.fillRect(5, 5, this.canvas.width - 10, this.canvas.height - 10) let added = 0 @@ -38,7 +41,7 @@ class Drawer { if (i > 5) break // Can't fit so many on here :P if (ev.eventStartTime < Date.now() || ev.eventEndTime < Date.now()) continue - ctx.fillStyle = '#fff' + ctx.fillStyle = fontColor let y = (i * 60) + 30 // Write event name @@ -47,16 +50,16 @@ class Drawer { evn = evn.substring(0, 14) + '…' } - ctx.font = '26px sans-serif' + ctx.font = '26px ' + font ctx.fillText(evn, 10, y) // Write event description - ctx.font = '16px sans-serif' + ctx.font = '16px ' + font ctx.fillText(ev.description, 10, y + 20) // Write event time let time = dateFormat(ev.eventStartTime) - ctx.font = '26px sans-serif' + ctx.font = '26px ' + font let tlen = ctx.measureText(time).width ctx.fillText(time, (this.canvas.width - 10) - tlen, y) @@ -70,12 +73,12 @@ class Drawer { } if (added === 0) { - ctx.fillStyle = '#fff' - ctx.font = '26px sans-serif' + ctx.fillStyle = fontColor + ctx.font = '26px ' + font ctx.fillText('No events scheduled.', 10, 35) } - this.toFile() + await this.toFile() } toFile () { @@ -96,17 +99,26 @@ class Calendar { this.config = conf - this.drawer = new Drawer(300, 400) + this.drawer = new Drawer() this.schedRunner = null + this.schedReload = null this.started = [] this.timers = { a: null, b: null, c: null } } + update () { + this.drawer.draw(this).then(() => { + setTimeout(() => { + this.schedReload && this.schedReload.call(this, this) + }, 1000) + }) + } + startTimers () { // Initial run this.calendarFetch().then( - (e) => this.drawer.draw(this), + (e) => this.update(), (e) => console.error('Calendar fetch failed!', e.stack) ) @@ -114,7 +126,7 @@ class Calendar { this.timers = { a: setInterval(() => this.calendarFetch().catch((e) => console.error('Calendar fetch failed!', e.stack)), this.config.interval * 1000), b: setInterval(() => this.runners(), 60 * 1000), - c: setInterval(() => this.drawer.draw(this), 120 * 1000) + c: setInterval(() => this.update(), 120 * 1000) } } @@ -198,6 +210,10 @@ class Calendar { this.schedRunner = runner } + set reload (reload) { + this.schedReload = reload + } + runners () { if (!this.schedRunner) return for (let i in this.events) { diff --git a/liq/view.liq b/liq/view.liq index 3c35901..1142fa5 100644 --- a/liq/view.liq +++ b/liq/view.liq @@ -8,16 +8,17 @@ set("server.telnet", true) set("server.telnet.bind_addr", confstr("control.host", "0.0.0.0")) set("server.telnet.port", confint("control.port", 7004)) -set("frame.video.width",1280) -set("frame.video.height",720) -set("frame.video.samplerate",25) +set("frame.video.width",confint("liquidsoap.output.width", 1280)) +set("frame.video.height",confint("liquidsoap.output.height", 720)) +set("frame.video.samplerate",confint("liquidsoap.output.samplerate", 25)) video_no_queue = single(confstr("liquidsoap.fallback",""), conservative=true) video_base = video.add_image( - width=300,height=400, + width=confint("calendar.width", 300),height=confint("calendar.height", 400), x=900,y=80, file="schedule.png", video_no_queue) +add_skip_command(command="schedule.reload", video_base) queue1 = request.equeue(id="queue", conservative=true, length=60., timeout=1000.) add_skip_command(command="queue.skip", queue1) @@ -30,5 +31,5 @@ source = on_end(delay=0., file_end_cleanup, source) output.rtmp.live( key=confstr("rtmp.key",""), url=confstr("rtmp.url","rtmp://localhost/live"), - video_bitrate=confint("liquidsoap.bitrate", 2000), + video_bitrate=confint("liquidsoap.output.bitrate", 2000), source)