« 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--man/http-music.126
-rwxr-xr-xsrc/http-music.js37
-rw-r--r--src/loop-play.js51
3 files changed, 104 insertions, 10 deletions
diff --git a/man/http-music.1 b/man/http-music.1
index 3bda2f5..bf7befa 100644
--- a/man/http-music.1
+++ b/man/http-music.1
@@ -24,8 +24,26 @@ It can be used anywhere with a Node environment, requiring only two commonly ins
 
 .SH KEYBOARD CONTROLS
 .TP
-.BR <del>
-Assigns a new track to be played next, overwriting the current up-next track.
+.BR <left-arrow>
+Skips backwards 5 seconds in the currently playing track; hold shift to skip by
+30 seconds.
+
+.TP
+.BR <right-arrow>
+Skips forwards 5 seconds in the currently playing track; hold shift to skip by
+30 seconds.
+
+.TP
+.BR <up-arrow>
+Turns the volume up a 10%-notch.
+
+.TP
+.BR <down-arrow>
+Turns the volume down 10%.
+
+.TP
+.BR <space>
+Pauses (or plays) playback.
 
 .TP
 .BR i
@@ -41,6 +59,10 @@ Quits the http-music process and stops music currently being played.
 .BR s
 Skips the currently playing track.
 
+.TP
+.BR <del>
+Assigns a new track to be played next, skipping the current up-next track.
+
 
 .SH OPTIONS
 .TP
diff --git a/src/http-music.js b/src/http-music.js
index 48aff95..7686b45 100755
--- a/src/http-music.js
+++ b/src/http-music.js
@@ -281,6 +281,43 @@ Promise.resolve()
       process.stdin.setRawMode(true)
 
       process.stdin.on('data', data => {
+        const escModifier = Buffer.from('\x1b[')
+        const shiftModifier = Buffer.from('1;2')
+
+        const esc = num => Buffer.concat([escModifier, Buffer.from([num])])
+
+        const shiftEsc = num => (
+          Buffer.concat([escModifier, shiftModifier, Buffer.from([num])])
+        )
+
+        if (Buffer.from([0x20]).equals(data)) {
+          play.togglePause()
+        }
+
+        if (esc(0x43).equals(data)) {
+          play.seekAhead(5)
+        }
+
+        if (esc(0x44).equals(data)) {
+          play.seekBack(5)
+        }
+
+        if (shiftEsc(0x43).equals(data)) {
+          play.seekAhead(30)
+        }
+
+        if (shiftEsc(0x44).equals(data)) {
+          play.seekBack(30)
+        }
+
+        if (esc(0x41).equals(data)) {
+          play.volUp(10)
+        }
+
+        if (esc(0x42).equals(data)) {
+          play.volDown(10)
+        }
+
         if (Buffer.from('s').equals(data)) {
           // clearConsoleLine()
           // console.log(
diff --git a/src/loop-play.js b/src/loop-play.js
index 24f5303..328bb0b 100644
--- a/src/loop-play.js
+++ b/src/loop-play.js
@@ -240,7 +240,11 @@ class PlayController {
 
   playFile(file) {
     this.fifo = new FIFO()
-    this.process = spawn('mpv', ['--input-file=' + this.fifo.path, file])
+    this.process = spawn('mpv', [
+      '--input-file=' + this.fifo.path,
+      '--no-audio-display',
+      file
+    ])
 
     this.process.stderr.on('data', data => {
       const match = data.toString().match(
@@ -284,6 +288,36 @@ class PlayController {
     })
   }
 
+  skipCurrent() {
+    this.killProcess()
+  }
+
+  seekAhead(secs) {
+    this.sendCommand(`seek +${parseFloat(secs)}`)
+  }
+
+  seekBack(secs) {
+    this.sendCommand(`seek -${parseFloat(secs)}`)
+  }
+
+  volUp(amount) {
+    this.sendCommand(`add volume +${parseFloat(amount)}`)
+  }
+
+  volDown(amount) {
+    this.sendCommand(`add volume -${parseFloat(amount)}`)
+  }
+
+  togglePause() {
+    this.sendCommand('cycle pause')
+  }
+
+  sendCommand(command) {
+    if (this.fifo) {
+      this.fifo.write(command)
+    }
+  }
+
   killProcess() {
     if (this.process) {
       this.process.kill()
@@ -291,6 +325,7 @@ class PlayController {
 
     if (this.fifo) {
       this.fifo.close()
+      delete this.fifo
     }
 
     this.currentTrack = null
@@ -315,13 +350,13 @@ module.exports = function loopPlay(picker, downloader, playArgs = []) {
   return {
     promise,
 
-    skipCurrent: function() {
-      playController.killProcess()
-    },
-
-    skipUpNext: function() {
-      downloadController.skipUpNext()
-    },
+    seekBack: secs => playController.seekBack(secs),
+    seekAhead: secs => playController.seekAhead(secs),
+    skipCurrent: () => playController.skipCurrent(),
+    skipUpNext: () => downloadController.skipUpNext(),
+    volUp: amount => playController.volUp(amount),
+    volDown: amount => playController.volDown(amount),
+    togglePause: () => playController.togglePause(),
 
     kill: function() {
       playController.killProcess()