icytv-liq/control/liquidsoap.js

119 lines
2.8 KiB
JavaScript

// Liquidsoap class
const path = require('path')
const net = require('net')
const spawn = require('child_process').spawn
const config = require(path.join(__dirname, 'config.js'))
const rootpath = path.join(__dirname, '..')
const csl = require(path.join(__dirname, 'console.js'))
function printProcessOutput (fn) {
return function (data) {
let str = data.toString().trim()
csl.rl.output.write('\x1b[2K\r')
fn.call(null, str)
csl.rl && csl.rl.prompt(true)
}
}
function sanitizeMetadata (meta) {
let final = {}
for (let key in meta) {
let value = meta[key]
if (!value) continue
if (value === 'true') value = true
if (value === 'false') value = false
if (value.match && value.match(/^\d+\/\d+\/\d+ \d+:\d+:\d+$/)) value = new Date(value)
if (!isNaN(parseFloat(value))) value = parseFloat(value)
if (key === 'start') value = new Date(value * 1000)
if (value.indexOf && value.indexOf('(dot)') !== -1) {
value = value.replace('(dot)', '.')
}
if (key.indexOf('-') !== -1) {
key = key.replace(/\-/g, '_')
}
final[key] = value
}
return final
}
class Liquidsoap {
constructor () {
this.running = false
this.meta = {}
}
set metadata (mdt) {
mdt = sanitizeMetadata(mdt)
mdt.is_fallback = (mdt.source && mdt.source === config.liquidsoap.fallback)
this.meta = mdt
}
get metadata () {
return this.meta
}
start () {
let pd = path.parse(config.liquidsoap.entry)
let proc = this.proc = spawn('liquidsoap', [pd.base], {cwd: path.join(rootpath, pd.dir)})
this.running = true
proc.stdout.on('data', printProcessOutput(csl.realConsoleLog))
proc.stderr.on('data', printProcessOutput(csl.realConsoleError))
proc.on('close', () => {
this.running = false
})
}
stop () {
if (this.running && this.proc) {
this.proc.kill()
}
}
async sendCommand (msg) {
if (!this.running) throw new Error('Process is not running.')
let client = net.connect(config.control.port, config.control.host)
return new Promise((resolve, reject) => {
client.once('connect', function () {
let split = msg.split('\n')
for (let i in split) {
client.write(split[i] + '\r\n')
}
client.end('quit\r\n')
resolve()
})
})
}
queue (item) {
if (typeof item !== 'object') item = [item]
let q = []
for (let i in item) {
let ii = item[i]
if (typeof ii !== 'string') continue
if (ii.indexOf('smart:') !== 0 && ii.indexOf('annotate:') !== 0) {
ii = 'smart:' + ii
}
q.push('queue.push ' + ii)
}
this.sendCommand(q.join('\n')).catch((e) => console.error('Failed to queue:', e.message))
}
skip () {
this.sendCommand('skip').catch((e) => console.error('Failed to skip:', e.message))
}
}
module.exports = Liquidsoap