ziplayer 0.1.4 → 0.2.0
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/README.md +16 -0
- package/dist/extensions/index.d.ts +18 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +146 -3
- package/dist/extensions/index.js.map +1 -1
- package/dist/plugins/index.d.ts +12 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +55 -1
- package/dist/plugins/index.js.map +1 -1
- package/dist/structures/FilterManager.d.ts +126 -0
- package/dist/structures/FilterManager.d.ts.map +1 -0
- package/dist/structures/FilterManager.js +247 -0
- package/dist/structures/FilterManager.js.map +1 -0
- package/dist/structures/Player.d.ts +145 -135
- package/dist/structures/Player.d.ts.map +1 -1
- package/dist/structures/Player.js +662 -820
- package/dist/structures/Player.js.map +1 -1
- package/dist/structures/PlayerManager.d.ts +5 -1
- package/dist/structures/PlayerManager.d.ts.map +1 -1
- package/dist/structures/PlayerManager.js.map +1 -1
- package/dist/types/index.d.ts +129 -16
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +223 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +3 -2
- package/src/extensions/index.ts +165 -3
- package/src/plugins/index.ts +70 -0
- package/src/structures/FilterManager.ts +262 -0
- package/src/structures/Player.ts +729 -908
- package/src/structures/PlayerManager.ts +16 -11
- package/src/types/index.ts +347 -16
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FilterManager = void 0;
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const prism_media_1 = __importDefault(require("prism-media"));
|
|
9
|
+
class FilterManager {
|
|
10
|
+
constructor(player, manager) {
|
|
11
|
+
this.activeFilters = [];
|
|
12
|
+
this.ffmpeg = null;
|
|
13
|
+
this.StreamType = "mp3";
|
|
14
|
+
this.player = player;
|
|
15
|
+
this.debug = (message, ...optionalParams) => {
|
|
16
|
+
if (manager.debugEnabled) {
|
|
17
|
+
manager.emit("debug", `[FilterManager] ${message}`, ...optionalParams);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Destroy the filter manager
|
|
23
|
+
*
|
|
24
|
+
* @returns {void}
|
|
25
|
+
* @example
|
|
26
|
+
* player.filter.destroy();
|
|
27
|
+
*/
|
|
28
|
+
destroy() {
|
|
29
|
+
this.activeFilters = [];
|
|
30
|
+
if (this.ffmpeg) {
|
|
31
|
+
try {
|
|
32
|
+
this.ffmpeg.destroy();
|
|
33
|
+
}
|
|
34
|
+
catch { }
|
|
35
|
+
this.ffmpeg = null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the combined FFmpeg filter string for all active filters
|
|
40
|
+
*
|
|
41
|
+
* @returns {string} Combined FFmpeg filter string
|
|
42
|
+
* @example
|
|
43
|
+
* const filterString = player.getFilterString();
|
|
44
|
+
* console.log(`Filter string: ${filterString}`);
|
|
45
|
+
*/
|
|
46
|
+
getFilterString() {
|
|
47
|
+
if (this.activeFilters.length === 0)
|
|
48
|
+
return "";
|
|
49
|
+
return this.activeFilters.map((f) => f.ffmpegFilter).join(",");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get all currently applied filters
|
|
53
|
+
*
|
|
54
|
+
* @returns {AudioFilter[]} Array of active filters
|
|
55
|
+
* @example
|
|
56
|
+
* const filters = player.getActiveFilters();
|
|
57
|
+
* console.log(`Active filters: ${filters.map(f => f.name).join(', ')}`);
|
|
58
|
+
*/
|
|
59
|
+
getActiveFilters() {
|
|
60
|
+
return [...this.activeFilters];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Check if a specific filter is currently applied
|
|
64
|
+
*
|
|
65
|
+
* @param {string} filterName - Name of the filter to check
|
|
66
|
+
* @returns {boolean} True if filter is applied
|
|
67
|
+
* @example
|
|
68
|
+
* const hasBassBoost = player.hasFilter("bassboost");
|
|
69
|
+
* console.log(`Has bass boost: ${hasBassBoost}`);
|
|
70
|
+
*/
|
|
71
|
+
hasFilter(filterName) {
|
|
72
|
+
return this.activeFilters.some((f) => f.name === filterName);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get available predefined filters
|
|
76
|
+
*
|
|
77
|
+
* @returns {AudioFilter[]} Array of all predefined filters
|
|
78
|
+
* @example
|
|
79
|
+
* const availableFilters = player.getAvailableFilters();
|
|
80
|
+
* console.log(`Available filters: ${availableFilters.length}`);
|
|
81
|
+
*/
|
|
82
|
+
getAvailableFilters() {
|
|
83
|
+
return Object.values(types_1.PREDEFINED_FILTERS);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get filters by category
|
|
87
|
+
*
|
|
88
|
+
* @param {string} category - Category to filter by
|
|
89
|
+
* @returns {AudioFilter[]} Array of filters in the category
|
|
90
|
+
* @example
|
|
91
|
+
* const eqFilters = player.getFiltersByCategory("eq");
|
|
92
|
+
* console.log(`EQ filters: ${eqFilters.map(f => f.name).join(', ')}`);
|
|
93
|
+
*/
|
|
94
|
+
getFiltersByCategory(category) {
|
|
95
|
+
return Object.values(types_1.PREDEFINED_FILTERS).filter((f) => f.category === category);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Apply an audio filter to the player
|
|
99
|
+
*
|
|
100
|
+
* @param {string | AudioFilter} filter - Filter name or AudioFilter object
|
|
101
|
+
* @returns {Promise<boolean>} True if filter was applied successfully
|
|
102
|
+
* @example
|
|
103
|
+
* // Apply predefined filter to current track
|
|
104
|
+
* await player.applyFilter("bassboost");
|
|
105
|
+
*
|
|
106
|
+
* // Apply custom filter to current track
|
|
107
|
+
* await player.applyFilter({
|
|
108
|
+
* name: "custom",
|
|
109
|
+
* ffmpegFilter: "volume=1.5,treble=g=5",
|
|
110
|
+
* description: "Tăng âm lượng và âm cao"
|
|
111
|
+
* });
|
|
112
|
+
*
|
|
113
|
+
* // Apply filter without affecting current track
|
|
114
|
+
* await player.applyFilter("bassboost", false);
|
|
115
|
+
*/
|
|
116
|
+
async applyFilter(filter) {
|
|
117
|
+
if (!filter)
|
|
118
|
+
return false;
|
|
119
|
+
let audioFilter;
|
|
120
|
+
if (typeof filter === "string") {
|
|
121
|
+
const predefined = types_1.PREDEFINED_FILTERS[filter];
|
|
122
|
+
if (!predefined) {
|
|
123
|
+
this.debug(`[FilterManager] Predefined filter not found: ${filter}`);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
audioFilter = predefined;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
audioFilter = filter;
|
|
130
|
+
}
|
|
131
|
+
if (this.activeFilters.some((f) => f.name === audioFilter.name)) {
|
|
132
|
+
this.debug(`[FilterManager] Filter already applied: ${audioFilter.name}`);
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
this.activeFilters.push(audioFilter);
|
|
136
|
+
this.debug(`[FilterManager] Applied filter: ${audioFilter.name} - ${audioFilter.description}`);
|
|
137
|
+
return await this.player.refeshPlayerResource();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Apply multiple filters at once
|
|
141
|
+
*
|
|
142
|
+
* @param {(string | AudioFilter)[]} filters - Array of filter names or AudioFilter objects
|
|
143
|
+
* @returns {Promise<boolean>} True if all filters were applied successfully
|
|
144
|
+
* @example
|
|
145
|
+
* // Apply multiple filters to current track
|
|
146
|
+
* await player.applyFilters(["bassboost", "trebleboost"]);
|
|
147
|
+
*
|
|
148
|
+
* // Apply filters without affecting current track
|
|
149
|
+
* await player.applyFilters(["bassboost", "trebleboost"], false);
|
|
150
|
+
*/
|
|
151
|
+
async applyFilters(filters) {
|
|
152
|
+
let allApplied = true;
|
|
153
|
+
for (const f of filters) {
|
|
154
|
+
const ok = await this.applyFilter(f);
|
|
155
|
+
if (!ok)
|
|
156
|
+
allApplied = false;
|
|
157
|
+
}
|
|
158
|
+
return allApplied;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Remove an audio filter from the player
|
|
162
|
+
*
|
|
163
|
+
* @param {string} filterName - Name of the filter to remove
|
|
164
|
+
* @returns {boolean} True if filter was removed successfully
|
|
165
|
+
* @example
|
|
166
|
+
* player.removeFilter("bassboost");
|
|
167
|
+
*/
|
|
168
|
+
async removeFilter(filterName) {
|
|
169
|
+
const index = this.activeFilters.findIndex((f) => f.name === filterName);
|
|
170
|
+
if (index === -1) {
|
|
171
|
+
this.debug(`[FilterManager] Filter not found: ${filterName}`);
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
const removed = this.activeFilters.splice(index, 1)[0];
|
|
175
|
+
this.debug(`[FilterManager] Removed filter: ${removed.name}`);
|
|
176
|
+
return await this.player.refeshPlayerResource();
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Clear all audio filters from the player
|
|
180
|
+
*
|
|
181
|
+
* @returns {boolean} True if filters were cleared successfully
|
|
182
|
+
* @example
|
|
183
|
+
* player.clearFilters();
|
|
184
|
+
*/
|
|
185
|
+
async clearAll() {
|
|
186
|
+
const count = this.activeFilters.length;
|
|
187
|
+
this.activeFilters = [];
|
|
188
|
+
this.debug(`[FilterManager] Cleared ${count} filters`);
|
|
189
|
+
return await this.player.refeshPlayerResource();
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Apply filters and seek to a stream
|
|
193
|
+
*
|
|
194
|
+
* @param {Readable} stream - The stream to apply filters and seek to
|
|
195
|
+
* @param {number} position - The position to seek to in milliseconds (default: 0)
|
|
196
|
+
* @returns {Promise<Readable>} The stream with filters and seek applied
|
|
197
|
+
*/
|
|
198
|
+
async applyFiltersAndSeek(stream, position = -1) {
|
|
199
|
+
const filterString = this.getFilterString();
|
|
200
|
+
this.debug(`[FilterManager] Applying filters and seek to stream: ${filterString || "none"}, seek: ${position}ms`);
|
|
201
|
+
try {
|
|
202
|
+
const args = ["-analyzeduration", "0", "-loglevel", "0"];
|
|
203
|
+
if (position > 0) {
|
|
204
|
+
const seekSeconds = Math.floor(position / 1000);
|
|
205
|
+
args.push("-ss", seekSeconds.toString());
|
|
206
|
+
}
|
|
207
|
+
// Add filter if any are active
|
|
208
|
+
if (filterString) {
|
|
209
|
+
args.push("-af", filterString);
|
|
210
|
+
}
|
|
211
|
+
args.push("-f", this.StreamType === "webm/opus" ? "webm/opus" : this.StreamType === "ogg/opus" ? "ogg/opus" : "mp3");
|
|
212
|
+
args.push("-ar", "48000", "-ac", "2");
|
|
213
|
+
try {
|
|
214
|
+
if (this.ffmpeg) {
|
|
215
|
+
this.ffmpeg.destroy();
|
|
216
|
+
}
|
|
217
|
+
this.ffmpeg = null;
|
|
218
|
+
}
|
|
219
|
+
catch { }
|
|
220
|
+
this.ffmpeg = stream.pipe(new prism_media_1.default.FFmpeg({ args }));
|
|
221
|
+
this.ffmpeg.on("close", () => {
|
|
222
|
+
this.debug(`[FilterManager] FFmpeg filter+seek processing completed`);
|
|
223
|
+
if (this.ffmpeg) {
|
|
224
|
+
this.ffmpeg.destroy();
|
|
225
|
+
this.ffmpeg = null;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
this.ffmpeg.on("error", (err) => {
|
|
229
|
+
this.debug(`[FilterManager] FFmpeg filter+seek error:`, err);
|
|
230
|
+
if (this.ffmpeg) {
|
|
231
|
+
this.ffmpeg.destroy();
|
|
232
|
+
}
|
|
233
|
+
if (this.ffmpeg) {
|
|
234
|
+
this.ffmpeg = null;
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
return this.ffmpeg;
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
this.debug(`[FilterManager] Error creating FFmpeg instance:`, error);
|
|
241
|
+
// Fallback to original stream if FFmpeg fails
|
|
242
|
+
throw error;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
exports.FilterManager = FilterManager;
|
|
247
|
+
//# sourceMappingURL=FilterManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterManager.js","sourceRoot":"","sources":["../../src/structures/FilterManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
2
|
import { VoiceConnection, AudioPlayer as DiscordAudioPlayer } from "@discordjs/voice";
|
|
3
3
|
import { VoiceChannel } from "discord.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { Readable } from "stream";
|
|
5
|
+
import type { BaseExtension } from "../extensions";
|
|
6
|
+
import type { Track, PlayerOptions, PlayerEvents, SourcePlugin, SearchResult, ProgressBarOptions, LoopMode, SaveOptions } from "../types";
|
|
7
|
+
import type { PlayerManager } from "./PlayerManager";
|
|
6
8
|
import { Queue } from "./Queue";
|
|
7
9
|
import { PluginManager } from "../plugins";
|
|
8
|
-
import
|
|
10
|
+
import { ExtensionManager } from "../extensions";
|
|
9
11
|
export declare interface Player {
|
|
10
12
|
on<K extends keyof PlayerEvents>(event: K, listener: (...args: PlayerEvents[K]) => void): this;
|
|
11
13
|
emit<K extends keyof PlayerEvents>(event: K, ...args: PlayerEvents[K]): boolean;
|
|
@@ -56,73 +58,19 @@ export declare class Player extends EventEmitter {
|
|
|
56
58
|
isPaused: boolean;
|
|
57
59
|
options: PlayerOptions;
|
|
58
60
|
pluginManager: PluginManager;
|
|
61
|
+
extensionManager: ExtensionManager;
|
|
59
62
|
userdata?: Record<string, any>;
|
|
60
63
|
private manager;
|
|
61
64
|
private leaveTimeout;
|
|
62
65
|
private currentResource;
|
|
63
66
|
private volumeInterval;
|
|
64
67
|
private skipLoop;
|
|
65
|
-
private
|
|
66
|
-
private extensionContext;
|
|
67
|
-
private pluginCache;
|
|
68
|
-
private readonly PLUGIN_CACHE_TTL;
|
|
69
|
-
private pluginCacheTimestamps;
|
|
68
|
+
private filter;
|
|
70
69
|
private searchCache;
|
|
71
70
|
private readonly SEARCH_CACHE_TTL;
|
|
72
71
|
private searchCacheTimestamps;
|
|
73
|
-
/**
|
|
74
|
-
* Attach an extension to the player
|
|
75
|
-
*
|
|
76
|
-
* @param {BaseExtension} extension - The extension to attach
|
|
77
|
-
* @example
|
|
78
|
-
* player.attachExtension(new MyExtension());
|
|
79
|
-
*/
|
|
80
|
-
attachExtension(extension: BaseExtension): void;
|
|
81
|
-
/**
|
|
82
|
-
* Detach an extension from the player
|
|
83
|
-
*
|
|
84
|
-
* @param {BaseExtension} extension - The extension to detach
|
|
85
|
-
* @example
|
|
86
|
-
* player.detachExtension(new MyExtension());
|
|
87
|
-
*/
|
|
88
|
-
detachExtension(extension: BaseExtension): void;
|
|
89
|
-
/**
|
|
90
|
-
* Get all extensions attached to the player
|
|
91
|
-
*
|
|
92
|
-
* @returns {readonly BaseExtension[]} All attached extensions
|
|
93
|
-
* @example
|
|
94
|
-
* const extensions = player.getExtensions();
|
|
95
|
-
* console.log(`Extensions: ${extensions.length}`);
|
|
96
|
-
*/
|
|
97
|
-
getExtensions(): readonly BaseExtension[];
|
|
98
|
-
private invokeExtensionLifecycle;
|
|
99
|
-
private runBeforePlayHooks;
|
|
100
|
-
private runAfterPlayHooks;
|
|
101
|
-
private extensionsProvideSearch;
|
|
102
|
-
private extensionsProvideStream;
|
|
103
|
-
/**
|
|
104
|
-
* Start playing a specific track immediately, replacing the current resource.
|
|
105
|
-
*/
|
|
106
|
-
private startTrack;
|
|
107
72
|
private ttsPlayer;
|
|
108
|
-
private ttsQueue;
|
|
109
|
-
private ttsActive;
|
|
110
|
-
private clearLeaveTimeout;
|
|
111
|
-
private debug;
|
|
112
73
|
constructor(guildId: string, options: PlayerOptions | undefined, manager: PlayerManager);
|
|
113
|
-
private setupEventListeners;
|
|
114
|
-
private ensureTTSPlayer;
|
|
115
|
-
addPlugin(plugin: SourcePlugin): void;
|
|
116
|
-
removePlugin(name: string): boolean;
|
|
117
|
-
/**
|
|
118
|
-
* Connect to a voice channel
|
|
119
|
-
*
|
|
120
|
-
* @param {VoiceChannel} channel - Discord voice channel
|
|
121
|
-
* @returns {Promise<VoiceConnection>} The voice connection
|
|
122
|
-
* @example
|
|
123
|
-
* await player.connect(voiceChannel);
|
|
124
|
-
*/
|
|
125
|
-
connect(channel: VoiceChannel): Promise<VoiceConnection>;
|
|
126
74
|
/**
|
|
127
75
|
* Search for tracks using the player's extensions and plugins
|
|
128
76
|
*
|
|
@@ -134,67 +82,6 @@ export declare class Player extends EventEmitter {
|
|
|
134
82
|
* console.log(`Search result: ${result.tracks.length} tracks`);
|
|
135
83
|
*/
|
|
136
84
|
search(query: string, requestedBy: string): Promise<SearchResult>;
|
|
137
|
-
/**
|
|
138
|
-
* Play a track, search query, search result, or play from queue
|
|
139
|
-
*
|
|
140
|
-
* @param {string | Track | SearchResult | null} query - Track URL, search query, Track object, SearchResult, or null for play
|
|
141
|
-
* @param {string} requestedBy - User ID who requested the track
|
|
142
|
-
* @returns {Promise<boolean>} True if playback started successfully
|
|
143
|
-
* @example
|
|
144
|
-
* await player.play("Never Gonna Give You Up", userId); // Search query
|
|
145
|
-
* await player.play("https://youtube.com/watch?v=dQw4w9WgXcQ", userId); // Direct URL
|
|
146
|
-
* await player.play("tts: Hello everyone!", userId); // Text-to-Speech
|
|
147
|
-
* await player.play(trackObject, userId); // Track object
|
|
148
|
-
* await player.play(searchResult, userId); // SearchResult object
|
|
149
|
-
* await player.play(null); // play from queue
|
|
150
|
-
*/
|
|
151
|
-
play(query: string | Track | SearchResult | null, requestedBy?: string): Promise<boolean>;
|
|
152
|
-
/**
|
|
153
|
-
* Interrupt current music with a TTS track. Pauses music, swaps the
|
|
154
|
-
* subscription to a dedicated TTS player, plays TTS, then resumes.
|
|
155
|
-
*
|
|
156
|
-
* @param {Track} track - The track to interrupt with
|
|
157
|
-
* @returns {Promise<void>}
|
|
158
|
-
* @example
|
|
159
|
-
* await player.interruptWithTTSTrack(track);
|
|
160
|
-
*/
|
|
161
|
-
interruptWithTTSTrack(track: Track): Promise<void>;
|
|
162
|
-
/**
|
|
163
|
-
* Play queued TTS items sequentially
|
|
164
|
-
*
|
|
165
|
-
* @returns {Promise<void>}
|
|
166
|
-
* @example
|
|
167
|
-
* await player.playNextTTS();
|
|
168
|
-
*/
|
|
169
|
-
private playNextTTS;
|
|
170
|
-
/**
|
|
171
|
-
* Get cached plugin or find and cache a new one
|
|
172
|
-
* @param track The track to find plugin for
|
|
173
|
-
* @returns The matching plugin or null if not found
|
|
174
|
-
*/
|
|
175
|
-
private getCachedPlugin;
|
|
176
|
-
/**
|
|
177
|
-
* Clear expired cache entries
|
|
178
|
-
*/
|
|
179
|
-
private clearExpiredCache;
|
|
180
|
-
/**
|
|
181
|
-
* Clear all plugin cache entries
|
|
182
|
-
* @example
|
|
183
|
-
* player.clearPluginCache();
|
|
184
|
-
*/
|
|
185
|
-
clearPluginCache(): void;
|
|
186
|
-
/**
|
|
187
|
-
* Get plugin cache statistics
|
|
188
|
-
* @returns Cache statistics
|
|
189
|
-
* @example
|
|
190
|
-
* const stats = player.getPluginCacheStats();
|
|
191
|
-
* console.log(`Cache size: ${stats.size}, Hit rate: ${stats.hitRate}%`);
|
|
192
|
-
*/
|
|
193
|
-
getPluginCacheStats(): {
|
|
194
|
-
size: number;
|
|
195
|
-
hitRate: number;
|
|
196
|
-
expiredEntries: number;
|
|
197
|
-
};
|
|
198
85
|
/**
|
|
199
86
|
* Get cached search result or null if not found/expired
|
|
200
87
|
* @param query The search query
|
|
@@ -217,18 +104,6 @@ export declare class Player extends EventEmitter {
|
|
|
217
104
|
* player.clearSearchCache();
|
|
218
105
|
*/
|
|
219
106
|
clearSearchCache(): void;
|
|
220
|
-
/**
|
|
221
|
-
* Get search cache statistics
|
|
222
|
-
* @returns Search cache statistics
|
|
223
|
-
* @example
|
|
224
|
-
* const stats = player.getSearchCacheStats();
|
|
225
|
-
* console.log(`Search cache size: ${stats.size}, Expired: ${stats.expiredEntries}`);
|
|
226
|
-
*/
|
|
227
|
-
getSearchCacheStats(): {
|
|
228
|
-
size: number;
|
|
229
|
-
expiredEntries: number;
|
|
230
|
-
queries: string[];
|
|
231
|
-
};
|
|
232
107
|
/**
|
|
233
108
|
* Debug method to check for duplicate search calls
|
|
234
109
|
* @param query The search query to check
|
|
@@ -240,10 +115,57 @@ export declare class Player extends EventEmitter {
|
|
|
240
115
|
pluginCount: number;
|
|
241
116
|
ttsFiltered: boolean;
|
|
242
117
|
};
|
|
243
|
-
/** Build AudioResource for a given track using the plugin pipeline */
|
|
244
|
-
private resourceFromTrack;
|
|
245
118
|
private generateWillNext;
|
|
119
|
+
/**
|
|
120
|
+
* Play a track, search query, search result, or play from queue
|
|
121
|
+
*
|
|
122
|
+
* @param {string | Track | SearchResult | null} query - Track URL, search query, Track object, SearchResult, or null for play
|
|
123
|
+
* @param {string} requestedBy - User ID who requested the track
|
|
124
|
+
* @returns {Promise<boolean>} True if playback started successfully
|
|
125
|
+
* @example
|
|
126
|
+
* await player.play("Never Gonna Give You Up", userId); // Search query
|
|
127
|
+
* await player.play("https://youtube.com/watch?v=dQw4w9WgXcQ", userId); // Direct URL
|
|
128
|
+
* await player.play("tts: Hello everyone!", userId); // Text-to-Speech
|
|
129
|
+
* await player.play(trackObject, userId); // Track object
|
|
130
|
+
* await player.play(searchResult, userId); // SearchResult object
|
|
131
|
+
* await player.play(null); // play from queue
|
|
132
|
+
*/
|
|
133
|
+
play(query: string | Track | SearchResult | null, requestedBy?: string): Promise<boolean>;
|
|
134
|
+
/**
|
|
135
|
+
* Create AudioResource with filters and seek applied
|
|
136
|
+
*
|
|
137
|
+
* @param {StreamInfo} streamInfo - The stream information
|
|
138
|
+
* @param {Track} track - The track being processed
|
|
139
|
+
* @param {number} position - Position in milliseconds to seek to (0 = no seek)
|
|
140
|
+
* @returns {Promise<AudioResource>} The AudioResource with filters and seek applied
|
|
141
|
+
*/
|
|
142
|
+
private createResource;
|
|
143
|
+
private getStream;
|
|
144
|
+
/**
|
|
145
|
+
* Start playing a specific track immediately, replacing the current resource.
|
|
146
|
+
*/
|
|
147
|
+
private startTrack;
|
|
246
148
|
private playNext;
|
|
149
|
+
private ensureTTSPlayer;
|
|
150
|
+
/**
|
|
151
|
+
* Interrupt current music with a TTS track. Pauses music, swaps the
|
|
152
|
+
* subscription to a dedicated TTS player, plays TTS, then resumes.
|
|
153
|
+
*
|
|
154
|
+
* @param {Track} track - The track to interrupt with
|
|
155
|
+
* @returns {Promise<void>}
|
|
156
|
+
* @example
|
|
157
|
+
* await player.interruptWithTTSTrack(track);
|
|
158
|
+
*/
|
|
159
|
+
interruptWithTTSTrack(track: Track): Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* Connect to a voice channel
|
|
162
|
+
*
|
|
163
|
+
* @param {VoiceChannel} channel - Discord voice channel
|
|
164
|
+
* @returns {Promise<VoiceConnection>} The voice connection
|
|
165
|
+
* @example
|
|
166
|
+
* await player.connect(voiceChannel);
|
|
167
|
+
*/
|
|
168
|
+
connect(channel: VoiceChannel): Promise<VoiceConnection>;
|
|
247
169
|
/**
|
|
248
170
|
* Pause the current track
|
|
249
171
|
*
|
|
@@ -271,6 +193,20 @@ export declare class Player extends EventEmitter {
|
|
|
271
193
|
* console.log(`Stopped: ${stopped}`);
|
|
272
194
|
*/
|
|
273
195
|
stop(): boolean;
|
|
196
|
+
/**
|
|
197
|
+
* Seek to a specific position in the current track
|
|
198
|
+
*
|
|
199
|
+
* @param {number} position - Position in milliseconds to seek to
|
|
200
|
+
* @returns {Promise<boolean>} True if seek was successful
|
|
201
|
+
* @example
|
|
202
|
+
* // Seek to 30 seconds (30000ms)
|
|
203
|
+
* const success = await player.seek(30000);
|
|
204
|
+
* console.log(`Seek successful: ${success}`);
|
|
205
|
+
*
|
|
206
|
+
* // Seek to 1 minute 30 seconds (90000ms)
|
|
207
|
+
* await player.seek(90000);
|
|
208
|
+
*/
|
|
209
|
+
seek(position: number): Promise<boolean>;
|
|
274
210
|
/**
|
|
275
211
|
* Skip to the next track or skip to a specific index
|
|
276
212
|
*
|
|
@@ -291,6 +227,39 @@ export declare class Player extends EventEmitter {
|
|
|
291
227
|
* console.log(`Previous: ${previous}`);
|
|
292
228
|
*/
|
|
293
229
|
previous(): Promise<boolean>;
|
|
230
|
+
/**
|
|
231
|
+
* Save a track's stream to a file and return a Readable stream
|
|
232
|
+
*
|
|
233
|
+
* @param {Track} track - The track to save
|
|
234
|
+
* @param {SaveOptions | string} options - Save options or filename string (for backward compatibility)
|
|
235
|
+
* @returns {Promise<Readable>} A Readable stream containing the audio data
|
|
236
|
+
* @example
|
|
237
|
+
* // Save current track to file
|
|
238
|
+
* const track = player.currentTrack;
|
|
239
|
+
* if (track) {
|
|
240
|
+
* const stream = await player.save(track);
|
|
241
|
+
*
|
|
242
|
+
* // Use fs to write the stream to file
|
|
243
|
+
* const fs = require('fs');
|
|
244
|
+
* const writeStream = fs.createWriteStream('saved-song.mp3');
|
|
245
|
+
* stream.pipe(writeStream);
|
|
246
|
+
*
|
|
247
|
+
* writeStream.on('finish', () => {
|
|
248
|
+
* console.log('File saved successfully!');
|
|
249
|
+
* });
|
|
250
|
+
* }
|
|
251
|
+
*
|
|
252
|
+
* // Save any track by URL
|
|
253
|
+
* const searchResult = await player.search("Never Gonna Give You Up", userId);
|
|
254
|
+
* if (searchResult.tracks.length > 0) {
|
|
255
|
+
* const stream = await player.save(searchResult.tracks[0]);
|
|
256
|
+
* // Handle the stream...
|
|
257
|
+
* }
|
|
258
|
+
*
|
|
259
|
+
* // Backward compatibility - filename as string
|
|
260
|
+
* const stream = await player.save(track, "my-song.mp3");
|
|
261
|
+
*/
|
|
262
|
+
save(track: Track, options?: SaveOptions | string): Promise<Readable>;
|
|
294
263
|
/**
|
|
295
264
|
* Loop the current track or queue
|
|
296
265
|
*
|
|
@@ -400,7 +369,6 @@ export declare class Player extends EventEmitter {
|
|
|
400
369
|
* console.log(`Formatted time: ${formattedTime}`);
|
|
401
370
|
*/
|
|
402
371
|
formatTime(ms: number): string;
|
|
403
|
-
private scheduleLeave;
|
|
404
372
|
/**
|
|
405
373
|
* Destroy the player
|
|
406
374
|
*
|
|
@@ -409,6 +377,48 @@ export declare class Player extends EventEmitter {
|
|
|
409
377
|
* player.destroy();
|
|
410
378
|
*/
|
|
411
379
|
destroy(): void;
|
|
380
|
+
private scheduleLeave;
|
|
381
|
+
/**
|
|
382
|
+
* Refesh player resource (apply filter)
|
|
383
|
+
*
|
|
384
|
+
* @param {boolean} applyToCurrent - Apply filter for curent track
|
|
385
|
+
* @param {number} position - Position to seek to in milliseconds
|
|
386
|
+
* @returns {Promise<boolean>}
|
|
387
|
+
* @example
|
|
388
|
+
* const refreshed = await player.refeshPlayerResource(true, 1000);
|
|
389
|
+
* console.log(`Refreshed: ${refreshed}`);
|
|
390
|
+
*/
|
|
391
|
+
refeshPlayerResource(applyToCurrent?: boolean, position?: number): Promise<boolean>;
|
|
392
|
+
/**
|
|
393
|
+
* Attach an extension to the player
|
|
394
|
+
*
|
|
395
|
+
* @param {BaseExtension} extension - The extension to attach
|
|
396
|
+
* @example
|
|
397
|
+
* player.attachExtension(new MyExtension());
|
|
398
|
+
*/
|
|
399
|
+
attachExtension(extension: BaseExtension): void;
|
|
400
|
+
/**
|
|
401
|
+
* Detach an extension from the player
|
|
402
|
+
*
|
|
403
|
+
* @param {BaseExtension} extension - The extension to detach
|
|
404
|
+
* @example
|
|
405
|
+
* player.detachExtension(new MyExtension());
|
|
406
|
+
*/
|
|
407
|
+
detachExtension(extension: BaseExtension): void;
|
|
408
|
+
/**
|
|
409
|
+
* Get all extensions attached to the player
|
|
410
|
+
*
|
|
411
|
+
* @returns {readonly BaseExtension[]} All attached extensions
|
|
412
|
+
* @example
|
|
413
|
+
* const extensions = player.getExtensions();
|
|
414
|
+
* console.log(`Extensions: ${extensions.length}`);
|
|
415
|
+
*/
|
|
416
|
+
getExtensions(): readonly BaseExtension[];
|
|
417
|
+
private clearLeaveTimeout;
|
|
418
|
+
private debug;
|
|
419
|
+
private setupEventListeners;
|
|
420
|
+
addPlugin(plugin: SourcePlugin): void;
|
|
421
|
+
removePlugin(name: string): boolean;
|
|
412
422
|
/**
|
|
413
423
|
* Get the size of the queue
|
|
414
424
|
*
|
|
@@ -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,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Player.d.ts","sourceRoot":"","sources":["../../src/structures/Player.ts"],"names":[],"mappings":"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"}
|