« get me outta code hell

http-music - Command-line music player + utils (not a server!)
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/http-music.js21
-rw-r--r--src/loop-play.js61
2 files changed, 48 insertions, 34 deletions
diff --git a/src/http-music.js b/src/http-music.js
index 1392c34..ed79878 100755
--- a/src/http-music.js
+++ b/src/http-music.js
@@ -246,6 +246,7 @@ setupDefaultPlaylist('./playlist.json')
 
       process.stdin.on('data', data => {
         if (Buffer.from('s').equals(data)) {
+          // clearConsoleLine()
           // console.log(
           //   "Skipping the track that's currently playing. " +
           //   "(Press I for track info!)"
@@ -255,6 +256,7 @@ setupDefaultPlaylist('./playlist.json')
         }
 
         if (Buffer.from([0x7f]).equals(data)) { // Delete
+          clearConsoleLine()
           console.log(
             "Skipping the track that's up next. " +
             "(Press I for track info!)"
@@ -264,6 +266,14 @@ setupDefaultPlaylist('./playlist.json')
         }
 
         if (
+          Buffer.from('i').equals(data) ||
+          Buffer.from('t').equals(data)
+        ) {
+          clearConsoleLine()
+          play.logTrackInfo()
+        }
+
+        if (
           Buffer.from('q').equals(data) ||
           Buffer.from([0x03]).equals(data) || // ^C
           Buffer.from([0x04]).equals(data) // ^D
@@ -272,13 +282,6 @@ setupDefaultPlaylist('./playlist.json')
           process.stdout.write('\n')
           process.exit(0)
         }
-
-        if (
-          Buffer.from('i').equals(data) ||
-          Buffer.from('t').equals(data)
-        ) {
-          play.logTrackInfo()
-        }
       })
 
       return play.promise
@@ -287,3 +290,7 @@ setupDefaultPlaylist('./playlist.json')
     }
   })
   .catch(err => console.error(err))
+
+function clearConsoleLine() {
+  process.stdout.write('\x1b[1K\r')
+}
diff --git a/src/loop-play.js b/src/loop-play.js
index cf6d829..ac666a3 100644
--- a/src/loop-play.js
+++ b/src/loop-play.js
@@ -13,17 +13,31 @@ class DownloadController extends EventEmitter {
 
     this.pickedTrack = null
     this.process = null
-    this.requestingSkipUpNext = false
     this.isDownloading = false
 
     this.picker = picker
     this.downloader = downloader
+
+    this._downloadNext = null
+  }
+
+  downloadNext() {
+    this.downloadNextHelper()
+
+    return new Promise(resolve => {
+      this.once('downloadFinished', resolve)
+    })
   }
 
-  async downloadNext() {
-    this.requestingSkipUpNext = false
+  async downloadNextHelper() {
     this.isDownloading = true
 
+    let wasDestroyed = false
+
+    this._destroyDownload = () => {
+      wasDestroyed = true
+    }
+
     // We need to actually pick something to download; we'll use the picker
     // (given in the DownloadController constructor) for that.
     // (See pickers.js.)
@@ -91,41 +105,32 @@ class DownloadController extends EventEmitter {
       // isn't any guarding against a situation like that here.)
 
       // Usually we'll log a warning message saying that the convertion failed,
-      // but if we're requesting a skip-up-next, it's expected for the avconv
+      // but if this download was destroyed, it's expected for the avconv
       // process to fail; so in that case we don't bother warning the user.
-      if (!this.requestingSkipUpNext) {
+      if (!wasDestroyed) {
         console.warn("Failed to convert " + title)
         console.warn("Selecting a new track")
-      }
 
-      return await this.downloadNext()
+        return await this.downloadNext()
+      }
     }
 
-    // If we were requested to skip the up-next track that's currently being
-    // downloaded (probably by the user), we'll have to do that now.
-    if (this.requestingSkipUpNext) return await this.downloadNext()
+    // If this download was destroyed, we quit now; we don't want to emit that
+    // the download was finished if the finished download was the destroyed
+    // one!
+    if (wasDestroyed) {
+      return
+    }
 
-    // We successfully downloaded something, and so the downloadNext function
-    // is done. We mark that here, so that skipUpNext will know that it'll need
-    // to start a whole new downloadNext to have any effect.
-    this.isDownloading = false
+    this.emit('downloadFinished')
   }
 
   skipUpNext() {
-    // If we're already in the process of downloading the up-next track, we'll
-    // set the requestingSkipUpNext flag to true. downloadNext will use this to
-    // cancel its current download and begin new.
-    if (this.isDownloading) {
-      this.requestingSkipUpNext = true
-      this.killProcess()
+    if (this._destroyDownload) {
+      this._destroyDownload()
     }
 
-    // If we aren't currently downloading a track, downloadNext won't
-    // automatically be called from the start again, so we need to do that
-    // here.
-    if (!this.isDownloading) {
-      this.downloadNext()
-    }
+    this.downloadNextHelper()
   }
 
   killProcess() {
@@ -145,7 +150,6 @@ class PlayController {
     this.downloadController = downloadController
 
     this.downloadController.on('trackPicked', track => {
-      console.log('Changed:', track[0])
       this.upNextTrack = track
     })
   }
@@ -159,6 +163,7 @@ class PlayController {
     while (this.downloadController.wavFile) {
       this.currentTrack = this.downloadController.pickedTrack
 
+
       const file = this.downloadController.wavFile
       const playProcess = spawn('play', [...this.playArgs, file])
       const playPromise = promisifyProcess(playProcess)
@@ -180,6 +185,8 @@ class PlayController {
     if (this.process) {
       this.process.kill()
     }
+
+    this.currentTrack = null
   }
 }