Fix schedule image reload, more config options

This commit is contained in:
Evert Prants 2019-01-11 04:27:56 +02:00
parent 732ede8986
commit a6a51a24a6
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
5 changed files with 76 additions and 26 deletions

View File

@ -4,8 +4,8 @@ const configFile = path.join(__dirname, '..', 'config.json')
const defvals = { const defvals = {
api: { api: {
host: '0.0.0.0', host: '0.0.0.0',
port: 7005, port: 7005,
mount: '/api' mount: '/api'
}, },
rtmp: { rtmp: {
@ -19,14 +19,26 @@ const defvals = {
}, },
liquidsoap: { liquidsoap: {
fallback: '', fallback: '',
bitrate: 2000, entry: 'liq/view.liq',
entry: 'liq/view.liq' output: {
bitrate: 2000,
width: 1280,
height: 720,
samplerate: 25
}
}, },
calendar: { calendar: {
googleKey: '', googleKey: '',
calendar: '', calendar: '',
interval: 60, interval: 60,
timeFrame: 120000, 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 = {} let keys = {}
for (let key in obj) { 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.url'] = 'rtmp://' + vals.rtmp.host + vals.rtmp.mount
keys['rtmp.key'] = vals.rtmp.key 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]) let ks = getKeys(defvals[key], vals[key])
for (let i in ks) { for (let i in ks) {
keys[key + '.' + i] = ks[i] keys[key + '.' + i] = ks[i]

View File

@ -9,10 +9,15 @@ liq.start()
let scheduler = new Scheduler(config.calendar) let scheduler = new Scheduler(config.calendar)
scheduler.startTimers() scheduler.startTimers()
scheduler.runner = function (event) { scheduler.runner = function (event) {
liq.queue(event.descriptor) 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 // User input handler
rl.on('line', function (line) { rl.on('line', function (line) {
let argv = line.split(' ') let argv = line.split(' ')
@ -46,6 +51,19 @@ rl.on('line', function (line) {
console.log('Refreshing scheduler..') console.log('Refreshing scheduler..')
scheduler.calendarFetch().catch((e) => console.error('Calendar fetch failed!', e.stack)) scheduler.calendarFetch().catch((e) => console.error('Calendar fetch failed!', e.stack))
break 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: default:
console.log('Unknown command.') console.log('Unknown command.')
} }

View File

@ -62,7 +62,7 @@ class Liquidsoap {
queue (item) { queue (item) {
if (typeof item !== 'object') item = [item] if (typeof item !== 'object') item = [item]
let q = [] let q = []
for (let i in item) { for (let i in item) {
q.push('queue.push smart:' + item[i]) q.push('queue.push smart:' + item[i])

View File

@ -18,16 +18,19 @@ function dateFormat (date, yr) {
} }
class Drawer { class Drawer {
constructor (w, h) { constructor () {
this.canvas = c.createCanvas(w, h) this.canvas = c.createCanvas(config.calendar.schedule.width, config.calendar.schedule.height)
this.ctx = this.canvas.getContext('2d') this.ctx = this.canvas.getContext('2d')
} }
draw (cal) { async draw (cal) {
let ctx = this.ctx 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.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) ctx.fillRect(5, 5, this.canvas.width - 10, this.canvas.height - 10)
let added = 0 let added = 0
@ -38,7 +41,7 @@ class Drawer {
if (i > 5) break // Can't fit so many on here :P if (i > 5) break // Can't fit so many on here :P
if (ev.eventStartTime < Date.now() || ev.eventEndTime < Date.now()) continue if (ev.eventStartTime < Date.now() || ev.eventEndTime < Date.now()) continue
ctx.fillStyle = '#fff' ctx.fillStyle = fontColor
let y = (i * 60) + 30 let y = (i * 60) + 30
// Write event name // Write event name
@ -47,16 +50,16 @@ class Drawer {
evn = evn.substring(0, 14) + '…' evn = evn.substring(0, 14) + '…'
} }
ctx.font = '26px sans-serif' ctx.font = '26px ' + font
ctx.fillText(evn, 10, y) ctx.fillText(evn, 10, y)
// Write event description // Write event description
ctx.font = '16px sans-serif' ctx.font = '16px ' + font
ctx.fillText(ev.description, 10, y + 20) ctx.fillText(ev.description, 10, y + 20)
// Write event time // Write event time
let time = dateFormat(ev.eventStartTime) let time = dateFormat(ev.eventStartTime)
ctx.font = '26px sans-serif' ctx.font = '26px ' + font
let tlen = ctx.measureText(time).width let tlen = ctx.measureText(time).width
ctx.fillText(time, (this.canvas.width - 10) - tlen, y) ctx.fillText(time, (this.canvas.width - 10) - tlen, y)
@ -70,12 +73,12 @@ class Drawer {
} }
if (added === 0) { if (added === 0) {
ctx.fillStyle = '#fff' ctx.fillStyle = fontColor
ctx.font = '26px sans-serif' ctx.font = '26px ' + font
ctx.fillText('No events scheduled.', 10, 35) ctx.fillText('No events scheduled.', 10, 35)
} }
this.toFile() await this.toFile()
} }
toFile () { toFile () {
@ -96,17 +99,26 @@ class Calendar {
this.config = conf this.config = conf
this.drawer = new Drawer(300, 400) this.drawer = new Drawer()
this.schedRunner = null this.schedRunner = null
this.schedReload = null
this.started = [] this.started = []
this.timers = { a: null, b: null, c: null } this.timers = { a: null, b: null, c: null }
} }
update () {
this.drawer.draw(this).then(() => {
setTimeout(() => {
this.schedReload && this.schedReload.call(this, this)
}, 1000)
})
}
startTimers () { startTimers () {
// Initial run // Initial run
this.calendarFetch().then( this.calendarFetch().then(
(e) => this.drawer.draw(this), (e) => this.update(),
(e) => console.error('Calendar fetch failed!', e.stack) (e) => console.error('Calendar fetch failed!', e.stack)
) )
@ -114,7 +126,7 @@ class Calendar {
this.timers = { this.timers = {
a: setInterval(() => this.calendarFetch().catch((e) => console.error('Calendar fetch failed!', e.stack)), this.config.interval * 1000), a: setInterval(() => this.calendarFetch().catch((e) => console.error('Calendar fetch failed!', e.stack)), this.config.interval * 1000),
b: setInterval(() => this.runners(), 60 * 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 this.schedRunner = runner
} }
set reload (reload) {
this.schedReload = reload
}
runners () { runners () {
if (!this.schedRunner) return if (!this.schedRunner) return
for (let i in this.events) { for (let i in this.events) {

View File

@ -8,16 +8,17 @@ set("server.telnet", true)
set("server.telnet.bind_addr", confstr("control.host", "0.0.0.0")) set("server.telnet.bind_addr", confstr("control.host", "0.0.0.0"))
set("server.telnet.port", confint("control.port", 7004)) set("server.telnet.port", confint("control.port", 7004))
set("frame.video.width",1280) set("frame.video.width",confint("liquidsoap.output.width", 1280))
set("frame.video.height",720) set("frame.video.height",confint("liquidsoap.output.height", 720))
set("frame.video.samplerate",25) set("frame.video.samplerate",confint("liquidsoap.output.samplerate", 25))
video_no_queue = single(confstr("liquidsoap.fallback",""), conservative=true) video_no_queue = single(confstr("liquidsoap.fallback",""), conservative=true)
video_base = video.add_image( video_base = video.add_image(
width=300,height=400, width=confint("calendar.width", 300),height=confint("calendar.height", 400),
x=900,y=80, x=900,y=80,
file="schedule.png", file="schedule.png",
video_no_queue) video_no_queue)
add_skip_command(command="schedule.reload", video_base)
queue1 = request.equeue(id="queue", conservative=true, length=60., timeout=1000.) queue1 = request.equeue(id="queue", conservative=true, length=60., timeout=1000.)
add_skip_command(command="queue.skip", queue1) add_skip_command(command="queue.skip", queue1)
@ -30,5 +31,5 @@ source = on_end(delay=0., file_end_cleanup, source)
output.rtmp.live( output.rtmp.live(
key=confstr("rtmp.key",""), key=confstr("rtmp.key",""),
url=confstr("rtmp.url","rtmp://localhost/live"), url=confstr("rtmp.url","rtmp://localhost/live"),
video_bitrate=confint("liquidsoap.bitrate", 2000), video_bitrate=confint("liquidsoap.output.bitrate", 2000),
source) source)