diff --git a/bin/mpg321-dummy b/bin/mpg321-dummy index 9867004..050767f 100755 --- a/bin/mpg321-dummy +++ b/bin/mpg321-dummy @@ -1,5 +1,5 @@ #!/bin/bash while read line ; do - echo "OK" + echo "running $line" done diff --git a/jukebox/children.js b/jukebox/children.js index 7494517..214d0ad 100644 --- a/jukebox/children.js +++ b/jukebox/children.js @@ -1,3 +1,8 @@ +"use strict"; + +// TODO: These should really be their own individual classes. Are +// there enough commonalities to warrant a base class? + const spawn = require('child_process').spawn; const EventEmitter = require('events').EventEmitter; @@ -5,7 +10,40 @@ const EventEmitter = require('events').EventEmitter; const TAGREADER = 'tagreader'; const MP3PLAYER = 'mpg321'; -const child_processes = new Map(); +class ChildEmitter extends EventEmitter { + constructor(process) { + super(); + + this.childProcess = process; + + this.childProcess.on('error', function(err) { + this.emit('process_error', err); + }); + + this.childProcess.on('close', function(code, signal) { + this.emit('close', code, signal); + }); + + this.childProcess.stdout.on('data', (data) => { + var s = data.toString(), lines = s.split(/\n/g); + for (var i = 0, l = lines.length; i < l; i++) { + this.emit('message', lines[i]); + } + }); + + this.childProcess.stderr.on('data', (data) => { + this.emit('error', data); + }); + } + + kill() { + this.childProcess.kill(); + } + + send(message) { + this.childProcess.stdin.write(message); + } +} function launchChild(name, command) { var cmd = command[0], @@ -14,56 +52,22 @@ function launchChild(name, command) { return spawn(cmd, args); } -function setupEmitter(name, emitter, child) { - exports[name] = emitter; - - child.on('error', function(err) { - emitter.emit('process_error', err); - }); - - child.on('close', function(code, signal) { - emitter.emit('close', code, signal); - }); - - child.stdout.on('data', (data) => { - var s = data.toString(), lines = s.split(/\n/g); - for (var i = 0, l = lines.length; i < l; i++) { - emitter.emit('message', lines[i]); - } - }); - - child.stderr.on('data', (data) => { - emitter.emit('error', data); - }); - - return emitter; -} - exports.init = function(config) { // Set up tag reader var tagreader = launchChild(TAGREADER, config.tag_reader); - var tagreader_emitter = new EventEmitter(); - setupEmitter(TAGREADER, tagreader_emitter, tagreader); - - child_processes.set(TAGREADER, tagreader); - exports.tagreader = tagreader_emitter; + exports.tagreader = new ChildEmitter(tagreader); // set up mp3 player var mp3player = launchChild(MP3PLAYER, config.mpg321); - var mp3player_emitter = new EventEmitter(); - setupEmitter(MP3PLAYER, mp3player_emitter, mp3player); - - child_processes.set(MP3PLAYER, mp3player); - exports.mp3player = mp3player_emitter; + exports.mp3player = new ChildEmitter(mp3player); }; exports.exitHandler = function(options, err) { console.log('[player] closing children'); if (err) console.log(err.stack); - child_processes.forEach((p) => { - p.kill(); - }); + module.exports.tagreader.kill(); + module.exports.mp3player.kill(); if (options.exit) { process.exit(); diff --git a/player.js b/player.js index 68b90cb..af89077 100644 --- a/player.js +++ b/player.js @@ -46,6 +46,12 @@ children.tagreader.on('message', (data) => { processLine(data); }); +if (config.debug) { + children.mp3player.on('message', (data) => { + console.log(`[mp3player] stdout: ${data}`); + }); +} + var last_tag = null; var debounce_until = 0; @@ -97,7 +103,7 @@ function processLine(data) { debounce_until = Date.now() / 1000 + wait_sec; if (action) { console.log(`[action] [${action}] for [${last_tag}]`); - player.stdin.write(action + "\n"); + children.mp3player.send(action + "\n"); } }); }