« get me outta code hell

Support SoX again; make 'converter' meta-downloader (converts to wav) - http-music - Command-line music player + utils (not a server!)
about summary refs log tree commit diff
path: root/src/loop-play.js
diff options
context:
space:
mode:
authorliam4 <towerofnix@gmail.com>2017-07-24 20:26:37 -0300
committerliam4 <towerofnix@gmail.com>2017-07-24 20:26:37 -0300
commita8ef887dbfaee530d13e86ff583393a4ddf88e93 (patch)
tree8c9b1d94c9b79e83d3201e58882382dd9cdce930 /src/loop-play.js
parentb6e90e8f380569803b9a83f8997159b34d64e501 (diff)
Support SoX again; make 'converter' meta-downloader (converts to wav)
Diffstat (limited to 'src/loop-play.js')
-rw-r--r--src/loop-play.js56
1 files changed, 48 insertions, 8 deletions
diff --git a/src/loop-play.js b/src/loop-play.js
index 8fdbdf3..b0bb4dd 100644
--- a/src/loop-play.js
+++ b/src/loop-play.js
@@ -5,8 +5,9 @@
 const { spawn } = require('child_process')
 const FIFO = require('fifo-js')
 const EventEmitter = require('events')
-const { getDownloaderFor } = require('./downloaders')
+const { getDownloaderFor, makeConverterDownloader } = require('./downloaders')
 const { getItemPathString } = require('./playlist-utils')
+const promisifyProcess = require('./promisify-process')
 
 class DownloadController extends EventEmitter {
   waitForDownload() {
@@ -65,11 +66,12 @@ class DownloadController extends EventEmitter {
 
 class PlayController {
   constructor(picker, downloadController) {
-    this.currentTrack = null
-    this.playOpts = []
-    this.process = null
     this.picker = picker
     this.downloadController = downloadController
+    this.playOpts = []
+    this.playerCommand = null
+    this.currentTrack = null
+    this.process = null
   }
 
   async loopPlay() {
@@ -112,13 +114,47 @@ class PlayController {
     if (picked === null) {
       return null
     } else {
-      const downloader = getDownloaderFor(picked.downloaderArg)
+      let downloader = getDownloaderFor(picked.downloaderArg)
+      downloader = makeConverterDownloader(downloader, 'wav')
       this.downloadController.download(downloader, picked.downloaderArg)
       return picked
     }
   }
 
   playFile(file) {
+    if (this.playerCommand === 'sox' || this.playerCommand === 'play') {
+      return this.playFileSoX(file)
+    } else if (this.playerCommand === 'mpv') {
+      return this.playFileMPV(file)
+    } else {
+      if (this.playerCommand) {
+        console.warn('Invalid player command given?', this.playerCommand)
+      } else {
+        console.warn('No player command given?')
+      }
+
+      return Promise.resolve()
+    }
+  }
+
+  playFileSoX(file) {
+    // SoX's play command is useful for systems that don't have MPV. SoX is
+    // much easier to install (and probably more commonly installed, as well).
+    // You don't get keyboard controls such as seeking or volume adjusting
+    // with SoX, though.
+
+    this.process = spawn('play', [
+      ...this.playOpts,
+      file
+    ])
+
+    return promisifyProcess(this.process)
+  }
+
+  playFileMPV(file) {
+    // The more powerful MPV player. MPV is virtually impossible for a human
+    // being to install; if you're having trouble with it, try the SoX player.
+
     this.fifo = new FIFO()
     this.process = spawn('mpv', [
       '--input-file=' + this.fifo.path,
@@ -194,7 +230,7 @@ class PlayController {
   }
 
   sendCommand(command) {
-    if (this.fifo) {
+    if (this.playerCommand === 'mpv' && this.fifo) {
       this.fifo.write(command)
     }
   }
@@ -235,15 +271,19 @@ class PlayController {
   }
 }
 
-module.exports = function loopPlay(picker, playOpts = []) {
+module.exports = function loopPlay(
+  picker, playerCommand = 'mpv', playOpts = []
+) {
   // Looping play function. Takes one argument, the "picker" function,
   // which returns a track to play. Stops when the result of the picker
   // function is null (or similar). Optionally takes a second argument
   // used as arguments to the `play` process (before the file name).
 
   const downloadController = new DownloadController()
+
   const playController = new PlayController(picker, downloadController)
-  playController.playOpts = playOpts
+
+  Object.assign(playController, {playerCommand, playOpts})
 
   const promise = playController.loopPlay()