UNPKG

vlc-remote

Version:

VLC control through TCP/RC (telnet) remote interface

155 lines (118 loc) 3.4 kB
"use strict"; const isWin = (process.platform == 'win32'); const Remote = require('./remote'); const debug = require('debug')('vlc'); const map = require('mout/object/map'); const values = require('mout/object/values'); const mixIn = require('mout/object/mixIn'); const sleep = require('nyks/async/sleep'); const defer = require('nyks/promise/defer'); const vlc = require('vlc-player'); const heartbeat_interval = 1000; const splitter = /input debug: `(.*)' successfully opened/; var config = { 'ignore-config' : null, 'no-plugins-cache' : null, 'no-media-library' : null, 'config' : 'blank', 'no-video-title-show' : null, 'verbose' : 3, 'intf' : 'dummy', 'rc-host' : '127.0.0.1:8088', 'extraintf' : 'rc', 'loop' : null, }; if(isWin) { mixIn(config, { 'no-crashdump' : null, 'rc-quiet' : null, 'dummy-quiet' : null, }); } class Player extends Remote { constructor(options = {}, vlcfactory = vlc) { var player_options = mixIn({}, config, (options || {}).args); let [host, port] = player_options['rc-host'].split(':'); super(port, host); this.options = player_options; this.vlcfactory = vlcfactory; } async start() { if(this.vlc) return; var cmdargs = values(map(this.options, function(v, k) { return '--' + k + '' + (v === null ? '' : '=' + v); })); this.vlc = await this.vlcfactory(cmdargs, {stdio : ['ignore', 'ignore', 'pipe']}); var dataBuff = ''; this.vlc.stderr.on('data', (data) => { dataBuff = dataBuff + data; if(splitter.test(dataBuff)) { var matches = splitter.exec(dataBuff); dataBuff = ''; this.emit('play', matches[1]); debug(`playing ${matches[1]}`); } }); if(this.options.intf == "skins2") await this._waitVlcSkin(); try { debug("waiting player server"); await this._waitVlcServerStart(); debug("Player ready"); } catch(err) { this.close(); throw err; } debug(`Spawned vlc child pid: ${this.vlc.pid}`); this.vlc.on('close', this.emit.bind(this, 'close')); this.vlc.on('error', this.emit.bind(this, 'error')); var heartbeat = setInterval(() => { this.info().catch(() => { this.close(); clearInterval(heartbeat); }); }, heartbeat_interval); } close() { if(!this.vlc) return; try { this.vlc.kill(); debug(`killed vlc child pid: ${this.vlc.pid}`); } catch(err) { debug(err); } this.vlc = null; } _waitVlcSkin() { var waitSkin = defer(); var skinBuff = ''; var self = this; debug("waiting skin load "); this.vlc.stderr.on('data', function listener(data) { skinBuff = skinBuff + data; if((skinBuff).indexOf("using skin file") != -1) { debug("Skin ready"); self.vlc.stderr.removeListener('data', listener); waitSkin.resolve(); } }); return waitSkin; } async _waitVlcServerStart() { var attempt = 10; var shouldWait = true; while(shouldWait && (attempt--) > 0) { try { await this.info(); shouldWait = false; } catch(err) { await sleep(200); } } if(attempt <= 0) throw 'Server not ready'; } } module.exports = Player;