commit d46e916
uint
·
2026-01-31 20:27:40 +0000 UTC
parent 0a3c07f
remove webui
3 files changed,
+0,
-311
+0,
-39
1@@ -1,39 +0,0 @@
2-<!doctype html>
3-<html>
4- <head>
5- <meta charset="utf-8">
6- <meta name="viewport" content="width=device-width, initial-scale=1">
7- <title>parados</title>
8- <link rel="stylesheet" href="style.css">
9- </head>
10- <body>
11- <header>
12- <h1>parados</h1>
13-
14- <form id="cfg" autocomplete="off">
15- <input id="base" type="text" value="http://127.0.0.1:8088">
16- <button id="load" type="submit">load</button>
17- <span id="status"></span>
18- </form>
19- </header>
20-
21- <main>
22- <section id="left">
23- <input id="filter" type="text" placeholder="filter...">
24- <ul id="list"></ul>
25- </section>
26-
27- <section id="right">
28- <div id="now"></div>
29-
30- <audio id="aud" controls preload="metadata"></audio>
31- <video id="vid" controls preload="metadata"></video>
32-
33- <pre id="meta"></pre>
34- </section>
35- </main>
36-
37- <script src="parados.js"></script>
38- </body>
39-</html>
40-
+0,
-258
1@@ -1,258 +0,0 @@
2-"use strict";
3-
4-let items = [];
5-let active_id = null;
6-
7-function $(id)
8-{
9- return document.getElementById(id);
10-}
11-
12-function status_set(s)
13-{
14- const e = $("status");
15- if (e)
16- e.textContent = s;
17-}
18-
19-function base_url()
20-{
21- const e = $("base");
22- const s = e ? (e.value || "") : "";
23- return s.replace(/\/+$/, "");
24-}
25-
26-function human_size(n)
27-{
28- if (typeof n !== "number" || !isFinite(n))
29- return "" + n;
30-
31- const u = ["B","KB","MB","GB","TB"];
32- let i = 0;
33- while (n >= 1024 && i < u.length - 1) {
34- n /= 1024;
35- i++;
36- }
37- return (i === 0 ? n.toFixed(0) : n.toFixed(1)) + " " + u[i];
38-}
39-
40-function is_video(type, path)
41-{
42- if (type && type.startsWith("video/"))
43- return true;
44-
45- return /\.(mp4|mkv|webm|mov)$/i.test(path || "");
46-}
47-
48-function is_audio(type, path)
49-{
50- if (type && type.startsWith("audio/"))
51- return true;
52-
53- return /\.(mp3|m4a|aac|flac|wav|ogg|opus)$/i.test(path || "");
54-}
55-
56-function clear_players()
57-{
58- const a = $("aud");
59- const v = $("vid");
60-
61- if (a) {
62- a.pause();
63- a.removeAttribute("src");
64- a.style.display = "none";
65- }
66- if (v) {
67- v.pause();
68- v.removeAttribute("src");
69- v.style.display = "none";
70- }
71-}
72-
73-async function api_json(url)
74-{
75- const r = await fetch(url, { method: "GET" });
76- if (!r.ok) {
77- let t = "";
78- try {
79- t = await r.text();
80- }
81- catch (e) {
82- t = "";
83- }
84- t = (t || "").trim();
85- throw new Error("http " + r.status + (t ? (": " + t) : ""));
86- }
87-
88- return await r.json();
89-}
90-
91-function render_list()
92-{
93- const list = $("list");
94- const f = $("filter");
95-
96- if (!list)
97- return;
98-
99- const q = (f ? (f.value || "") : "").toLowerCase();
100-
101- list.innerHTML = "";
102- for (const it of items) {
103- if (q && !(it.path || "").toLowerCase().includes(q))
104- continue;
105-
106- const li = document.createElement("li");
107- li.dataset.id = it.id;
108- li.textContent = it.path || it.id;
109-
110- if (it.id === active_id)
111- li.classList.add("active");
112-
113- li.addEventListener("click", () => select_item(it.id));
114-
115- list.appendChild(li);
116- }
117-}
118-
119-function set_active_class()
120-{
121- const list = $("list");
122- if (!list)
123- return;
124-
125- const lis = list.querySelectorAll("li");
126- for (const li of lis) {
127- if (li.dataset.id === active_id)
128- li.classList.add("active");
129- else
130- li.classList.remove("active");
131- }
132-}
133-
134-async function load_library()
135-{
136- status_set("loading...");
137- clear_players();
138-
139- const now = $("now");
140- const meta = $("meta");
141-
142- if (now)
143- now.textContent = "";
144- if (meta)
145- meta.textContent = "";
146-
147- const base = base_url();
148- const j = await api_json(base + "/library");
149-
150- if (!j || !Array.isArray(j.items))
151- throw new Error("bad /library json");
152-
153- items = j.items.slice();
154- active_id = null;
155-
156- status_set("ok (" + items.length + " items)");
157- render_list();
158-}
159-
160-async function select_item(id)
161-{
162- active_id = id;
163- set_active_class();
164- clear_players();
165-
166- const base = base_url();
167-
168- const it = items.find(x => x.id === id);
169- const path = it ? (it.path || "") : "";
170-
171- const now = $("now");
172- const meta = $("meta");
173- const a = $("aud");
174- const v = $("vid");
175-
176- if (now)
177- now.textContent = path ? path : ("id " + id);
178- if (meta)
179- meta.textContent = "loading meta...";
180-
181- let m = null;
182- try {
183- m = await api_json(base + "/meta/" + id);
184- }
185- catch (e) {
186- if (meta)
187- meta.textContent = "" + e;
188- return;
189- }
190-
191- const type = m.type || "";
192- const size = Number(m.size);
193-
194- if (meta) {
195- meta.textContent =
196- "id: " + (m.id || id) + "\n" +
197- "path: " + (m.path || path) + "\n" +
198- "type: " + type + "\n" +
199- "size: " + (isFinite(size) ? human_size(size) : (m.size || "")) + "\n";
200- }
201-
202- const stream = base + "/stream/" + id;
203-
204- if (v && is_video(type, m.path || path)) {
205- v.src = stream;
206- v.style.display = "block";
207- v.load();
208- return;
209- }
210-
211- if (a && is_audio(type, m.path || path)) {
212- a.src = stream;
213- a.style.display = "block";
214- a.load();
215- return;
216- }
217-
218- if (meta)
219- meta.textContent += "\n(no player for this type)\n";
220-}
221-
222-async function main()
223-{
224- const cfg = $("cfg");
225- const load = $("load");
226- const filter = $("filter");
227-
228- if (cfg) {
229- cfg.addEventListener("submit", async (ev) => {
230- ev.preventDefault();
231- if (load)
232- load.disabled = true;
233-
234- try {
235- await load_library();
236- }
237- catch (e) {
238- status_set("error: " + (e.message || e));
239- }
240- finally {
241- if (load)
242- load.disabled = false;
243- }
244- });
245- }
246-
247- if (filter)
248- filter.addEventListener("input", render_list);
249-
250- try {
251- await load_library();
252- }
253- catch (e) {
254- status_set("error: " + (e.message || e));
255- }
256-}
257-
258-main();
259-
+0,
-14
1@@ -1,14 +0,0 @@
2-body {
3- color: #eeeeee;
4- background-color: #1e1f21;
5- font-family: serif;
6- margin: 20px;
7-}
8-
9-video {
10- width: 100%;
11- max-width: 400px;
12- background: #000;
13- display: block;
14-}
15-