« get me outta code hell

remove mkfifo; use socat instead - mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2020-02-04 22:03:56 -0400
committerFlorrie <towerofnix@gmail.com>2020-02-04 22:03:56 -0400
commit5a3835184ed6c31bff97e716f172abaeae93f100 (patch)
treeb3ce7017d67980b56f0223ca41c43c2db9855eca
parentd14770b5f5ec8aaa350d7b235a6c4e5d40dd9a2d (diff)
remove mkfifo; use socat instead
-rw-r--r--package-lock.json27
-rw-r--r--package.json1
-rw-r--r--players.js54
-rw-r--r--socat.js41
-rw-r--r--test-socat.txt0
-rw-r--r--todo.txt9
6 files changed, 91 insertions, 41 deletions
diff --git a/package-lock.json b/package-lock.json
index 99afaa1..325ce96 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,24 +27,11 @@
         "clone": "^1.0.2"
       }
     },
-    "es6-error": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-3.2.0.tgz",
-      "integrity": "sha1-5WfP3LMk1OeuWSKjcAraXeh5oMo="
-    },
     "expand-home-dir": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/expand-home-dir/-/expand-home-dir-0.0.3.tgz",
       "integrity": "sha1-ct6KBIbMKKO71wRjU5iCW1tign0="
     },
-    "fifo-js": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fifo-js/-/fifo-js-2.1.0.tgz",
-      "integrity": "sha1-iEBfId6gZzYlWBieegdlXcD+FL4=",
-      "requires": {
-        "es6-error": "^3.0.1"
-      }
-    },
     "is-wsl": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz",
@@ -121,17 +108,17 @@
       }
     },
     "tui-text-editor": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/tui-text-editor/-/tui-text-editor-0.2.0.tgz",
-      "integrity": "sha512-XnqfBQ3EGqABUf6Xdyxl47byRUR1q+mxDJ4tFBDpezi9ui7Loub4t7LTnsb8fwxJkeMiemF4gpVnEC5JkV5Iqw==",
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/tui-text-editor/-/tui-text-editor-0.3.1.tgz",
+      "integrity": "sha512-ySLdKfUHwxt6W1hub7Qt7smtuwujRHWxMIwdnO+IOzhd2B9naIg07JDr2LISZ3X+SZg0mvBNcGGeTf+L8bcSpw==",
       "requires": {
-        "tui-lib": "^0.1.0"
+        "tui-lib": "^0.1.1"
       },
       "dependencies": {
         "tui-lib": {
-          "version": "0.1.0",
-          "resolved": "https://registry.npmjs.org/tui-lib/-/tui-lib-0.1.0.tgz",
-          "integrity": "sha512-pSq5gn4/8MDlG4B0qbz2u1G5YeuF4xFvqfVLmC0hDAlv90r3yj7pErilDg4Sk7pAE5LEPrxIPsklKbaIXYTEaw==",
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/tui-lib/-/tui-lib-0.1.1.tgz",
+          "integrity": "sha512-QAE4axNCJ42IZSNnc2pLOkFtzHqYFgenDyw88JHHRNd8PXTVO8+JIpJArpgAguopd4MmoYaJbreze0BHoWMXfA==",
           "requires": {
             "wcwidth": "^1.0.1",
             "word-wrap": "^1.2.3"
diff --git a/package.json b/package.json
index 81fb70a..6f8e447 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,6 @@
   "dependencies": {
     "command-exists": "^1.2.6",
     "expand-home-dir": "0.0.3",
-    "fifo-js": "^2.1.0",
     "mkdirp": "^0.5.1",
     "node-fetch": "^2.1.2",
     "node-natural-sort": "^0.8.6",
diff --git a/players.js b/players.js
index 651b519..07b711c 100644
--- a/players.js
+++ b/players.js
@@ -1,9 +1,9 @@
 // stolen from http-music
 
 const { spawn } = require('child_process')
-const FIFO = require('fifo-js')
-const EventEmitter = require('events')
 const { commandExists, killProcess, getTimeStrings } = require('./general-util')
+const EventEmitter = require('events')
+const Socat = require('./socat')
 
 class Player extends EventEmitter {
   constructor() {
@@ -116,27 +116,43 @@ module.exports.MPVPlayer = class extends Player {
 
 module.exports.ControllableMPVPlayer = class extends module.exports.MPVPlayer {
   getMPVOptions(file) {
-    return ['--input-file=' + this.fifo.path, ...super.getMPVOptions(file)]
+    return ['--input-ipc-server=' + this.socat.path, ...super.getMPVOptions(file)]
   }
 
   playFile(file) {
-    this.fifo = new FIFO()
+    let path
+    do {
+      path = '/tmp/mtui-socket-' + Math.floor(Math.random() * 10000)
+    } while (this.existsSync(path))
+
+    this.socat = new Socat(path)
+
+    const mpv = super.playFile(file)
 
-    return super.playFile(file)
+    return mpv
   }
 
-  sendCommand(command) {
-    if (this.fifo) {
-      this.fifo.write(command)
+  existsSync(path) {
+    try {
+      fs.statSync(path)
+      return true
+    } catch (error) {
+      return false
+    }
+  }
+
+  sendCommand(...command) {
+    if (this.socat) {
+      this.socat.send(JSON.stringify({command}))
     }
   }
 
   seekAhead(secs) {
-    this.sendCommand(`seek +${parseFloat(secs)}`)
+    this.sendCommand('seek', secs)
   }
 
   seekBack(secs) {
-    this.sendCommand(`seek -${parseFloat(secs)}`)
+    this.sendCommand('seek', -secs)
   }
 
   volUp(amount) {
@@ -151,35 +167,33 @@ module.exports.ControllableMPVPlayer = class extends module.exports.MPVPlayer {
     this.volume = value
     this.volume = Math.max(0, this.volume)
     this.volume = Math.min(100, this.volume)
-    this.sendCommand(`set volume ${this.volume}`)
+    this.sendCommand('set', 'volume', this.volue)
   }
 
   togglePause() {
     this.isPaused = !this.isPaused
-    this.sendCommand('cycle pause')
+    this.sendCommand('cycle', 'pause')
   }
 
   toggleLoop() {
     this.isLooping = !this.isLooping
-    this.sendCommand('cycle loop')
+    this.sendCommand('cycle', 'loop')
   }
 
   setPause(val) {
     this.isPaused = !!val
-    this.sendCommand('set pause ' + (val ? 'yes' : 'no'))
+    this.sendCommand('set', 'pause', this.isPaused)
   }
 
   setLoop(val) {
     this.isLooping = !!val
-    this.sendCommand('set loop ' + (val ? 'yes' : 'no'))
+    this.sendCommand('set', 'loop', this.isLooping)
   }
 
   kill() {
-    if (this.fifo) {
-      this.fifo.close()
-      delete this.fifo
+    if (this.socat) {
+      this.socat.stop()
     }
-
     return super.kill()
   }
 }
@@ -246,7 +260,7 @@ module.exports.SoXPlayer = class extends Player {
 
 module.exports.getPlayer = async function() {
   if (await commandExists('mpv')) {
-    if (await commandExists('mkfifo')) {
+    if (await commandExists('socat')) {
       return new module.exports.ControllableMPVPlayer()
     } else {
       return new module.exports.MPVPlayer()
diff --git a/socat.js b/socat.js
new file mode 100644
index 0000000..ca317ea
--- /dev/null
+++ b/socat.js
@@ -0,0 +1,41 @@
+// Simple interface for making a socat process and interacting with it.
+// Assumes access to the `socat` command as a child process.
+
+const EventEmitter = require('events')
+const { spawn } = require('child_process')
+const { killProcess } = require('./general-util')
+
+module.exports = class Socat extends EventEmitter {
+  constructor(path) {
+    super()
+    this.setPath(path)
+  }
+
+  setPath(path) {
+    this.stop()
+    this.path = path
+  }
+
+  start() {
+    this.stop()
+    this.subprocess = spawn('socat', ['-', this.path])
+    this.subprocess.stdout.on('data', data => this.emit('data', data))
+    this.subprocess.on('close', () => {
+      this.subprocess = null
+    })
+  }
+
+  stop() {
+    if (this.subprocess) {
+      killProcess(this.subprocess)
+      this.subprocess = null
+    }
+  }
+
+  send(message) {
+    if (!this.subprocess) {
+      this.start()
+    }
+    this.subprocess.stdin.write(message + '\r\n')
+  }
+}
diff --git a/test-socat.txt b/test-socat.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test-socat.txt
diff --git a/todo.txt b/todo.txt
index 0db2382..5e1fe65 100644
--- a/todo.txt
+++ b/todo.txt
@@ -463,3 +463,12 @@ TODO: Only count *consistently* formatted text, across all tracks in a group,
       it is the only track in the group which is formatted '## # <text>'.
       It does follow the formatting '## <text>' as all other tracks do, so only
       the first digits, and following whitespace, should be removed.
+
+TODO: Related to the above - always keep at least one word. See CANSLP's new
+      release "untitled folder", with tracks named "01 1", "02 2", etc.
+
+TODO: Update to work with IPC server mpv (and socat).
+      (Done!)
+
+TODO: Look into testing ^that on Windows. Remove mkfifo, since it's probably
+      no longer necessary!