diff --git a/app/index.html b/app/index.html
index 63788d8..2ab716a 100644
--- a/app/index.html
+++ b/app/index.html
@@ -44,7 +44,9 @@
-
+
diff --git a/app/js/app.js b/app/js/app.js
index 9ddc754..2955e2e 100644
--- a/app/js/app.js
+++ b/app/js/app.js
@@ -6,8 +6,9 @@ import * as queue from "./queue.js";
import * as library from "./library.js";
import * as fs from "./fs.js";
import * as playlists from "./playlists.js";
+import * as yt from "./yt.js";
-const components = { queue, library, fs, playlists };
+const components = { queue, library, fs, playlists, yt };
export function activate(what) {
for (let id in components) {
@@ -33,7 +34,7 @@ async function init() {
player.init(document.querySelector("#player"));
- activate("fs");
+ activate("yt");
}
diff --git a/app/js/lib/ui.js b/app/js/lib/ui.js
index d368a56..d8f519e 100644
--- a/app/js/lib/ui.js
+++ b/app/js/lib/ui.js
@@ -28,17 +28,20 @@ function fileName(data) {
}
function formatTitle(ctx, data) {
+ let tokens = [];
switch (ctx) {
case CTX_FS:
return `🎵 ${fileName(data)}`;
break;
case CTX_LIBRARY:
- return data["Artist"] || fileName(data);
+ data["Track"] && tokens.push(data["Track"].padStart(2, "0"));
+ data["Title"] && tokens.push(data["Title"]);
+ if (!tokens.length) {tokens.push(fileName(data)); }
+ return tokens.join(" ");
break;
case CTX_QUEUE:
- let tokens = [];
data["Artist"] && tokens.push(data["Artist"]);
data["Title"] && tokens.push(data["Title"]);
if (!tokens.length) { tokens.push(fileName(data)); }
@@ -118,6 +121,7 @@ export function song(ctx, data, parent) {
deleteButton(TYPE_ID, id, node);
break;
+ case CTX_LIBRARY:
case CTX_FS:
let url = data["file"];
playButton(TYPE_URL, url, node);
diff --git a/app/js/yt.js b/app/js/yt.js
new file mode 100644
index 0000000..f7fb6f9
--- /dev/null
+++ b/app/js/yt.js
@@ -0,0 +1,26 @@
+import * as mpd from "./lib/mpd.js";
+import * as html from "./lib/html.js";
+import * as pubsub from "./lib/pubsub.js";
+import * as ui from "./lib/ui.js";
+
+let node;
+
+async function onClick(e) {
+ let url = prompt("Please enter a YouTube URL:");
+ if (!url) { return; }
+
+ let body = new URLSearchParams();
+ body.set("url", url);
+ let response = await fetch("/youtube", {method:"POST", body});
+ console.log(response);
+ let text = await response.text();
+ console.log(text, text.length);
+}
+
+export async function activate() {}
+
+export function init(n) {
+ node = n;
+
+ node.querySelector(".go").addEventListener("click", onClick);
+}
diff --git a/index.js b/index.js
index 4c06723..1f145dd 100644
--- a/index.js
+++ b/index.js
@@ -2,9 +2,61 @@ const static = require("node-static");
const app = new static.Server("./app");
const port = 8080;
-let httpServer = require("http").createServer((request, response) => {
- request.on("end", () => app.serve(request, response)).resume();
-});
-httpServer.listen(port);
+function downloadYoutube(url, response) {
+ console.log("YouTube downloading", url);
+ let args = [
+ "-f", "bestaudio",
+ "-o", `${__dirname}/_youtube/%(title)s-%(id)s.%(ext)s`,
+ url
+ ]
+ let child = require("child_process").spawn("youtube-dl", args);
+ let stdOut = "";
+ let stdErr = "";
+ child.stdout.setEncoding("utf8").on("data", chunk => stdOut += chunk);
+ child.stderr.setEncoding("utf8").on("data", chunk => stdErr += chunk);
+
+ child.on("error", error => {
+ console.log(error);
+ response.writeHead(500);
+ response.end(error.message);
+ });
+
+ child.on("close", code => {
+ if (code == 0) {
+ console.log("OK");
+ response.end(stdOut);
+ } else {
+ console.log(code, stdOut, stdErr);
+ response.writeHead(500);
+ response.end(stdErr);
+ }
+ });
+}
+
+function handleYoutube(request, response) {
+ let str = "";
+ request.setEncoding("utf8");
+ request.on("data", chunk => str += chunk);
+ request.on("end", () => {
+ let url = require("querystring").parse(str)["url"];
+ console.log(url);
+ if (url) {
+ downloadYoutube(url, response);
+ } else {
+ response.writeHead(404);
+ response.end();
+ }
+ });
+}
+
+function onRequest(request, response) {
+ if (request.method == "POST" && request.url == "/youtube") {
+ return handleYoutube(request, response);
+ } else {
+ request.on("end", () => app.serve(request, response)).resume();
+ }
+}
+
+let httpServer = require("http").createServer(onRequest).listen(port);
require("ws2mpd").ws2mpd(httpServer, `http://localhost:${port}`);