nixamp 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +2 -2
- package/dist/playlist.d.ts +15 -0
- package/dist/playlist.js +26 -0
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/src/main.ts +2 -2
- package/src/playlist.ts +27 -0
- package/src/server.ts +2 -2
- package/web/dist/sw.js +1 -1
package/dist/main.js
CHANGED
|
@@ -12,7 +12,7 @@ import { resolve } from "node:path";
|
|
|
12
12
|
import { detectTools, formatTime, peaks, RATE, Stream, toMono, } from "./audio.js";
|
|
13
13
|
import { Analyser, bandEdges, bands, decay } from "./fft.js";
|
|
14
14
|
import { version } from "./meta.js";
|
|
15
|
-
import { displayName, loadSource } from "./playlist.js";
|
|
15
|
+
import { displayName, loadSource, loadTagged } from "./playlist.js";
|
|
16
16
|
import { isRemote } from "./sources.js";
|
|
17
17
|
import { DEFAULT_PORT } from "./server.js";
|
|
18
18
|
const FFT_SIZE = 2048;
|
|
@@ -317,7 +317,7 @@ export async function main() {
|
|
|
317
317
|
// The titles, arriving into a player that is already up. Not awaited, and
|
|
318
318
|
// applied only if the list is still the one it describes.
|
|
319
319
|
if (!isRemote(target)) {
|
|
320
|
-
void
|
|
320
|
+
void loadTagged(tools, target)
|
|
321
321
|
.then((tagged) => {
|
|
322
322
|
if (tagged.length !== state.tracks.length)
|
|
323
323
|
return;
|
package/dist/playlist.d.ts
CHANGED
|
@@ -24,4 +24,19 @@ export declare function loadSource(tools: Tools, source: string, probeTags?: boo
|
|
|
24
24
|
* the caller decides when to pay for it. Untagged entries still play.
|
|
25
25
|
*/
|
|
26
26
|
export declare function loadPlaylist(tools: Tools, root: string, probeTags?: boolean): Track[];
|
|
27
|
+
/**
|
|
28
|
+
* The same tags, read without holding the process still.
|
|
29
|
+
*
|
|
30
|
+
* `probe` is a spawnSync per file, so reading a library inside one async
|
|
31
|
+
* function never yields: the listening socket keeps accepting connections,
|
|
32
|
+
* the kernel completes their handshakes, and the process answers none of them
|
|
33
|
+
* until the last file is done. From outside that is indistinguishable from a
|
|
34
|
+
* firewall -- a connection that opens and then says nothing -- and on a library
|
|
35
|
+
* of any size it lasts minutes.
|
|
36
|
+
*
|
|
37
|
+
* One turn of the event loop per file fixes it. A request then waits for one
|
|
38
|
+
* ffprobe rather than for the whole library, and the tagging still finishes in
|
|
39
|
+
* about the time it did.
|
|
40
|
+
*/
|
|
41
|
+
export declare function loadTagged(tools: Tools, source: string): Promise<Track[]>;
|
|
27
42
|
export declare function displayName(track: Track): string;
|
package/dist/playlist.js
CHANGED
|
@@ -121,6 +121,32 @@ export function loadPlaylist(tools, root, probeTags = true) {
|
|
|
121
121
|
artist: "", album: "", duration: 0,
|
|
122
122
|
});
|
|
123
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* The same tags, read without holding the process still.
|
|
126
|
+
*
|
|
127
|
+
* `probe` is a spawnSync per file, so reading a library inside one async
|
|
128
|
+
* function never yields: the listening socket keeps accepting connections,
|
|
129
|
+
* the kernel completes their handshakes, and the process answers none of them
|
|
130
|
+
* until the last file is done. From outside that is indistinguishable from a
|
|
131
|
+
* firewall -- a connection that opens and then says nothing -- and on a library
|
|
132
|
+
* of any size it lasts minutes.
|
|
133
|
+
*
|
|
134
|
+
* One turn of the event loop per file fixes it. A request then waits for one
|
|
135
|
+
* ffprobe rather than for the whole library, and the tagging still finishes in
|
|
136
|
+
* about the time it did.
|
|
137
|
+
*/
|
|
138
|
+
export async function loadTagged(tools, source) {
|
|
139
|
+
// A URL is one thing and is never probed; a playlist carries its own titles.
|
|
140
|
+
if (isRemote(source) || isPlaylistFile(source))
|
|
141
|
+
return loadSource(tools, source, true);
|
|
142
|
+
const paths = findAudio(source);
|
|
143
|
+
const tracks = [];
|
|
144
|
+
for (const path of paths) {
|
|
145
|
+
tracks.push(probe(tools, path));
|
|
146
|
+
await new Promise((done) => setImmediate(done));
|
|
147
|
+
}
|
|
148
|
+
return tracks;
|
|
149
|
+
}
|
|
124
150
|
export function displayName(track) {
|
|
125
151
|
return track.artist ? `${track.artist} — ${track.title}` : track.title;
|
|
126
152
|
}
|
package/dist/server.js
CHANGED
|
@@ -39,7 +39,7 @@ import { extname, join, normalize, resolve, sep } from "node:path";
|
|
|
39
39
|
import { fileURLToPath } from "node:url";
|
|
40
40
|
import { detectTools, peaks, RATE, Stream, toMono, } from "./audio.js";
|
|
41
41
|
import { Analyser, bandEdges, bands, decay } from "./fft.js";
|
|
42
|
-
import { loadSource } from "./playlist.js";
|
|
42
|
+
import { loadSource, loadTagged } from "./playlist.js";
|
|
43
43
|
import { emptySnapshot, parseCommand, } from "./protocol.js";
|
|
44
44
|
const FFT_SIZE = 2048;
|
|
45
45
|
export const SERVE_BAND_COUNT = 24;
|
|
@@ -2131,7 +2131,7 @@ export async function serve(argv, version = "0.1.0") {
|
|
|
2131
2131
|
// awaited: nothing downstream needs it, and a library that takes a minute to
|
|
2132
2132
|
// read should cost nobody a minute of silence.
|
|
2133
2133
|
if (tracks.length > 0 && !isRemote(root)) {
|
|
2134
|
-
void
|
|
2134
|
+
void loadTagged(tools, root)
|
|
2135
2135
|
.then((tagged) => engine.retag(tagged, root))
|
|
2136
2136
|
.catch(() => {
|
|
2137
2137
|
// Filenames are a working player. A failure here is worth nothing but
|
package/package.json
CHANGED
package/src/main.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "./audio.ts";
|
|
16
16
|
import { Analyser, bandEdges, bands, decay } from "./fft.ts";
|
|
17
17
|
import { version } from "./meta.ts";
|
|
18
|
-
import { displayName, loadSource } from "./playlist.ts";
|
|
18
|
+
import { displayName, loadSource, loadTagged } from "./playlist.ts";
|
|
19
19
|
import { isRemote } from "./sources.ts";
|
|
20
20
|
import { DEFAULT_PORT } from "./server.ts";
|
|
21
21
|
import type { DaemonState } from "./daemon.ts";
|
|
@@ -352,7 +352,7 @@ export async function main(): Promise<void> {
|
|
|
352
352
|
// The titles, arriving into a player that is already up. Not awaited, and
|
|
353
353
|
// applied only if the list is still the one it describes.
|
|
354
354
|
if (!isRemote(target)) {
|
|
355
|
-
void
|
|
355
|
+
void loadTagged(tools, target)
|
|
356
356
|
.then((tagged) => {
|
|
357
357
|
if (tagged.length !== state.tracks.length) return;
|
|
358
358
|
if (tagged.some((track, at) => track.path !== state.tracks[at]?.path)) return;
|
package/src/playlist.ts
CHANGED
|
@@ -132,6 +132,33 @@ export function loadPlaylist(tools: Tools, root: string, probeTags = true): Trac
|
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* The same tags, read without holding the process still.
|
|
137
|
+
*
|
|
138
|
+
* `probe` is a spawnSync per file, so reading a library inside one async
|
|
139
|
+
* function never yields: the listening socket keeps accepting connections,
|
|
140
|
+
* the kernel completes their handshakes, and the process answers none of them
|
|
141
|
+
* until the last file is done. From outside that is indistinguishable from a
|
|
142
|
+
* firewall -- a connection that opens and then says nothing -- and on a library
|
|
143
|
+
* of any size it lasts minutes.
|
|
144
|
+
*
|
|
145
|
+
* One turn of the event loop per file fixes it. A request then waits for one
|
|
146
|
+
* ffprobe rather than for the whole library, and the tagging still finishes in
|
|
147
|
+
* about the time it did.
|
|
148
|
+
*/
|
|
149
|
+
export async function loadTagged(tools: Tools, source: string): Promise<Track[]> {
|
|
150
|
+
// A URL is one thing and is never probed; a playlist carries its own titles.
|
|
151
|
+
if (isRemote(source) || isPlaylistFile(source)) return loadSource(tools, source, true);
|
|
152
|
+
|
|
153
|
+
const paths = findAudio(source);
|
|
154
|
+
const tracks: Track[] = [];
|
|
155
|
+
for (const path of paths) {
|
|
156
|
+
tracks.push(probe(tools, path));
|
|
157
|
+
await new Promise<void>((done) => setImmediate(done));
|
|
158
|
+
}
|
|
159
|
+
return tracks;
|
|
160
|
+
}
|
|
161
|
+
|
|
135
162
|
export function displayName(track: Track): string {
|
|
136
163
|
return track.artist ? `${track.artist} — ${track.title}` : track.title;
|
|
137
164
|
}
|
package/src/server.ts
CHANGED
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
type Tools, type Track,
|
|
77
77
|
} from "./audio.ts";
|
|
78
78
|
import { Analyser, bandEdges, bands, decay } from "./fft.ts";
|
|
79
|
-
import { loadSource } from "./playlist.ts";
|
|
79
|
+
import { loadSource, loadTagged } from "./playlist.ts";
|
|
80
80
|
import {
|
|
81
81
|
emptySnapshot, parseCommand,
|
|
82
82
|
type Command, type RemoteTrack, type Snapshot,
|
|
@@ -2448,7 +2448,7 @@ export async function serve(argv: string[], version = "0.1.0"): Promise<void> {
|
|
|
2448
2448
|
// awaited: nothing downstream needs it, and a library that takes a minute to
|
|
2449
2449
|
// read should cost nobody a minute of silence.
|
|
2450
2450
|
if (tracks.length > 0 && !isRemote(root)) {
|
|
2451
|
-
void
|
|
2451
|
+
void loadTagged(tools, root)
|
|
2452
2452
|
.then((tagged) => engine.retag(tagged, root))
|
|
2453
2453
|
.catch(() => {
|
|
2454
2454
|
// Filenames are a working player. A failure here is worth nothing but
|
package/web/dist/sw.js
CHANGED