From a48c6bbbbcca48ddc0bade66b33781e13f80213d Mon Sep 17 00:00:00 2001 From: liam4 Date: Sun, 11 Jun 2017 10:04:09 -0300 Subject: Beginnings of keyboard controls --- src/http-music.js | 23 ++++++++++++++++++++++- src/loop-play.js | 47 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/http-music.js b/src/http-music.js index fee1b79..3d7e217 100755 --- a/src/http-music.js +++ b/src/http-music.js @@ -239,7 +239,28 @@ setupDefaultPlaylist('./playlist.json') return } - return loopPlay(picker, downloader, playOpts) + const play = loopPlay(picker, downloader, playOpts) + + // We're looking to gather standard input one keystroke at a time. + process.stdin.setRawMode(true) + + process.stdin.on('data', data => { + if (Buffer.from('s').equals(data)) { + play.skip() + } + + if ( + Buffer.from('q').equals(data) || + Buffer.from([0x03]).equals(data) || // ^C + Buffer.from([0x04]).equals(data) // ^D + ) { + play.kill() + process.stdout.write('\n') + process.exit(0) + } + }) + + return play.promise } else { return activePlaylist } diff --git a/src/loop-play.js b/src/loop-play.js index 5205025..ff77940 100644 --- a/src/loop-play.js +++ b/src/loop-play.js @@ -12,7 +12,7 @@ const sanitize = require('sanitize-filename') const writeFile = promisify(fs.writeFile) -module.exports = async function loopPlay(picker, downloader, playArgs = []) { +module.exports = function loopPlay(picker, downloader, playArgs = []) { // Looping play function. Takes one argument, the "pick" function, // which returns a track to play. Preemptively downloads the next // track while the current one is playing for seamless continuation @@ -20,6 +20,8 @@ module.exports = async function loopPlay(picker, downloader, playArgs = []) { // function is null (or similar). Optionally takes a second argument // used as arguments to the `play` process (before the file name). + let playProcess, convertProcess + async function downloadNext() { const picked = picker() @@ -36,7 +38,9 @@ module.exports = async function loopPlay(picker, downloader, playArgs = []) { const wavFile = tempDir + `/.${sanitize(title)}.wav` try { - await convert(downloadFile, wavFile) + const convertPromise = convert(downloadFile, wavFile) + convertProcess = convertPromise.process + await convertPromise } catch(err) { console.warn("Failed to convert " + title) console.warn("Selecting a new track\n") @@ -47,12 +51,39 @@ module.exports = async function loopPlay(picker, downloader, playArgs = []) { return wavFile } - let wavFile = await downloadNext() + async function main() { + let wavFile = await downloadNext() + + while (wavFile) { + const nextPromise = downloadNext() + + // What a mouthful! + const playPromise = playFile(wavFile, playArgs) + playProcess = playPromise.process - while (wavFile) { - const nextPromise = downloadNext() - await playFile(wavFile, playArgs) - wavFile = await nextPromise + try { + await playPromise + } catch(err) { + console.warn(err) + } + + wavFile = await nextPromise + } + } + + const promise = main() + + return { + promise, + + skip: function() { + if (playProcess) playProcess.kill() + }, + + kill: function() { + if (playProcess) playProcess.kill() + if (convertProcess) convertProcess.kill() + } } } @@ -63,5 +94,5 @@ function convert(fromFile, toFile) { function playFile(file, opts = []) { const play = spawn('play', [...opts, file]) - return promisifyProcess(play) + return Object.assign(promisifyProcess(play), {process: play}) } -- cgit 1.3.0-6-gf8a5