ziplayer 0.2.1 → 0.2.3-dev-1
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/structures/FilterManager.d.ts +1 -0
- package/dist/structures/FilterManager.d.ts.map +1 -1
- package/dist/structures/FilterManager.js +49 -10
- package/dist/structures/FilterManager.js.map +1 -1
- package/dist/structures/Player.d.ts +15 -2
- package/dist/structures/Player.d.ts.map +1 -1
- package/dist/structures/Player.js +123 -37
- package/dist/structures/Player.js.map +1 -1
- package/dist/types/extension.d.ts +114 -0
- package/dist/types/extension.d.ts.map +1 -0
- package/dist/types/extension.js +3 -0
- package/dist/types/extension.js.map +1 -0
- package/dist/types/fillter.d.ts +44 -0
- package/dist/types/fillter.d.ts.map +1 -0
- package/dist/types/fillter.js +226 -0
- package/dist/types/fillter.js.map +1 -0
- package/dist/types/index.d.ts +14 -209
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +17 -223
- package/dist/types/index.js.map +1 -1
- package/dist/types/plugin.d.ts +58 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +21 -0
- package/dist/types/plugin.js.map +1 -0
- package/package.json +7 -2
- package/src/structures/FilterManager.ts +303 -262
- package/src/structures/Player.ts +135 -41
- package/src/types/extension.ts +129 -0
- package/src/types/fillter.ts +264 -0
- package/src/types/index.ts +15 -443
- package/src/types/plugin.ts +57 -0
- package/dist/plugins/SoundCloudPlugin.d.ts +0 -22
- package/dist/plugins/SoundCloudPlugin.d.ts.map +0 -1
- package/dist/plugins/SoundCloudPlugin.js +0 -171
- package/dist/plugins/SoundCloudPlugin.js.map +0 -1
- package/dist/plugins/SpotifyPlugin.d.ts +0 -26
- package/dist/plugins/SpotifyPlugin.d.ts.map +0 -1
- package/dist/plugins/SpotifyPlugin.js +0 -183
- package/dist/plugins/SpotifyPlugin.js.map +0 -1
- package/dist/plugins/YouTubePlugin.d.ts +0 -25
- package/dist/plugins/YouTubePlugin.d.ts.map +0 -1
- package/dist/plugins/YouTubePlugin.js +0 -314
- package/dist/plugins/YouTubePlugin.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterManager.d.ts","sourceRoot":"","sources":["../../src/structures/FilterManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIvC,qBAAa,aAAa;IACzB,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAuB;
|
|
1
|
+
{"version":3,"file":"FilterManager.d.ts","sourceRoot":"","sources":["../../src/structures/FilterManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIvC,qBAAa,aAAa;IACzB,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,kBAAkB,CAAyB;IAC5C,UAAU,EAAE,WAAW,GAAG,UAAU,GAAG,KAAK,GAAG,WAAW,CAAS;gBAE9D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa;IAUlD;;;;;;OAMG;IACH,OAAO,IAAI,IAAI;IAoBf;;;;;;;OAOG;IACI,eAAe,IAAI,MAAM;IAKhC;;;;;;;OAOG;IACI,gBAAgB,IAAI,WAAW,EAAE;IAIxC;;;;;;;;OAQG;IACI,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAI7C;;;;;;;OAOG;IACI,mBAAmB,IAAI,WAAW,EAAE;IAI3C;;;;;;;;OAQG;IACI,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE;IAI5D;;;;;;;;;;;;;;;;;;OAkBG;IACU,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAyBzE;;;;;;;;;;;OAWG;IACU,YAAY,CAAC,OAAO,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ9E;;;;;;;OAOG;IACU,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW/D;;;;;;OAMG;IACU,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAOzC;;;;;;OAMG;IACU,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAE,MAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;CAiF5F"}
|
|
@@ -10,6 +10,7 @@ class FilterManager {
|
|
|
10
10
|
constructor(player, manager) {
|
|
11
11
|
this.activeFilters = [];
|
|
12
12
|
this.ffmpeg = null;
|
|
13
|
+
this.currentInputStream = null;
|
|
13
14
|
this.StreamType = "mp3";
|
|
14
15
|
this.player = player;
|
|
15
16
|
this.debug = (message, ...optionalParams) => {
|
|
@@ -27,6 +28,7 @@ class FilterManager {
|
|
|
27
28
|
*/
|
|
28
29
|
destroy() {
|
|
29
30
|
this.activeFilters = [];
|
|
31
|
+
// Destroy FFmpeg process
|
|
30
32
|
if (this.ffmpeg) {
|
|
31
33
|
try {
|
|
32
34
|
this.ffmpeg.destroy();
|
|
@@ -34,6 +36,14 @@ class FilterManager {
|
|
|
34
36
|
catch { }
|
|
35
37
|
this.ffmpeg = null;
|
|
36
38
|
}
|
|
39
|
+
// Destroy input stream
|
|
40
|
+
if (this.currentInputStream && typeof this.currentInputStream.destroy === "function") {
|
|
41
|
+
try {
|
|
42
|
+
this.currentInputStream.destroy();
|
|
43
|
+
}
|
|
44
|
+
catch { }
|
|
45
|
+
}
|
|
46
|
+
this.currentInputStream = null;
|
|
37
47
|
}
|
|
38
48
|
/**
|
|
39
49
|
* Get the combined FFmpeg filter string for all active filters
|
|
@@ -208,36 +218,65 @@ class FilterManager {
|
|
|
208
218
|
if (filterString) {
|
|
209
219
|
args.push("-af", filterString);
|
|
210
220
|
}
|
|
211
|
-
args.push("-f", this.StreamType === "webm/opus" ? "webm/opus"
|
|
221
|
+
args.push("-f", this.StreamType === "webm/opus" ? "webm/opus"
|
|
222
|
+
: this.StreamType === "ogg/opus" ? "ogg/opus"
|
|
223
|
+
: "mp3");
|
|
212
224
|
args.push("-ar", "48000", "-ac", "2");
|
|
213
225
|
try {
|
|
214
226
|
if (this.ffmpeg) {
|
|
215
227
|
this.ffmpeg.destroy();
|
|
228
|
+
this.ffmpeg = null;
|
|
229
|
+
}
|
|
230
|
+
// Destroy previous input stream
|
|
231
|
+
if (this.currentInputStream && typeof this.currentInputStream.destroy === "function") {
|
|
232
|
+
try {
|
|
233
|
+
this.currentInputStream.destroy();
|
|
234
|
+
}
|
|
235
|
+
catch { }
|
|
216
236
|
}
|
|
217
|
-
this.
|
|
237
|
+
this.currentInputStream = null;
|
|
218
238
|
}
|
|
219
239
|
catch { }
|
|
240
|
+
// Store reference to input stream
|
|
241
|
+
this.currentInputStream = stream;
|
|
220
242
|
this.ffmpeg = stream.pipe(new prism_media_1.default.FFmpeg({ args }));
|
|
221
243
|
this.ffmpeg.on("close", () => {
|
|
222
244
|
this.debug(`[FilterManager] FFmpeg filter+seek processing completed`);
|
|
223
|
-
|
|
224
|
-
this.ffmpeg
|
|
225
|
-
|
|
245
|
+
try {
|
|
246
|
+
if (this.ffmpeg) {
|
|
247
|
+
this.ffmpeg.destroy();
|
|
248
|
+
this.ffmpeg = null;
|
|
249
|
+
}
|
|
226
250
|
}
|
|
251
|
+
catch { }
|
|
227
252
|
});
|
|
228
253
|
this.ffmpeg.on("error", (err) => {
|
|
229
254
|
this.debug(`[FilterManager] FFmpeg filter+seek error:`, err);
|
|
230
|
-
|
|
231
|
-
this.ffmpeg
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
255
|
+
try {
|
|
256
|
+
if (this.ffmpeg) {
|
|
257
|
+
this.ffmpeg.destroy();
|
|
258
|
+
this.ffmpeg = null;
|
|
259
|
+
}
|
|
260
|
+
// Also destroy input stream on error
|
|
261
|
+
if (this.currentInputStream && typeof this.currentInputStream.destroy === "function") {
|
|
262
|
+
this.currentInputStream.destroy();
|
|
263
|
+
}
|
|
235
264
|
}
|
|
265
|
+
catch { }
|
|
266
|
+
this.currentInputStream = null;
|
|
236
267
|
});
|
|
237
268
|
return this.ffmpeg;
|
|
238
269
|
}
|
|
239
270
|
catch (error) {
|
|
240
271
|
this.debug(`[FilterManager] Error creating FFmpeg instance:`, error);
|
|
272
|
+
// Destroy input stream if FFmpeg fails
|
|
273
|
+
if (this.currentInputStream && typeof this.currentInputStream.destroy === "function") {
|
|
274
|
+
try {
|
|
275
|
+
this.currentInputStream.destroy();
|
|
276
|
+
}
|
|
277
|
+
catch { }
|
|
278
|
+
}
|
|
279
|
+
this.currentInputStream = null;
|
|
241
280
|
// Fallback to original stream if FFmpeg fails
|
|
242
281
|
throw error;
|
|
243
282
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterManager.js","sourceRoot":"","sources":["../../src/structures/FilterManager.ts"],"names":[],"mappings":";;;;;;AACA,oCAA8C;AAG9C,8DAA4C;AAK5C,MAAa,aAAa;
|
|
1
|
+
{"version":3,"file":"FilterManager.js","sourceRoot":"","sources":["../../src/structures/FilterManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
2
|
import { VoiceConnection, AudioPlayer as DiscordAudioPlayer } from "@discordjs/voice";
|
|
3
|
-
import { VoiceChannel } from "discord.js";
|
|
4
3
|
import { Readable } from "stream";
|
|
5
4
|
import type { BaseExtension } from "../extensions";
|
|
6
|
-
import type { Track, PlayerOptions, PlayerEvents, SourcePlugin, SearchResult, ProgressBarOptions, LoopMode, SaveOptions } from "../types";
|
|
5
|
+
import type { Track, PlayerOptions, PlayerEvents, SourcePlugin, SearchResult, ProgressBarOptions, LoopMode, SaveOptions, VoiceChannel } from "../types";
|
|
7
6
|
import type { PlayerManager } from "./PlayerManager";
|
|
8
7
|
import { Queue } from "./Queue";
|
|
9
8
|
import { PluginManager } from "../plugins";
|
|
@@ -71,6 +70,11 @@ export declare class Player extends EventEmitter {
|
|
|
71
70
|
private searchCacheTimestamps;
|
|
72
71
|
private ttsPlayer;
|
|
73
72
|
constructor(guildId: string, options: PlayerOptions | undefined, manager: PlayerManager);
|
|
73
|
+
/**
|
|
74
|
+
* Destroy current stream to prevent memory leaks
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
77
|
+
private destroyCurrentStream;
|
|
74
78
|
/**
|
|
75
79
|
* Search for tracks using the player's extensions and plugins
|
|
76
80
|
*
|
|
@@ -115,6 +119,15 @@ export declare class Player extends EventEmitter {
|
|
|
115
119
|
pluginCount: number;
|
|
116
120
|
ttsFiltered: boolean;
|
|
117
121
|
};
|
|
122
|
+
/**
|
|
123
|
+
* Get related tracks for a given track
|
|
124
|
+
* @param {Track} track Track to find related tracks for
|
|
125
|
+
* @returns {Track[]} Related tracks or empty array
|
|
126
|
+
* @example
|
|
127
|
+
* const related = await player.getRelatedTracks(track);
|
|
128
|
+
* console.log(`Found ${related.length} related tracks`);
|
|
129
|
+
*/
|
|
130
|
+
getRelatedTracks(track: Track): Promise<Track[]>;
|
|
118
131
|
private generateWillNext;
|
|
119
132
|
/**
|
|
120
133
|
* Play a track, search query, search result, or play from queue
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Player.d.ts","sourceRoot":"","sources":["../../src/structures/Player.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAKN,eAAe,EACf,WAAW,IAAI,kBAAkB,EAMjC,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"Player.d.ts","sourceRoot":"","sources":["../../src/structures/Player.ts"],"names":[],"mappings":"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"}
|
|
@@ -109,6 +109,25 @@ class Player extends events_1.EventEmitter {
|
|
|
109
109
|
this.ensureTTSPlayer();
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Destroy current stream to prevent memory leaks
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
destroyCurrentStream() {
|
|
117
|
+
try {
|
|
118
|
+
// Get the metadata from current resource to find the stream
|
|
119
|
+
if (this.currentResource) {
|
|
120
|
+
const stream = this.currentResource?.metadata?.stream || this.currentResource?.stream;
|
|
121
|
+
if (stream && typeof stream.destroy === "function") {
|
|
122
|
+
stream.destroy();
|
|
123
|
+
this.debug(`[Player] Destroyed current stream`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
this.debug(`[Player] Error destroying current stream:`, error);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
112
131
|
//#region Search
|
|
113
132
|
/**
|
|
114
133
|
* Search for tracks using the player's extensions and plugins
|
|
@@ -256,37 +275,53 @@ class Player extends events_1.EventEmitter {
|
|
|
256
275
|
ttsFiltered: allPlugins.length > plugins.length,
|
|
257
276
|
};
|
|
258
277
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
278
|
+
/**
|
|
279
|
+
* Get related tracks for a given track
|
|
280
|
+
* @param {Track} track Track to find related tracks for
|
|
281
|
+
* @returns {Track[]} Related tracks or empty array
|
|
282
|
+
* @example
|
|
283
|
+
* const related = await player.getRelatedTracks(track);
|
|
284
|
+
* console.log(`Found ${related.length} related tracks`);
|
|
285
|
+
*/
|
|
286
|
+
async getRelatedTracks(track) {
|
|
287
|
+
if (!track)
|
|
288
|
+
return [];
|
|
289
|
+
const preferred = this.pluginManager.findPlugin(track.url) || this.pluginManager.get(track.source);
|
|
265
290
|
const all = this.pluginManager.getAll();
|
|
266
291
|
const candidates = [...(preferred ? [preferred] : []), ...all.filter((p) => p !== preferred)].filter((p) => typeof p.getRelatedTracks === "function");
|
|
267
292
|
for (const p of candidates) {
|
|
268
293
|
try {
|
|
269
294
|
this.debug(`[Player] Trying related from plugin: ${p.name}`);
|
|
270
|
-
const related = await (0, timeout_1.withTimeout)(p.getRelatedTracks(
|
|
295
|
+
const related = await (0, timeout_1.withTimeout)(p.getRelatedTracks(track.url, {
|
|
271
296
|
limit: 10,
|
|
272
297
|
history: this.queue.previousTracks,
|
|
273
298
|
}), this.options.extractorTimeout ?? 15000, `getRelatedTracks timed out for ${p.name}`);
|
|
274
299
|
if (Array.isArray(related) && related.length > 0) {
|
|
275
|
-
|
|
276
|
-
const nextTrack = this.queue.nextTrack ? this.queue.nextTrack : related[randomchoice];
|
|
277
|
-
this.queue.willNextTrack(nextTrack);
|
|
278
|
-
this.queue.relatedTracks(related);
|
|
279
|
-
this.debug(`[Player] Will next track if autoplay: ${nextTrack?.title} (via ${p.name})`);
|
|
280
|
-
this.emit("willPlay", nextTrack, related);
|
|
281
|
-
return; // success
|
|
300
|
+
return related; // success
|
|
282
301
|
}
|
|
283
302
|
this.debug(`[Player] ${p.name} returned no related tracks`);
|
|
284
303
|
}
|
|
285
304
|
catch (err) {
|
|
286
305
|
this.debug(`[Player] getRelatedTracks error from ${p.name}:`, err);
|
|
306
|
+
return [];
|
|
287
307
|
// try next candidate
|
|
288
308
|
}
|
|
289
309
|
}
|
|
310
|
+
return [];
|
|
311
|
+
}
|
|
312
|
+
async generateWillNext() {
|
|
313
|
+
const lastTrack = this.queue.previousTracks[this.queue.previousTracks.length - 1] ?? this.queue.currentTrack;
|
|
314
|
+
if (!lastTrack)
|
|
315
|
+
return;
|
|
316
|
+
const related = await this.getRelatedTracks(lastTrack);
|
|
317
|
+
if (!related || related.length === 0)
|
|
318
|
+
return;
|
|
319
|
+
const randomchoice = Math.floor(Math.random() * related.length);
|
|
320
|
+
const nextTrack = this.queue.nextTrack ? this.queue.nextTrack : related[randomchoice];
|
|
321
|
+
this.queue.willNextTrack(nextTrack);
|
|
322
|
+
this.queue.relatedTracks(related);
|
|
323
|
+
this.debug(`[Player] Will next track if autoplay: ${nextTrack?.title}]`);
|
|
324
|
+
this.emit("willPlay", nextTrack, related);
|
|
290
325
|
}
|
|
291
326
|
//#endregion
|
|
292
327
|
//#region Play
|
|
@@ -305,12 +340,9 @@ class Player extends events_1.EventEmitter {
|
|
|
305
340
|
* await player.play(null); // play from queue
|
|
306
341
|
*/
|
|
307
342
|
async play(query, requestedBy) {
|
|
308
|
-
const debugInfo = query === null
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
? query
|
|
312
|
-
: "tracks" in query
|
|
313
|
-
? `${query.tracks.length} tracks`
|
|
343
|
+
const debugInfo = query === null ? "null"
|
|
344
|
+
: typeof query === "string" ? query
|
|
345
|
+
: "tracks" in query ? `${query.tracks.length} tracks`
|
|
314
346
|
: query.title || "unknown";
|
|
315
347
|
this.debug(`[Player] Play called with query: ${debugInfo}`);
|
|
316
348
|
this.clearLeaveTimeout();
|
|
@@ -463,10 +495,8 @@ class Player extends events_1.EventEmitter {
|
|
|
463
495
|
// Create AudioResource with better error handling
|
|
464
496
|
const resource = (0, voice_1.createAudioResource)(stream, {
|
|
465
497
|
metadata: track,
|
|
466
|
-
inputType: streamInfo.type === "webm/opus"
|
|
467
|
-
? voice_1.StreamType.
|
|
468
|
-
: streamInfo.type === "ogg/opus"
|
|
469
|
-
? voice_1.StreamType.OggOpus
|
|
498
|
+
inputType: streamInfo.type === "webm/opus" ? voice_1.StreamType.WebmOpus
|
|
499
|
+
: streamInfo.type === "ogg/opus" ? voice_1.StreamType.OggOpus
|
|
470
500
|
: voice_1.StreamType.Arbitrary,
|
|
471
501
|
inlineVolume: true,
|
|
472
502
|
});
|
|
@@ -478,10 +508,8 @@ class Player extends events_1.EventEmitter {
|
|
|
478
508
|
try {
|
|
479
509
|
const resource = (0, voice_1.createAudioResource)(streamInfo.stream, {
|
|
480
510
|
metadata: track,
|
|
481
|
-
inputType: streamInfo.type === "webm/opus"
|
|
482
|
-
? voice_1.StreamType.
|
|
483
|
-
: streamInfo.type === "ogg/opus"
|
|
484
|
-
? voice_1.StreamType.OggOpus
|
|
511
|
+
inputType: streamInfo.type === "webm/opus" ? voice_1.StreamType.WebmOpus
|
|
512
|
+
: streamInfo.type === "ogg/opus" ? voice_1.StreamType.OggOpus
|
|
485
513
|
: voice_1.StreamType.Arbitrary,
|
|
486
514
|
inlineVolume: true,
|
|
487
515
|
});
|
|
@@ -512,6 +540,18 @@ class Player extends events_1.EventEmitter {
|
|
|
512
540
|
// Kiểm tra nếu có stream thực sự để tạo AudioResource
|
|
513
541
|
if (streamInfo && streamInfo.stream) {
|
|
514
542
|
try {
|
|
543
|
+
// Destroy the old stream and resource before creating a new one
|
|
544
|
+
this.destroyCurrentStream();
|
|
545
|
+
if (this.currentResource) {
|
|
546
|
+
try {
|
|
547
|
+
const oldStream = this.currentResource._readableState?.stream || this.currentResource.stream;
|
|
548
|
+
if (oldStream && typeof oldStream.destroy === "function") {
|
|
549
|
+
oldStream.destroy();
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
catch { }
|
|
553
|
+
this.currentResource = null;
|
|
554
|
+
}
|
|
515
555
|
this.currentResource = await this.createResource(streamInfo, track, 0);
|
|
516
556
|
if (this.volumeInterval) {
|
|
517
557
|
clearInterval(this.volumeInterval);
|
|
@@ -530,10 +570,8 @@ class Player extends events_1.EventEmitter {
|
|
|
530
570
|
this.debug(`[Player] Attempting fallback without filters`);
|
|
531
571
|
const fallbackResource = (0, voice_1.createAudioResource)(streamInfo.stream, {
|
|
532
572
|
metadata: track,
|
|
533
|
-
inputType: streamInfo.type === "webm/opus"
|
|
534
|
-
? voice_1.StreamType.
|
|
535
|
-
: streamInfo.type === "ogg/opus"
|
|
536
|
-
? voice_1.StreamType.OggOpus
|
|
573
|
+
inputType: streamInfo.type === "webm/opus" ? voice_1.StreamType.WebmOpus
|
|
574
|
+
: streamInfo.type === "ogg/opus" ? voice_1.StreamType.OggOpus
|
|
537
575
|
: voice_1.StreamType.Arbitrary,
|
|
538
576
|
inlineVolume: true,
|
|
539
577
|
});
|
|
@@ -626,6 +664,8 @@ class Player extends events_1.EventEmitter {
|
|
|
626
664
|
async interruptWithTTSTrack(track) {
|
|
627
665
|
const wasPlaying = this.audioPlayer.state.status === voice_1.AudioPlayerStatus.Playing ||
|
|
628
666
|
this.audioPlayer.state.status === voice_1.AudioPlayerStatus.Buffering;
|
|
667
|
+
let ttsResource = null;
|
|
668
|
+
let ttsStream = null;
|
|
629
669
|
try {
|
|
630
670
|
if (!this.connection)
|
|
631
671
|
throw new Error("No voice connection for TTS");
|
|
@@ -635,10 +675,12 @@ class Player extends events_1.EventEmitter {
|
|
|
635
675
|
if (!streamInfo) {
|
|
636
676
|
throw new Error("No stream available for track: ${track.title}");
|
|
637
677
|
}
|
|
678
|
+
ttsStream = streamInfo.stream;
|
|
638
679
|
const resource = await this.createResource(streamInfo, track);
|
|
639
680
|
if (!resource) {
|
|
640
681
|
throw new Error("No resource available for track: ${track.title}");
|
|
641
682
|
}
|
|
683
|
+
ttsResource = resource;
|
|
642
684
|
if (resource.volume) {
|
|
643
685
|
resource.volume.setVolume((this.options?.tts?.volume ?? this?.volume ?? 100) / 100);
|
|
644
686
|
}
|
|
@@ -655,8 +697,14 @@ class Player extends events_1.EventEmitter {
|
|
|
655
697
|
await (0, voice_1.entersState)(ttsPlayer, voice_1.AudioPlayerStatus.Playing, 5000).catch(() => null);
|
|
656
698
|
// Derive timeoutMs from resource/track duration when available, with a sensible cap
|
|
657
699
|
const md = resource?.metadata ?? {};
|
|
658
|
-
const declared = typeof md.duration === "number" ? md.duration
|
|
659
|
-
|
|
700
|
+
const declared = typeof md.duration === "number" ? md.duration
|
|
701
|
+
: typeof track?.duration === "number" ? track.duration
|
|
702
|
+
: undefined;
|
|
703
|
+
const declaredMs = declared ?
|
|
704
|
+
declared > 1000 ?
|
|
705
|
+
declared
|
|
706
|
+
: declared * 1000
|
|
707
|
+
: undefined;
|
|
660
708
|
const cap = this.options?.tts?.Max_Time_TTS ?? 60000;
|
|
661
709
|
const idleTimeout = declaredMs ? Math.min(cap, Math.max(1000, declaredMs + 1500)) : cap;
|
|
662
710
|
await (0, voice_1.entersState)(ttsPlayer, voice_1.AudioPlayerStatus.Idle, idleTimeout).catch(() => null);
|
|
@@ -668,6 +716,15 @@ class Player extends events_1.EventEmitter {
|
|
|
668
716
|
this.emit("playerError", err);
|
|
669
717
|
}
|
|
670
718
|
finally {
|
|
719
|
+
// Clean up TTS stream and resource
|
|
720
|
+
try {
|
|
721
|
+
if (ttsStream && typeof ttsStream.destroy === "function") {
|
|
722
|
+
ttsStream.destroy();
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
catch (error) {
|
|
726
|
+
this.debug("[TTS] Error destroying stream:", error);
|
|
727
|
+
}
|
|
671
728
|
if (wasPlaying) {
|
|
672
729
|
try {
|
|
673
730
|
this.resume();
|
|
@@ -920,9 +977,19 @@ class Player extends events_1.EventEmitter {
|
|
|
920
977
|
}
|
|
921
978
|
// Apply filters if any are active
|
|
922
979
|
let finalStream = streamInfo.stream;
|
|
923
|
-
if (
|
|
980
|
+
if (saveOptions.filter || saveOptions.seek) {
|
|
981
|
+
try {
|
|
982
|
+
this.filter.clearAll();
|
|
983
|
+
this.filter.applyFilters(saveOptions.filter || []);
|
|
984
|
+
}
|
|
985
|
+
catch (err) {
|
|
986
|
+
this.debug(`[Player] Error applying save filters:`, err);
|
|
987
|
+
}
|
|
924
988
|
this.debug(`[Player] Applying filters to save stream: ${this.filter.getFilterString() || "none"}`);
|
|
925
|
-
finalStream = await this.filter.applyFiltersAndSeek(streamInfo.stream)
|
|
989
|
+
finalStream = await this.filter.applyFiltersAndSeek(streamInfo.stream, saveOptions.seek || 0).catch((err) => {
|
|
990
|
+
this.debug(`[Player] Error applying filters to save stream:`, err);
|
|
991
|
+
return streamInfo.stream; // Fallback to original stream
|
|
992
|
+
});
|
|
926
993
|
}
|
|
927
994
|
// Return the stream directly - caller can pipe it to fs.createWriteStream()
|
|
928
995
|
return finalStream;
|
|
@@ -1187,6 +1254,8 @@ class Player extends events_1.EventEmitter {
|
|
|
1187
1254
|
clearTimeout(this.leaveTimeout);
|
|
1188
1255
|
this.leaveTimeout = null;
|
|
1189
1256
|
}
|
|
1257
|
+
// Destroy current stream before stopping audio
|
|
1258
|
+
this.destroyCurrentStream();
|
|
1190
1259
|
this.audioPlayer.stop(true);
|
|
1191
1260
|
if (this.ttsPlayer) {
|
|
1192
1261
|
try {
|
|
@@ -1205,6 +1274,11 @@ class Player extends events_1.EventEmitter {
|
|
|
1205
1274
|
this.extensionManager.destroy();
|
|
1206
1275
|
this.isPlaying = false;
|
|
1207
1276
|
this.isPaused = false;
|
|
1277
|
+
// Clear any remaining intervals
|
|
1278
|
+
if (this.volumeInterval) {
|
|
1279
|
+
clearInterval(this.volumeInterval);
|
|
1280
|
+
this.volumeInterval = null;
|
|
1281
|
+
}
|
|
1208
1282
|
this.emit("playerDestroy");
|
|
1209
1283
|
this.removeAllListeners();
|
|
1210
1284
|
}
|
|
@@ -1248,10 +1322,22 @@ class Player extends events_1.EventEmitter {
|
|
|
1248
1322
|
}
|
|
1249
1323
|
// Create AudioResource with filters and seek to current position
|
|
1250
1324
|
const resource = await this.createResource(streaminfo, track, currentPosition);
|
|
1251
|
-
// Stop current playback and
|
|
1325
|
+
// Stop current playback and destroy old resource/stream
|
|
1252
1326
|
const wasPlaying = this.isPlaying;
|
|
1253
1327
|
const wasPaused = this.isPaused;
|
|
1254
1328
|
this.audioPlayer.stop();
|
|
1329
|
+
// Properly destroy the old resource and stream
|
|
1330
|
+
try {
|
|
1331
|
+
if (this.currentResource) {
|
|
1332
|
+
const oldStream = this.currentResource._readableState?.stream || this.currentResource.stream;
|
|
1333
|
+
if (oldStream && typeof oldStream.destroy === "function") {
|
|
1334
|
+
oldStream.destroy();
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
catch (error) {
|
|
1339
|
+
this.debug(`[Player] Error destroying old stream in refeshPlayerResource:`, error);
|
|
1340
|
+
}
|
|
1255
1341
|
this.currentResource = resource;
|
|
1256
1342
|
// Subscribe to new resource
|
|
1257
1343
|
if (this.connection) {
|