@kattowo/distube 6.2.0 → 6.2.2
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/index.d.mts +68 -1
- package/dist/index.d.ts +68 -1
- package/dist/index.js +61 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +61 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/constant.ts
|
|
5
|
-
var version = "6.2.
|
|
5
|
+
var version = "6.2.2";
|
|
6
6
|
var AUDIO_SAMPLE_RATE = 48e3;
|
|
7
7
|
var AUDIO_CHANNELS = 2;
|
|
8
8
|
var DEFAULT_VOLUME = 50;
|
|
@@ -2548,8 +2548,8 @@ var Options = class {
|
|
|
2548
2548
|
if (typeof value !== "object" || Array.isArray(value)) {
|
|
2549
2549
|
throw new DisTubeError("INVALID_TYPE", "object", value, "DisTubeOptions.crossfade");
|
|
2550
2550
|
}
|
|
2551
|
-
checkInvalidKey(value, ["duration", "curve", "warmup"], "DisTubeOptions.crossfade");
|
|
2552
|
-
const { duration, curve, warmup } = value;
|
|
2551
|
+
checkInvalidKey(value, ["duration", "curve", "warmup", "preparePrimaryInput"], "DisTubeOptions.crossfade");
|
|
2552
|
+
const { duration, curve, warmup, preparePrimaryInput } = value;
|
|
2553
2553
|
if (duration !== void 0 && (typeof duration !== "number" || Number.isNaN(duration) || duration < 0)) {
|
|
2554
2554
|
throw new DisTubeError(
|
|
2555
2555
|
"INVALID_TYPE",
|
|
@@ -2572,10 +2572,19 @@ var Options = class {
|
|
|
2572
2572
|
if (warmup !== void 0 && (typeof warmup !== "number" || Number.isNaN(warmup) || warmup < 0)) {
|
|
2573
2573
|
throw new DisTubeError("INVALID_TYPE", "number >= 0", warmup, "DisTubeOptions.crossfade.warmup");
|
|
2574
2574
|
}
|
|
2575
|
+
if (preparePrimaryInput !== void 0 && typeof preparePrimaryInput !== "function") {
|
|
2576
|
+
throw new DisTubeError(
|
|
2577
|
+
"INVALID_TYPE",
|
|
2578
|
+
"function",
|
|
2579
|
+
preparePrimaryInput,
|
|
2580
|
+
"DisTubeOptions.crossfade.preparePrimaryInput"
|
|
2581
|
+
);
|
|
2582
|
+
}
|
|
2575
2583
|
return {
|
|
2576
2584
|
duration: duration ?? DEFAULT_CROSSFADE_DURATION_SECS,
|
|
2577
2585
|
curve: curve ?? DEFAULT_CROSSFADE_CURVE,
|
|
2578
|
-
warmup: warmup ?? DEFAULT_CROSSFADE_WARMUP_SECS
|
|
2586
|
+
warmup: warmup ?? DEFAULT_CROSSFADE_WARMUP_SECS,
|
|
2587
|
+
preparePrimaryInput
|
|
2579
2588
|
};
|
|
2580
2589
|
}
|
|
2581
2590
|
#validateOptions(options = this) {
|
|
@@ -2700,6 +2709,17 @@ var DisTubeStream = class extends TypedEmitter2 {
|
|
|
2700
2709
|
* The seek time in seconds that this stream started from
|
|
2701
2710
|
*/
|
|
2702
2711
|
seekTime;
|
|
2712
|
+
/**
|
|
2713
|
+
* Whether FFmpeg has already produced audio that is waiting to be read.
|
|
2714
|
+
*
|
|
2715
|
+
* The stream is spawned ahead of the playback (crossfade warmup) and the
|
|
2716
|
+
* pipe backs up once its buffers are full, so this is `true` as soon as the
|
|
2717
|
+
* first frame exists. A stream that is still `false` at playback time would
|
|
2718
|
+
* leave the audio player buffering until FFmpeg catches up.
|
|
2719
|
+
*/
|
|
2720
|
+
get hasBufferedAudio() {
|
|
2721
|
+
return this.stream.readableLength > 0;
|
|
2722
|
+
}
|
|
2703
2723
|
/**
|
|
2704
2724
|
* Create a DisTubeStream to play with {@link DisTubeVoice}
|
|
2705
2725
|
* @param url - Stream URL
|
|
@@ -2787,13 +2807,15 @@ var DisTubeStream = class extends TypedEmitter2 {
|
|
|
2787
2807
|
const extraFilters = typeof outputArgs.af === "string" ? outputArgs.af : Array.isArray(outputArgs.af) ? outputArgs.af.filter(Boolean).join(",") : void 0;
|
|
2788
2808
|
delete outputArgs.af;
|
|
2789
2809
|
const primaryOpts = {
|
|
2790
|
-
reconnect: 1,
|
|
2791
|
-
reconnect_streamed: 1,
|
|
2792
|
-
reconnect_delay_max: 5,
|
|
2793
|
-
analyzeduration: 0,
|
|
2794
2810
|
hide_banner: true,
|
|
2795
2811
|
...ffmpeg.args.global,
|
|
2796
|
-
...
|
|
2812
|
+
...crossfade.primaryInputArgs ?? {
|
|
2813
|
+
reconnect: 1,
|
|
2814
|
+
reconnect_streamed: 1,
|
|
2815
|
+
reconnect_delay_max: 5,
|
|
2816
|
+
analyzeduration: 0,
|
|
2817
|
+
...ffmpeg.args.input
|
|
2818
|
+
},
|
|
2797
2819
|
ss: typeof primarySeek === "number" && primarySeek > 0 ? primarySeek.toString() : null,
|
|
2798
2820
|
i: url
|
|
2799
2821
|
};
|
|
@@ -3372,7 +3394,28 @@ var QueueManager = class extends GuildIdManager {
|
|
|
3372
3394
|
if (!primary?.stream.playFromSource || !primary.stream.url) return;
|
|
3373
3395
|
if (!secondary?.stream.playFromSource || !secondary.stream.url) return;
|
|
3374
3396
|
this.debug(`[${queue.id}] Warming up crossfade stream: ${song} -> ${nextSong}`);
|
|
3375
|
-
|
|
3397
|
+
const boundarySeek = Math.max(0, songDuration - fade);
|
|
3398
|
+
let primaryUrl = primary.stream.url;
|
|
3399
|
+
let primarySeek = boundarySeek;
|
|
3400
|
+
let primaryInputArgs;
|
|
3401
|
+
const prepare = this.options.crossfade.preparePrimaryInput;
|
|
3402
|
+
if (prepare) {
|
|
3403
|
+
try {
|
|
3404
|
+
const prepared = await prepare(primary.stream.url, { seek: boundarySeek, song });
|
|
3405
|
+
if (prepared?.url) {
|
|
3406
|
+
primaryUrl = prepared.url;
|
|
3407
|
+
if (typeof prepared.seek === "number" && Number.isFinite(prepared.seek) && prepared.seek >= 0) {
|
|
3408
|
+
primarySeek = prepared.seek;
|
|
3409
|
+
}
|
|
3410
|
+
primaryInputArgs = prepared.inputArgs;
|
|
3411
|
+
this.debug(`[${queue.id}] Crossfade primary input prepared by the adapter`);
|
|
3412
|
+
}
|
|
3413
|
+
} catch (e) {
|
|
3414
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
3415
|
+
this.debug(`[${queue.id}] Crossfade primary input preparation failed: ${errorMessage}`);
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
transitionStream = new DisTubeStream(primaryUrl, {
|
|
3376
3419
|
ffmpeg: {
|
|
3377
3420
|
path: this.options.ffmpeg.path,
|
|
3378
3421
|
args: {
|
|
@@ -3383,10 +3426,11 @@ var QueueManager = class extends GuildIdManager {
|
|
|
3383
3426
|
},
|
|
3384
3427
|
crossfade: {
|
|
3385
3428
|
duration: fade,
|
|
3386
|
-
primarySeek
|
|
3429
|
+
primarySeek,
|
|
3387
3430
|
secondaryUrl: secondary.stream.url,
|
|
3388
3431
|
inCurve: this.options.crossfade.curve,
|
|
3389
|
-
outCurve: this.options.crossfade.curve
|
|
3432
|
+
outCurve: this.options.crossfade.curve,
|
|
3433
|
+
primaryInputArgs
|
|
3390
3434
|
}
|
|
3391
3435
|
});
|
|
3392
3436
|
transitionStream.on("debug", (data) => this.emit("ffmpegDebug" /* FFMPEG_DEBUG */, `[${queue.id}] [crossfade] ${data}`));
|
|
@@ -3396,7 +3440,7 @@ var QueueManager = class extends GuildIdManager {
|
|
|
3396
3440
|
}
|
|
3397
3441
|
queue._crossfadeWarmup = transitionStream;
|
|
3398
3442
|
transitionStream.spawn();
|
|
3399
|
-
const boundaryMs = Math.max(0, (
|
|
3443
|
+
const boundaryMs = Math.max(0, (songDuration - queue.currentTime - fade) * 1e3);
|
|
3400
3444
|
queue._crossfadeTimeout = setTimeout(() => {
|
|
3401
3445
|
queue._crossfadeTimeout = void 0;
|
|
3402
3446
|
void this.#crossfadeSwapTask(queue, transitionStream);
|
|
@@ -3434,6 +3478,10 @@ var QueueManager = class extends GuildIdManager {
|
|
|
3434
3478
|
if (queue.stopped || queue.paused || queue.songs[0] !== song || queue._crossfadeWarmup !== transitionStream) {
|
|
3435
3479
|
return abort();
|
|
3436
3480
|
}
|
|
3481
|
+
if (!transitionStream.hasBufferedAudio) {
|
|
3482
|
+
this.debug(`[${queue.id}] Crossfade aborted: the transition stream is not ready`);
|
|
3483
|
+
return abort();
|
|
3484
|
+
}
|
|
3437
3485
|
this.debug(`[${queue.id}] Starting crossfade: ${song} -> ${queue.songs.length > 1 ? queue.songs[1] : song}`);
|
|
3438
3486
|
await queue.voice.play(transitionStream);
|
|
3439
3487
|
queue._crossfadeWarmup = void 0;
|