From a22688a0f04920c73a06a7c1be09037c4de8f0ce Mon Sep 17 00:00:00 2001 From: Florrie Date: Wed, 24 Jan 2018 17:44:42 -0400 Subject: Add paused indicator for mpv player --- src/loop-play.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/loop-play.js') diff --git a/src/loop-play.js b/src/loop-play.js index 34ac4d5..70b5e5c 100644 --- a/src/loop-play.js +++ b/src/loop-play.js @@ -22,8 +22,11 @@ const { getItemPathString, safeUnlink, parentSymbol } = require('./playlist-utils') -function createStatusLine({percentStr, curStr, lenStr}) { - return `(${percentStr}) ${curStr} / ${lenStr}` +function createStatusLine({percentStr, curStr, lenStr, paused = false}) { + return ( + `(${percentStr}) ${curStr} / ${lenStr}` + + (paused === true ? ' (Paused)' : '') + ) } class Player extends EventEmitter { @@ -31,6 +34,7 @@ class Player extends EventEmitter { super() this.disablePlaybackStatus = false + this.paused = false } playFile(file) {} @@ -99,7 +103,9 @@ class MPVPlayer extends Player { (Math.trunc(percentVal * 100) / 100).toFixed(2) + '%' ) - this.printStatusLine(createStatusLine({percentStr, curStr, lenStr})) + this.printStatusLine(createStatusLine({ + percentStr, curStr, lenStr, paused: this.paused + })) } }) @@ -150,6 +156,7 @@ class ControllableMPVPlayer extends MPVPlayer { togglePause() { this.sendCommand('cycle pause') + this.paused = !this.paused } kill() { @@ -217,6 +224,8 @@ class SoXPlayer extends Player { lenStr = `${lenMin}:${pad(lenSec)}` } + // No need to pass paused to createStatusLine, since the SoX player + // can never be paused! this.printStatusLine(createStatusLine({percentStr, curStr, lenStr})) } } -- cgit 1.3.0-6-gf8a5 From a72500509a5a334bd8f0f7d490a4833c03201966 Mon Sep 17 00:00:00 2001 From: Florrie Date: Wed, 24 Jan 2018 22:53:17 -0400 Subject: Revert "Add paused indicator for mpv player" This reverts commit a22688a0f04920c73a06a7c1be09037c4de8f0ce. I still have to think through this feature a fair bit more - currently if you skip to the next track while paused, or pause before MPV actually starts playing, the paused indicator shows while MPV isn't actually paused. --- src/loop-play.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'src/loop-play.js') diff --git a/src/loop-play.js b/src/loop-play.js index 70b5e5c..34ac4d5 100644 --- a/src/loop-play.js +++ b/src/loop-play.js @@ -22,11 +22,8 @@ const { getItemPathString, safeUnlink, parentSymbol } = require('./playlist-utils') -function createStatusLine({percentStr, curStr, lenStr, paused = false}) { - return ( - `(${percentStr}) ${curStr} / ${lenStr}` + - (paused === true ? ' (Paused)' : '') - ) +function createStatusLine({percentStr, curStr, lenStr}) { + return `(${percentStr}) ${curStr} / ${lenStr}` } class Player extends EventEmitter { @@ -34,7 +31,6 @@ class Player extends EventEmitter { super() this.disablePlaybackStatus = false - this.paused = false } playFile(file) {} @@ -103,9 +99,7 @@ class MPVPlayer extends Player { (Math.trunc(percentVal * 100) / 100).toFixed(2) + '%' ) - this.printStatusLine(createStatusLine({ - percentStr, curStr, lenStr, paused: this.paused - })) + this.printStatusLine(createStatusLine({percentStr, curStr, lenStr})) } }) @@ -156,7 +150,6 @@ class ControllableMPVPlayer extends MPVPlayer { togglePause() { this.sendCommand('cycle pause') - this.paused = !this.paused } kill() { @@ -224,8 +217,6 @@ class SoXPlayer extends Player { lenStr = `${lenMin}:${pad(lenSec)}` } - // No need to pass paused to createStatusLine, since the SoX player - // can never be paused! this.printStatusLine(createStatusLine({percentStr, curStr, lenStr})) } } -- cgit 1.3.0-6-gf8a5 From e249bda854212d9ba29015b0c895b72aa2ee3cad Mon Sep 17 00:00:00 2001 From: Florrie Date: Mon, 12 Feb 2018 19:45:52 -0400 Subject: Add --track-display-file option for meme OBS livestreams --- src/loop-play.js | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'src/loop-play.js') diff --git a/src/loop-play.js b/src/loop-play.js index 34ac4d5..e82e77e 100644 --- a/src/loop-play.js +++ b/src/loop-play.js @@ -11,9 +11,13 @@ const { spawn } = require('child_process') const FIFO = require('fifo-js') const EventEmitter = require('events') +const fs = require('fs') +const util = require('util') const killProcess = require('./kill-process') const { HistoryController, generalPicker } = require('./pickers') +const writeFile = util.promisify(fs.writeFile) + const { getDownloaderFor, byName: downloadersByName, makeConverter } = require('./downloaders') @@ -345,14 +349,19 @@ class DownloadController extends EventEmitter { } class PlayController extends EventEmitter { - constructor(player, playlist, historyController, downloadController) { + constructor({ + player, playlist, historyController, downloadController, + useConverterOptions = true, + trackDisplayFile = null // File to output current track path to. + }) { super() this.player = player this.playlist = playlist this.historyController = historyController this.downloadController = downloadController - this.useConverterOptions = true + this.useConverterOptions = useConverterOptions + this.trackDisplayFile = trackDisplayFile this.currentTrack = null this.nextTrack = null @@ -440,6 +449,10 @@ class PlayController extends EventEmitter { ]) if (next) { + if (this.trackDisplayFile) { + await writeFile(this.trackDisplayFile, getItemPathString(this.currentTrack)) + } + await this.playFile(next) // Now that we're done playing the file, we should delete it.. unless @@ -643,7 +656,8 @@ module.exports = async function startLoopPlay( pickerOptions, playerCommand, converterCommand, useConverterOptions = true, disablePlaybackStatus = false, - startTrack = null + startTrack = null, + trackDisplayFile = null } ) { // Looping play function. Takes a playlist and an object containing general @@ -686,11 +700,12 @@ module.exports = async function startLoopPlay( historyController.timeline.push(startTrack) } - const playController = new PlayController( - player, playlist, historyController, downloadController - ) + const playController = new PlayController({ + player, playlist, historyController, downloadController, + trackDisplayFile + }) - Object.assign(playController, {playerCommand, useConverterOptions}) + Object.assign(playController, {useConverterOptions}) const promise = playController.loopPlay() -- cgit 1.3.0-6-gf8a5 From 1b5d6f8f96baae53367a7a7d0f9485a42029eaa3 Mon Sep 17 00:00:00 2001 From: Florrie Date: Fri, 16 Feb 2018 11:02:51 -0400 Subject: Make --track-display-file show SOURCE path to track This also means we're keeping track of the source item of items, which is sure to be useful more later. --- src/loop-play.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/loop-play.js') diff --git a/src/loop-play.js b/src/loop-play.js index e82e77e..83cbcfe 100644 --- a/src/loop-play.js +++ b/src/loop-play.js @@ -23,7 +23,7 @@ const { } = require('./downloaders') const { - getItemPathString, safeUnlink, parentSymbol + getItemPathString, safeUnlink, parentSymbol, sourceSymbol } = require('./playlist-utils') function createStatusLine({percentStr, curStr, lenStr}) { @@ -450,7 +450,9 @@ class PlayController extends EventEmitter { if (next) { if (this.trackDisplayFile) { - await writeFile(this.trackDisplayFile, getItemPathString(this.currentTrack)) + await writeFile(this.trackDisplayFile, + getItemPathString(this.currentTrack[sourceSymbol]) + ) } await this.playFile(next) -- cgit 1.3.0-6-gf8a5 From cd661532bcc861d177730273130768a33928ca37 Mon Sep 17 00:00:00 2001 From: Florrie Date: Fri, 23 Feb 2018 09:01:02 -0400 Subject: Handle player process crashing gracefully E.g. try pulseaudio -k, then run http-music. --- src/loop-play.js | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'src/loop-play.js') diff --git a/src/loop-play.js b/src/loop-play.js index 83cbcfe..c702bed 100644 --- a/src/loop-play.js +++ b/src/loop-play.js @@ -37,6 +37,19 @@ class Player extends EventEmitter { this.disablePlaybackStatus = false } + set process(newProcess) { + this._process = newProcess + this._process.on('exit', code => { + if (code !== 0) { + this.emit('crashed', code) // TODO: HANDLE THIS + } + }) + } + + get process() { + return this._process + } + playFile(file) {} seekAhead(secs) {} seekBack(secs) {} @@ -369,6 +382,24 @@ class PlayController extends EventEmitter { this.stopped = false this.shouldMoveNext = true this.failedCount = 0 + this.playFailCount = 0 + + this.player.on('crashed', () => { + console.log('\x1b[31mFailed to play track \x1b[1m' + + getItemPathString(this.currentTrack) + '\x1b[0m' + ) + this.playFailCount++ + + if (this.playFailCount >= 5) { + console.error( + '\x1b[31mFailed to play 5 tracks. Halting, to prevent damage to ' + + 'the computer.\x1b[0m' + ) + + process.exit(1) + throw new Error('Intentionally halted - failed to play tracks.') + } + }) this.player.on('printStatusLine', playerString => { let fullStatusLine = '' @@ -544,8 +575,8 @@ class PlayController extends EventEmitter { "prevent damage to the computer.\x1b[0m" ) - process.exit(0) - throw new Error('Intentionally halted.') + process.exit(1) + throw new Error('Intentionally halted - failed to download tracks.') } // A little bit blecht, but.. this works. -- cgit 1.3.0-6-gf8a5 From 68d879fd17821bc5cd71d9aeedf861dd6c0b488a Mon Sep 17 00:00:00 2001 From: Florrie Date: Fri, 23 Feb 2018 19:04:57 -0400 Subject: Don't count intentionally .kill()ing a process as it crashing --- src/loop-play.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'src/loop-play.js') diff --git a/src/loop-play.js b/src/loop-play.js index c702bed..9c679c7 100644 --- a/src/loop-play.js +++ b/src/loop-play.js @@ -40,9 +40,11 @@ class Player extends EventEmitter { set process(newProcess) { this._process = newProcess this._process.on('exit', code => { - if (code !== 0) { - this.emit('crashed', code) // TODO: HANDLE THIS + if (code !== 0 && !this._killed) { + this.emit('crashed', code) } + + this._killed = false }) } @@ -56,7 +58,13 @@ class Player extends EventEmitter { volUp(amount) {} volDown(amount) {} togglePause() {} - kill() {} + + async kill() { + if (this.process) { + this._killed = true + await killProcess(this.process) + } + } printStatusLine(str) { // Quick sanity check - we don't want to print the status line if it's @@ -124,12 +132,6 @@ class MPVPlayer extends Player { this.process.once('close', resolve) }) } - - async kill() { - if (this.process) { - await killProcess(this.process) - } - } } class ControllableMPVPlayer extends MPVPlayer { @@ -245,9 +247,6 @@ class SoXPlayer extends Player { } async kill() { - if (this.process) { - await killProcess(this.process) - } } } @@ -385,9 +384,13 @@ class PlayController extends EventEmitter { this.playFailCount = 0 this.player.on('crashed', () => { - console.log('\x1b[31mFailed to play track \x1b[1m' + - getItemPathString(this.currentTrack) + '\x1b[0m' - ) + if (this.currentTrack) { + console.log('\x1b[31mFailed to play track \x1b[1m' + + getItemPathString(this.currentTrack) + '\x1b[0m' + ) + } else { + console.log('\x1b[31mFailed to play track.\x1b[0m') + } this.playFailCount++ if (this.playFailCount >= 5) { -- cgit 1.3.0-6-gf8a5 From 8278392e00ef396abcdabc1d538bebeb20deb70c Mon Sep 17 00:00:00 2001 From: Florrie Date: Sat, 3 Mar 2018 08:38:40 -0400 Subject: Be more specific about loop-play errors --- src/loop-play.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/loop-play.js') diff --git a/src/loop-play.js b/src/loop-play.js index 9c679c7..b44e83f 100644 --- a/src/loop-play.js +++ b/src/loop-play.js @@ -310,7 +310,7 @@ class DownloadController extends EventEmitter { try { downloadFile = await downloader(downloaderArg) } catch(err) { - this.emit('errored', err) + this.emit('errored', 'Download error: ' + err) return } @@ -326,7 +326,7 @@ class DownloadController extends EventEmitter { try { convertFile = await this.converter(converterOptions)(downloadFile) } catch(err) { - this.emit('errored', err) + this.emit('errored', 'Convert error: ' + err) return } finally { // Whether the convertion succeeds or not (hence 'finally'), we should -- cgit 1.3.0-6-gf8a5 From 7c7d32d0136092d06f9747cc44c5a37bcc9832b8 Mon Sep 17 00:00:00 2001 From: Florrie Date: Wed, 7 Mar 2018 19:15:26 -0400 Subject: Make (t) key only show information about one track The showTrackInfo keybinding command can now take a number of next/ previous tracks to show. --- src/loop-play.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/loop-play.js') diff --git a/src/loop-play.js b/src/loop-play.js index b44e83f..0fd94e4 100644 --- a/src/loop-play.js +++ b/src/loop-play.js @@ -652,7 +652,11 @@ class PlayController extends EventEmitter { this.stopped = true } - logTrackInfo() { + logTrackInfo(upNextTrackCount = 3, previousTrackCount = undefined) { + if (typeof previousTrackCount === 'undefined') { + previousTrackCount = upNextTrackCount + } + const getColorMessage = t => { if (!t) return '\x1b[2m(No track)\x1b[0m' @@ -675,13 +679,13 @@ class PlayController extends EventEmitter { const tl = hc.timeline const tlI = hc.timelineIndex - for (let i = Math.max(0, tlI - 2); i < tlI; i++) { + for (let i = Math.max(0, tlI - (previousTrackCount - 1)); i < tlI; i++) { console.log(`\x1b[2m(Prev) ${getCleanMessage(tl[i])}\x1b[0m`) } console.log(`\x1b[1m(Curr) \x1b[1m${getColorMessage(tl[tlI])}\x1b[0m`) - for (let i = tlI + 1; i < Math.min(tlI + 3, tl.length); i++) { + for (let i = tlI + 1; i < Math.min(tlI + upNextTrackCount, tl.length); i++) { console.log(`(Next) ${getCleanMessage(tl[i])}`) } } -- cgit 1.3.0-6-gf8a5