« get me outta code hell

http-music - Command-line music player + utils (not a server!)
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--package.json1
-rw-r--r--src/loop-play.js66
-rw-r--r--yarn.lock10
3 files changed, 65 insertions, 12 deletions
diff --git a/package.json b/package.json
index f63376a..f082d05 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
   ],
   "dependencies": {
     "cheerio": "^1.0.0-rc.1",
+    "fifo-js": "^2.1.0",
     "ncp": "^2.0.0",
     "node-fetch": "^1.7.0",
     "node-natural-sort": "^0.8.6",
diff --git a/src/loop-play.js b/src/loop-play.js
index 597b58d..24f5303 100644
--- a/src/loop-play.js
+++ b/src/loop-play.js
@@ -6,6 +6,8 @@ const sanitize = require('sanitize-filename')
 const tempy = require('tempy')
 const path = require('path')
 
+const FIFO = require('fifo-js')
+
 const EventEmitter = require('events')
 
 class DownloadController extends EventEmitter {
@@ -93,6 +95,8 @@ class DownloadController extends EventEmitter {
   }
 
   async getSupportedFormats() {
+    // TODO: This is irrelevant with `mpv` instead of `play`.
+
     // Gets the formats supported by SoX (i.e., the `play` command) by
     // searching the help output for the line that starts with
     // 'AUDIO FILE FORMATS:'. This seems to be the only way to list the formats
@@ -228,22 +232,56 @@ class PlayController {
     while (this.downloadController.playFile) {
       this.currentTrack = this.downloadController.pickedTrack
 
+      await this.playFile(this.downloadController.playFile)
 
-      const file = this.downloadController.playFile
-      const playProcess = spawn('play', [...this.playArgs, file])
-      const playPromise = promisifyProcess(playProcess)
-      this.process = playProcess
-
-      const nextPromise = this.downloadController.downloadNext()
+      await this.downloadController.downloadNext()
+    }
+  }
 
-      try {
-        await playPromise
-      } catch(err) {
-        console.warn(err + '\n')
+  playFile(file) {
+    this.fifo = new FIFO()
+    this.process = spawn('mpv', ['--input-file=' + this.fifo.path, file])
+
+    this.process.stderr.on('data', data => {
+      const match = data.toString().match(
+        /(..):(..):(..) \/ (..):(..):(..) \(([0-9]+)%\)/
+      )
+
+      if (match) {
+        const [
+          curHour, curMin, curSec, // ##:##:##
+          lenHour, lenMin, lenSec, // ##:##:##
+          percent // ###%
+        ] = match.slice(1)
+
+        let curStr, lenStr
+
+        // We don't want to display hour counters if the total length is less
+        // than an hour.
+        if (parseInt(lenHour) > 0) {
+          curStr = `${curHour}:${curMin}:${curSec}`
+          lenStr = `${lenHour}:${lenMin}:${lenSec}`
+        } else {
+          curStr = `${curMin}:${curSec}`
+          lenStr = `${lenMin}:${lenSec}`
+        }
+
+        // Multiplication casts to numbers; addition prioritizes strings.
+        // Thanks, JavaScript!
+        const curSecTotal = (3600 * curHour) + (60 * curMin) + (1 * curSec)
+        const lenSecTotal = (3600 * lenHour) + (60 * lenMin) + (1 * lenSec)
+        const percentVal = (100 / lenSecTotal) * curSecTotal
+        const percentStr = (Math.trunc(percentVal * 100) / 100).toFixed(2)
+
+        process.stdout.write(
+          `\x1b[K~ (${percentStr}%) ${curStr} / ${lenStr}\r`
+        )
       }
+    })
 
-      await nextPromise
-    }
+    return new Promise(resolve => {
+      this.process.once('close', resolve)
+    })
   }
 
   killProcess() {
@@ -251,6 +289,10 @@ class PlayController {
       this.process.kill()
     }
 
+    if (this.fifo) {
+      this.fifo.close()
+    }
+
     this.currentTrack = null
   }
 }
diff --git a/yarn.lock b/yarn.lock
index dbeda92..414cc7d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -82,6 +82,16 @@ entities@^1.1.1, entities@~1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
 
+es6-error@^3.0.1:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-3.2.0.tgz#e567cfdcb324d4e7ae5922a3700ada5de879a0ca"
+
+fifo-js:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/fifo-js/-/fifo-js-2.1.0.tgz#88405f21dea067362558189e7a07655dc0fe14be"
+  dependencies:
+    es6-error "^3.0.1"
+
 htmlparser2@^3.9.1:
   version "3.9.2"
   resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"