distube 4.2.0 → 4.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/README.md +1 -1
- package/dist/index.d.ts +47 -21
- package/dist/index.js +98 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
# DisTube
|
|
21
21
|
|
|
22
|
-
A Discord.js module
|
|
22
|
+
A powerful Discord.js module for simplifying music commands and effortless playback of various sources with integrated audio filters.
|
|
23
23
|
|
|
24
24
|
[DisTube Support Server](https://discord.gg/feaDd9h) - [Frequently Asked Questions](https://discord.gg/feaDd9h)
|
|
25
25
|
|
package/dist/index.d.ts
CHANGED
|
@@ -127,7 +127,7 @@ type DisTubeOptions = {
|
|
|
127
127
|
searchCooldown?: number;
|
|
128
128
|
/**
|
|
129
129
|
* YouTube cookies. Guide: {@link
|
|
130
|
-
* https://
|
|
130
|
+
* https://github.com/skick1234/DisTube/wiki/YouTube-Cookies | YouTube Cookies}
|
|
131
131
|
*/
|
|
132
132
|
youtubeCookie?: Cookie[] | string;
|
|
133
133
|
/**
|
|
@@ -167,12 +167,31 @@ type DisTubeOptions = {
|
|
|
167
167
|
directLink?: boolean;
|
|
168
168
|
/**
|
|
169
169
|
* FFmpeg path
|
|
170
|
+
* @deprecated
|
|
170
171
|
*/
|
|
171
172
|
ffmpegPath?: string;
|
|
172
173
|
/**
|
|
173
174
|
* FFmpeg default arguments
|
|
174
|
-
|
|
175
|
-
|
|
175
|
+
* @deprecated
|
|
176
|
+
*/
|
|
177
|
+
ffmpegDefaultArgs?: FFmpegArgs;
|
|
178
|
+
/**
|
|
179
|
+
* FFmpeg options
|
|
180
|
+
*/
|
|
181
|
+
ffmpeg?: {
|
|
182
|
+
/**
|
|
183
|
+
* FFmpeg path
|
|
184
|
+
*/
|
|
185
|
+
path?: string;
|
|
186
|
+
/**
|
|
187
|
+
* FFmpeg default arguments
|
|
188
|
+
*/
|
|
189
|
+
args?: {
|
|
190
|
+
global?: FFmpegArgs;
|
|
191
|
+
input?: FFmpegArgs;
|
|
192
|
+
output?: FFmpegArgs;
|
|
193
|
+
};
|
|
194
|
+
};
|
|
176
195
|
};
|
|
177
196
|
/**
|
|
178
197
|
* Data that can be resolved to give a guild id string. This can be:
|
|
@@ -364,7 +383,15 @@ declare enum Events {
|
|
|
364
383
|
SEARCH_RESULT = "searchResult",
|
|
365
384
|
FFMPEG_DEBUG = "ffmpegDebug"
|
|
366
385
|
}
|
|
367
|
-
type
|
|
386
|
+
type FFmpegArgs = Record<string, string | number | boolean | Array<string | null | undefined> | null | undefined>;
|
|
387
|
+
type FFmpegOptions = {
|
|
388
|
+
path: string;
|
|
389
|
+
args: {
|
|
390
|
+
global: FFmpegArgs;
|
|
391
|
+
input: FFmpegArgs;
|
|
392
|
+
output: FFmpegArgs;
|
|
393
|
+
};
|
|
394
|
+
};
|
|
368
395
|
|
|
369
396
|
/**
|
|
370
397
|
* Default DisTube audio filters.
|
|
@@ -387,11 +414,6 @@ declare const defaultOptions: {
|
|
|
387
414
|
joinNewVoiceChannel: true;
|
|
388
415
|
streamType: StreamType.OPUS;
|
|
389
416
|
directLink: true;
|
|
390
|
-
ffmpegPath: string;
|
|
391
|
-
ffmpegDefaultArgs: {
|
|
392
|
-
analyzeduration: number;
|
|
393
|
-
hide_banner: true;
|
|
394
|
-
};
|
|
395
417
|
};
|
|
396
418
|
|
|
397
419
|
declare const ERROR_MESSAGES: {
|
|
@@ -413,6 +435,8 @@ declare const ERROR_MESSAGES: {
|
|
|
413
435
|
VOICE_RECONNECT_FAILED: string;
|
|
414
436
|
VOICE_DIFFERENT_GUILD: string;
|
|
415
437
|
VOICE_DIFFERENT_CLIENT: string;
|
|
438
|
+
FFMPEG_EXITED: (code: number) => string;
|
|
439
|
+
FFMPEG_NOT_INSTALLED: (path: string) => string;
|
|
416
440
|
NO_QUEUE: string;
|
|
417
441
|
QUEUE_EXIST: string;
|
|
418
442
|
PAUSED: string;
|
|
@@ -759,19 +783,18 @@ declare class DisTubeVoice extends TypedEmitter<DisTubeVoiceEvents> {
|
|
|
759
783
|
}
|
|
760
784
|
|
|
761
785
|
interface StreamOptions {
|
|
762
|
-
ffmpeg:
|
|
763
|
-
path: string;
|
|
764
|
-
args: FFmpegOptions;
|
|
765
|
-
};
|
|
786
|
+
ffmpeg: FFmpegOptions;
|
|
766
787
|
seek?: number;
|
|
767
788
|
type?: StreamType;
|
|
768
789
|
}
|
|
769
790
|
declare const chooseBestVideoFormat: ({ duration, formats, isLive }: Song) => ytdl.videoFormat | undefined;
|
|
791
|
+
declare const checkFFmpeg: (distube: DisTube) => void;
|
|
770
792
|
/**
|
|
771
793
|
* Create a stream to play with {@link DisTubeVoice}
|
|
772
794
|
*/
|
|
773
795
|
declare class DisTubeStream extends TypedEmitter<{
|
|
774
796
|
debug: (debug: string) => Awaitable;
|
|
797
|
+
error: (error: Error) => Awaitable;
|
|
775
798
|
}> {
|
|
776
799
|
private killed;
|
|
777
800
|
process: ChildProcess;
|
|
@@ -899,8 +922,11 @@ declare class Options {
|
|
|
899
922
|
joinNewVoiceChannel: boolean;
|
|
900
923
|
streamType: StreamType;
|
|
901
924
|
directLink: boolean;
|
|
902
|
-
|
|
903
|
-
|
|
925
|
+
/** @deprecated */
|
|
926
|
+
ffmpegPath: undefined;
|
|
927
|
+
/** @deprecated */
|
|
928
|
+
ffmpegDefaultArgs: undefined;
|
|
929
|
+
ffmpeg: FFmpegOptions;
|
|
904
930
|
constructor(options: DisTubeOptions);
|
|
905
931
|
}
|
|
906
932
|
|
|
@@ -1011,7 +1037,7 @@ declare class FilterManager extends BaseManager<Filter> {
|
|
|
1011
1037
|
* Array of enabled filters
|
|
1012
1038
|
*/
|
|
1013
1039
|
get values(): Filter[];
|
|
1014
|
-
get ffmpegArgs():
|
|
1040
|
+
get ffmpegArgs(): FFmpegArgs;
|
|
1015
1041
|
toString(): string;
|
|
1016
1042
|
}
|
|
1017
1043
|
|
|
@@ -1616,9 +1642,9 @@ declare class DisTube extends TypedEmitter<TypedDisTubeEvents> {
|
|
|
1616
1642
|
readonly filters: Filters;
|
|
1617
1643
|
/**
|
|
1618
1644
|
* @deprecated Use `youtubeCookie: Cookie[]` instead. Guide: {@link
|
|
1619
|
-
* https://
|
|
1645
|
+
* https://github.com/skick1234/DisTube/wiki/YouTube-Cookies | YouTube Cookies}
|
|
1620
1646
|
*/
|
|
1621
|
-
constructor(client: Client,
|
|
1647
|
+
constructor(client: Client, opts: DisTubeOptions & {
|
|
1622
1648
|
youtubeCookie: string;
|
|
1623
1649
|
});
|
|
1624
1650
|
/**
|
|
@@ -1638,9 +1664,9 @@ declare class DisTube extends TypedEmitter<TypedDisTubeEvents> {
|
|
|
1638
1664
|
* @throws {@link DisTubeError}
|
|
1639
1665
|
*
|
|
1640
1666
|
* @param client - Discord.JS client
|
|
1641
|
-
* @param
|
|
1667
|
+
* @param opts - Custom DisTube options
|
|
1642
1668
|
*/
|
|
1643
|
-
constructor(client: Client,
|
|
1669
|
+
constructor(client: Client, opts?: DisTubeOptions);
|
|
1644
1670
|
static get version(): string;
|
|
1645
1671
|
/**
|
|
1646
1672
|
* DisTube version
|
|
@@ -1965,4 +1991,4 @@ declare class DisTube extends TypedEmitter<TypedDisTubeEvents> {
|
|
|
1965
1991
|
emitError(error: Error, channel?: GuildTextBasedChannel): void;
|
|
1966
1992
|
}
|
|
1967
1993
|
|
|
1968
|
-
export { type Awaitable, BaseManager, type Chapter, type CustomPlaylistOptions, CustomPlugin, DirectLinkPlugin, DisTube, DisTubeBase, DisTubeError, type DisTubeEvents, DisTubeHandler, type DisTubeOptions, DisTubeStream, DisTubeVoice, type DisTubeVoiceEvents, DisTubeVoiceManager, Events, ExtractorPlugin, type FFmpegOptions, type Filter, FilterManager, type FilterResolvable, type Filters, GuildIdManager, type GuildIdResolvable, Options, type OtherSongInfo, type PlayHandlerOptions, type PlayOptions, Playlist, type PlaylistInfo, Plugin, PluginType, Queue, QueueManager, type RelatedSong, RepeatMode, type ResolveOptions, type ResolvePlaylistOptions, type SearchResult, SearchResultPlaylist, SearchResultType, SearchResultVideo, Song, StreamType, TaskQueue, type TypedDisTubeEvents, checkIntents, checkInvalidKey, chooseBestVideoFormat, DisTube as default, defaultFilters, defaultOptions, formatDuration, isClientInstance, isGuildInstance, isMemberInstance, isMessageInstance, isNsfwChannel, isObject, isRecord, isSnowflake, isSupportedVoiceChannel, isTextChannelInstance, isTruthy, isURL, isVoiceChannelEmpty, objectKeys, parseNumber, resolveGuildId, toSecond, version };
|
|
1994
|
+
export { type Awaitable, BaseManager, type Chapter, type CustomPlaylistOptions, CustomPlugin, DirectLinkPlugin, DisTube, DisTubeBase, DisTubeError, type DisTubeEvents, DisTubeHandler, type DisTubeOptions, DisTubeStream, DisTubeVoice, type DisTubeVoiceEvents, DisTubeVoiceManager, Events, ExtractorPlugin, type FFmpegArgs, type FFmpegOptions, type Filter, FilterManager, type FilterResolvable, type Filters, GuildIdManager, type GuildIdResolvable, Options, type OtherSongInfo, type PlayHandlerOptions, type PlayOptions, Playlist, type PlaylistInfo, Plugin, PluginType, Queue, QueueManager, type RelatedSong, RepeatMode, type ResolveOptions, type ResolvePlaylistOptions, type SearchResult, SearchResultPlaylist, SearchResultType, SearchResultVideo, Song, StreamType, TaskQueue, type TypedDisTubeEvents, checkFFmpeg, checkIntents, checkInvalidKey, chooseBestVideoFormat, DisTube as default, defaultFilters, defaultOptions, formatDuration, isClientInstance, isGuildInstance, isMemberInstance, isMessageInstance, isNsfwChannel, isObject, isRecord, isSnowflake, isSupportedVoiceChannel, isTextChannelInstance, isTruthy, isURL, isVoiceChannelEmpty, objectKeys, parseNumber, resolveGuildId, toSecond, version };
|
package/dist/index.js
CHANGED
|
@@ -63,7 +63,7 @@ var require_package = __commonJS({
|
|
|
63
63
|
"package.json"(exports2, module2) {
|
|
64
64
|
module2.exports = {
|
|
65
65
|
name: "distube",
|
|
66
|
-
version: "4.2.
|
|
66
|
+
version: "4.2.2",
|
|
67
67
|
description: "A Discord.js module to simplify your music commands and play songs with audio filters on Discord without any API key.",
|
|
68
68
|
main: "./dist/index.js",
|
|
69
69
|
types: "./dist/index.d.ts",
|
|
@@ -202,6 +202,7 @@ __export(src_exports, {
|
|
|
202
202
|
Song: () => Song,
|
|
203
203
|
StreamType: () => StreamType,
|
|
204
204
|
TaskQueue: () => TaskQueue,
|
|
205
|
+
checkFFmpeg: () => checkFFmpeg,
|
|
205
206
|
checkIntents: () => checkIntents,
|
|
206
207
|
checkInvalidKey: () => checkInvalidKey,
|
|
207
208
|
chooseBestVideoFormat: () => chooseBestVideoFormat,
|
|
@@ -307,12 +308,7 @@ var defaultOptions = {
|
|
|
307
308
|
emitAddListWhenCreatingQueue: true,
|
|
308
309
|
joinNewVoiceChannel: true,
|
|
309
310
|
streamType: 0 /* OPUS */,
|
|
310
|
-
directLink: true
|
|
311
|
-
ffmpegPath: "ffmpeg",
|
|
312
|
-
ffmpegDefaultArgs: {
|
|
313
|
-
analyzeduration: 0,
|
|
314
|
-
hide_banner: true
|
|
315
|
-
}
|
|
311
|
+
directLink: true
|
|
316
312
|
};
|
|
317
313
|
|
|
318
314
|
// src/struct/DisTubeError.ts
|
|
@@ -336,6 +332,8 @@ var ERROR_MESSAGES = {
|
|
|
336
332
|
VOICE_RECONNECT_FAILED: "Cannot reconnect to the voice channel",
|
|
337
333
|
VOICE_DIFFERENT_GUILD: "Cannot join a voice channel in a different guild",
|
|
338
334
|
VOICE_DIFFERENT_CLIENT: "Cannot join a voice channel created by a different client",
|
|
335
|
+
FFMPEG_EXITED: (code) => `ffmpeg exited with code ${code}`,
|
|
336
|
+
FFMPEG_NOT_INSTALLED: (path) => `ffmpeg is not installed at '${path}' path`,
|
|
339
337
|
NO_QUEUE: "There is no playing queue in this guild",
|
|
340
338
|
QUEUE_EXIST: "This guild has a Queue already",
|
|
341
339
|
PAUSED: "The queue has been paused already",
|
|
@@ -962,7 +960,7 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
962
960
|
*/
|
|
963
961
|
play(dtStream) {
|
|
964
962
|
this.emittedError = false;
|
|
965
|
-
dtStream.
|
|
963
|
+
dtStream.on("error", (error) => {
|
|
966
964
|
if (this.emittedError || error.code === "ERR_STREAM_PREMATURE_CLOSE")
|
|
967
965
|
return;
|
|
968
966
|
this.emittedError = true;
|
|
@@ -1080,11 +1078,41 @@ __name(_DisTubeVoice, "DisTubeVoice");
|
|
|
1080
1078
|
var DisTubeVoice = _DisTubeVoice;
|
|
1081
1079
|
|
|
1082
1080
|
// src/core/DisTubeStream.ts
|
|
1083
|
-
var import_child_process = require("child_process");
|
|
1084
1081
|
var import_node_stream = require("stream");
|
|
1082
|
+
var import_child_process = require("child_process");
|
|
1085
1083
|
var import_tiny_typed_emitter2 = require("tiny-typed-emitter");
|
|
1086
1084
|
var import_voice2 = require("@discordjs/voice");
|
|
1087
1085
|
var chooseBestVideoFormat = /* @__PURE__ */ __name(({ duration, formats, isLive }) => formats && formats.filter((f) => f.hasAudio && (duration < 10 * 60 || f.hasVideo) && (!isLive || f.isHLS)).sort((a, b) => Number(b.audioBitrate) - Number(a.audioBitrate) || Number(a.bitrate) - Number(b.bitrate))[0], "chooseBestVideoFormat");
|
|
1086
|
+
var checked = process.env.NODE_ENV === "test";
|
|
1087
|
+
var checkFFmpeg = /* @__PURE__ */ __name((distube) => {
|
|
1088
|
+
if (checked)
|
|
1089
|
+
return;
|
|
1090
|
+
const path = distube.options.ffmpeg.path;
|
|
1091
|
+
const debug = /* @__PURE__ */ __name((str) => distube.emit("ffmpegDebug" /* FFMPEG_DEBUG */, str), "debug");
|
|
1092
|
+
try {
|
|
1093
|
+
debug(`[test] spawn ffmpeg at '${path}' path`);
|
|
1094
|
+
const process2 = (0, import_child_process.spawnSync)(path, ["-h"], { windowsHide: true, shell: true, encoding: "utf-8" });
|
|
1095
|
+
if (process2.error)
|
|
1096
|
+
throw process2.error;
|
|
1097
|
+
if (process2.stderr && !process2.stdout)
|
|
1098
|
+
throw new Error(process2.stderr);
|
|
1099
|
+
const result = process2.output.join("\n");
|
|
1100
|
+
const version2 = /ffmpeg version (\S+)/iu.exec(result)?.[1];
|
|
1101
|
+
if (!version2)
|
|
1102
|
+
throw new Error("Invalid FFmpeg version");
|
|
1103
|
+
debug(`[test] ffmpeg version: ${version2}`);
|
|
1104
|
+
if (result.includes("--enable-libopus")) {
|
|
1105
|
+
debug("[test] ffmpeg supports libopus");
|
|
1106
|
+
} else {
|
|
1107
|
+
debug("[test] ffmpeg does not support libopus");
|
|
1108
|
+
distube.options.streamType = 1 /* RAW */;
|
|
1109
|
+
}
|
|
1110
|
+
} catch (e) {
|
|
1111
|
+
debug(`[test] failed to spawn ffmpeg at '${path}': ${e?.stack ?? e}`);
|
|
1112
|
+
throw new DisTubeError("FFMPEG_NOT_INSTALLED", path);
|
|
1113
|
+
}
|
|
1114
|
+
checked = true;
|
|
1115
|
+
}, "checkFFmpeg");
|
|
1088
1116
|
var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.TypedEmitter {
|
|
1089
1117
|
/**
|
|
1090
1118
|
* Create a DisTubeStream to play with {@link DisTubeVoice}
|
|
@@ -1103,13 +1131,16 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
1103
1131
|
this.type = !type ? import_voice2.StreamType.OggOpus : import_voice2.StreamType.Raw;
|
|
1104
1132
|
const opts = {
|
|
1105
1133
|
reconnect: 1,
|
|
1106
|
-
reconnect_on_network_error: 1,
|
|
1107
1134
|
reconnect_streamed: 1,
|
|
1108
1135
|
reconnect_delay_max: 5,
|
|
1136
|
+
analyzeduration: 0,
|
|
1137
|
+
hide_banner: true,
|
|
1138
|
+
...ffmpeg.args.global,
|
|
1139
|
+
...ffmpeg.args.input,
|
|
1109
1140
|
i: url,
|
|
1110
1141
|
ar: 48e3,
|
|
1111
1142
|
ac: 2,
|
|
1112
|
-
...ffmpeg.args
|
|
1143
|
+
...ffmpeg.args.output
|
|
1113
1144
|
};
|
|
1114
1145
|
if (!type) {
|
|
1115
1146
|
opts.f = "opus";
|
|
@@ -1119,8 +1150,6 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
1119
1150
|
}
|
|
1120
1151
|
if (typeof seek === "number" && seek > 0)
|
|
1121
1152
|
opts.ss = seek.toString();
|
|
1122
|
-
if (typeof ffmpeg.args === "object")
|
|
1123
|
-
Object.assign(opts, ffmpeg.args);
|
|
1124
1153
|
this.process = (0, import_child_process.spawn)(
|
|
1125
1154
|
ffmpeg.path,
|
|
1126
1155
|
[
|
|
@@ -1129,19 +1158,26 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
1129
1158
|
).flat(),
|
|
1130
1159
|
"pipe:1"
|
|
1131
1160
|
],
|
|
1132
|
-
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
1133
|
-
).on("error", (err) =>
|
|
1161
|
+
{ stdio: ["ignore", "pipe", "pipe"], shell: false, windowsHide: true }
|
|
1162
|
+
).on("error", (err) => {
|
|
1163
|
+
this.debug(`[process] error: ${err.message}`);
|
|
1164
|
+
this.emit("error", err);
|
|
1165
|
+
}).on("exit", (code, signal) => {
|
|
1134
1166
|
this.debug(`[process] exit: code=${code ?? "unknown"} signal=${signal ?? "unknown"}`);
|
|
1135
1167
|
if (!code || [0, 255].includes(code))
|
|
1136
1168
|
return;
|
|
1137
1169
|
this.debug(`[process] error: ffmpeg exited with code ${code}`);
|
|
1170
|
+
this.emit("error", new DisTubeError("FFMPEG_EXITED", code));
|
|
1138
1171
|
});
|
|
1139
1172
|
if (!this.process.stdout || !this.process.stderr) {
|
|
1140
1173
|
this.kill();
|
|
1141
1174
|
throw new Error("Failed to create ffmpeg process");
|
|
1142
1175
|
}
|
|
1143
1176
|
this.stream = new import_node_stream.PassThrough();
|
|
1144
|
-
this.stream.on("close", () => this.kill()).on("error", (err) =>
|
|
1177
|
+
this.stream.on("close", () => this.kill()).on("error", (err) => {
|
|
1178
|
+
this.debug(`[stream] error: ${err.message}`);
|
|
1179
|
+
this.emit("error", err);
|
|
1180
|
+
}).on("finish", () => this.debug("[stream] log: stream finished"));
|
|
1145
1181
|
this.process.stdout.pipe(this.stream);
|
|
1146
1182
|
this.process.stderr.setEncoding("utf8")?.on("data", (data) => {
|
|
1147
1183
|
const lines = data.split(/\r\n|\r|\n/u);
|
|
@@ -1247,7 +1283,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1247
1283
|
const cookies = __privateSet(this, _cookie, this.options.youtubeCookie);
|
|
1248
1284
|
if (typeof cookies === "string") {
|
|
1249
1285
|
console.warn(
|
|
1250
|
-
"\x1B[33mWARNING:\x1B[0m You are using the old YouTube cookie format, please use the new one instead. (https://
|
|
1286
|
+
"\x1B[33mWARNING:\x1B[0m You are using the old YouTube cookie format, please use the new one instead. (https://github.com/skick1234/DisTube/wiki/YouTube-Cookies)"
|
|
1251
1287
|
);
|
|
1252
1288
|
options.agent = import_ytdl_core.default.createAgent(
|
|
1253
1289
|
cookies.split(";").map((c) => import_tough_cookie.Cookie.parse(c)).filter(isTruthy)
|
|
@@ -1544,10 +1580,11 @@ __name(_DisTubeHandler, "DisTubeHandler");
|
|
|
1544
1580
|
var DisTubeHandler = _DisTubeHandler;
|
|
1545
1581
|
|
|
1546
1582
|
// src/core/DisTubeOptions.ts
|
|
1547
|
-
var _validateOptions, validateOptions_fn;
|
|
1583
|
+
var _validateOptions, validateOptions_fn, _ffmpegOption, ffmpegOption_fn;
|
|
1548
1584
|
var _Options = class _Options {
|
|
1549
1585
|
constructor(options) {
|
|
1550
1586
|
__privateAdd(this, _validateOptions);
|
|
1587
|
+
__privateAdd(this, _ffmpegOption);
|
|
1551
1588
|
__publicField(this, "plugins");
|
|
1552
1589
|
__publicField(this, "emitNewSongOnly");
|
|
1553
1590
|
__publicField(this, "leaveOnFinish");
|
|
@@ -1566,8 +1603,11 @@ var _Options = class _Options {
|
|
|
1566
1603
|
__publicField(this, "joinNewVoiceChannel");
|
|
1567
1604
|
__publicField(this, "streamType");
|
|
1568
1605
|
__publicField(this, "directLink");
|
|
1606
|
+
/** @deprecated */
|
|
1569
1607
|
__publicField(this, "ffmpegPath");
|
|
1608
|
+
/** @deprecated */
|
|
1570
1609
|
__publicField(this, "ffmpegDefaultArgs");
|
|
1610
|
+
__publicField(this, "ffmpeg");
|
|
1571
1611
|
if (typeof options !== "object" || Array.isArray(options)) {
|
|
1572
1612
|
throw new DisTubeError("INVALID_TYPE", "object", options, "DisTubeOptions");
|
|
1573
1613
|
}
|
|
@@ -1590,8 +1630,7 @@ var _Options = class _Options {
|
|
|
1590
1630
|
this.joinNewVoiceChannel = opts.joinNewVoiceChannel;
|
|
1591
1631
|
this.streamType = opts.streamType;
|
|
1592
1632
|
this.directLink = opts.directLink;
|
|
1593
|
-
this.
|
|
1594
|
-
this.ffmpegDefaultArgs = opts.ffmpegDefaultArgs;
|
|
1633
|
+
this.ffmpeg = __privateMethod(this, _ffmpegOption, ffmpegOption_fn).call(this, options);
|
|
1595
1634
|
checkInvalidKey(opts, this, "DisTubeOptions");
|
|
1596
1635
|
__privateMethod(this, _validateOptions, validateOptions_fn).call(this);
|
|
1597
1636
|
}
|
|
@@ -1611,8 +1650,8 @@ validateOptions_fn = /* @__PURE__ */ __name(function(options = this) {
|
|
|
1611
1650
|
"directLink"
|
|
1612
1651
|
]);
|
|
1613
1652
|
const numberOptions = /* @__PURE__ */ new Set(["searchCooldown", "emptyCooldown", "searchSongs"]);
|
|
1614
|
-
const stringOptions = /* @__PURE__ */ new Set(
|
|
1615
|
-
const objectOptions = /* @__PURE__ */ new Set(["customFilters", "ytdlOptions", "
|
|
1653
|
+
const stringOptions = /* @__PURE__ */ new Set();
|
|
1654
|
+
const objectOptions = /* @__PURE__ */ new Set(["customFilters", "ytdlOptions", "ffmpeg"]);
|
|
1616
1655
|
const optionalOptions = /* @__PURE__ */ new Set(["youtubeCookie", "customFilters"]);
|
|
1617
1656
|
for (const [key, value] of Object.entries(options)) {
|
|
1618
1657
|
if (value === void 0 && optionalOptions.has(key))
|
|
@@ -1642,6 +1681,29 @@ validateOptions_fn = /* @__PURE__ */ __name(function(options = this) {
|
|
|
1642
1681
|
}
|
|
1643
1682
|
}
|
|
1644
1683
|
}, "#validateOptions");
|
|
1684
|
+
_ffmpegOption = new WeakSet();
|
|
1685
|
+
ffmpegOption_fn = /* @__PURE__ */ __name(function(opts) {
|
|
1686
|
+
let path;
|
|
1687
|
+
const args = { global: {}, input: {}, output: {} };
|
|
1688
|
+
if (opts.ffmpegPath) {
|
|
1689
|
+
console.warn("`DisTubeOptions.ffmpegPath` is deprecated. Use `ffmpeg.path` instead.");
|
|
1690
|
+
path = opts.ffmpegPath;
|
|
1691
|
+
}
|
|
1692
|
+
if (opts.ffmpegDefaultArgs) {
|
|
1693
|
+
console.warn("`DisTubeOptions.ffmpegDefaultArgs` is deprecated. Use `ffmpeg.args` instead.");
|
|
1694
|
+
args.global = opts.ffmpegDefaultArgs;
|
|
1695
|
+
}
|
|
1696
|
+
path ??= opts.ffmpeg?.path ?? "ffmpeg";
|
|
1697
|
+
if (opts.ffmpeg?.args) {
|
|
1698
|
+
if (opts.ffmpeg.args.global)
|
|
1699
|
+
args.global = opts.ffmpeg.args.global;
|
|
1700
|
+
if (opts.ffmpeg.args.input)
|
|
1701
|
+
args.input = opts.ffmpeg.args.input;
|
|
1702
|
+
if (opts.ffmpeg.args.output)
|
|
1703
|
+
args.output = opts.ffmpeg.args.output;
|
|
1704
|
+
}
|
|
1705
|
+
return { path, args };
|
|
1706
|
+
}, "#ffmpegOption");
|
|
1645
1707
|
__name(_Options, "Options");
|
|
1646
1708
|
var Options = _Options;
|
|
1647
1709
|
|
|
@@ -1920,6 +1982,7 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
|
|
|
1920
1982
|
const queue = new Queue(this.distube, voice, song, textChannel);
|
|
1921
1983
|
await queue._taskQueue.queuing();
|
|
1922
1984
|
try {
|
|
1985
|
+
checkFFmpeg(this.distube);
|
|
1923
1986
|
await voice.join();
|
|
1924
1987
|
__privateMethod(this, _voiceEventHandler, voiceEventHandler_fn).call(this, queue);
|
|
1925
1988
|
this.add(queue.id, queue);
|
|
@@ -1940,10 +2003,11 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
|
|
|
1940
2003
|
const { duration, source, streamURL } = song;
|
|
1941
2004
|
const streamOptions = {
|
|
1942
2005
|
ffmpeg: {
|
|
1943
|
-
path: this.options.
|
|
2006
|
+
path: this.options.ffmpeg.path,
|
|
1944
2007
|
args: {
|
|
1945
|
-
...this.options.
|
|
1946
|
-
...
|
|
2008
|
+
global: { ...this.options.ffmpeg.args.global },
|
|
2009
|
+
input: { ...this.options.ffmpeg.args.input },
|
|
2010
|
+
output: { ...this.options.ffmpeg.args.output, ...queue.filters.ffmpegArgs }
|
|
1947
2011
|
}
|
|
1948
2012
|
},
|
|
1949
2013
|
seek: duration ? queue.beginTime : void 0,
|
|
@@ -1951,6 +2015,8 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
|
|
|
1951
2015
|
};
|
|
1952
2016
|
if (source === "youtube")
|
|
1953
2017
|
return DisTubeStream.YouTube(song, streamOptions);
|
|
2018
|
+
if (!streamURL)
|
|
2019
|
+
throw new Error("No streamURL, something went wrong");
|
|
1954
2020
|
return DisTubeStream.DirectLink(streamURL, streamOptions);
|
|
1955
2021
|
}
|
|
1956
2022
|
/**
|
|
@@ -2737,15 +2803,9 @@ var _DirectLinkPlugin = class _DirectLinkPlugin extends ExtractorPlugin {
|
|
|
2737
2803
|
return false;
|
|
2738
2804
|
}
|
|
2739
2805
|
resolve(url, options = {}) {
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
name: url.substring(url.lastIndexOf("/") + 1).replace(/((\?|#).*)?$/, "") || url,
|
|
2744
|
-
url,
|
|
2745
|
-
src: "direct_link"
|
|
2746
|
-
},
|
|
2747
|
-
options
|
|
2748
|
-
);
|
|
2806
|
+
const u = new URL(url);
|
|
2807
|
+
const name = u.pathname.split("/").pop() || u.href;
|
|
2808
|
+
return new Song({ name, url, src: "direct_link" }, options);
|
|
2749
2809
|
}
|
|
2750
2810
|
};
|
|
2751
2811
|
__name(_DirectLinkPlugin, "DirectLinkPlugin");
|
|
@@ -2757,7 +2817,7 @@ var import_tiny_typed_emitter3 = require("tiny-typed-emitter");
|
|
|
2757
2817
|
var { version } = require_package();
|
|
2758
2818
|
var _getQueue, getQueue_fn;
|
|
2759
2819
|
var _DisTube = class _DisTube extends import_tiny_typed_emitter3.TypedEmitter {
|
|
2760
|
-
constructor(client,
|
|
2820
|
+
constructor(client, opts = {}) {
|
|
2761
2821
|
super();
|
|
2762
2822
|
__privateAdd(this, _getQueue);
|
|
2763
2823
|
__publicField(this, "handler");
|
|
@@ -2773,7 +2833,7 @@ var _DisTube = class _DisTube extends import_tiny_typed_emitter3.TypedEmitter {
|
|
|
2773
2833
|
throw new DisTubeError("INVALID_TYPE", "Discord.Client", client, "client");
|
|
2774
2834
|
this.client = client;
|
|
2775
2835
|
checkIntents(client.options);
|
|
2776
|
-
this.options = new Options(
|
|
2836
|
+
this.options = new Options(opts);
|
|
2777
2837
|
this.voices = new DisTubeVoiceManager(this);
|
|
2778
2838
|
this.handler = new DisTubeHandler(this);
|
|
2779
2839
|
this.queues = new QueueManager(this);
|
|
@@ -3261,7 +3321,7 @@ ${e.message}`;
|
|
|
3261
3321
|
console.error(error);
|
|
3262
3322
|
console.warn("Unhandled 'error' event.");
|
|
3263
3323
|
console.warn(
|
|
3264
|
-
"See: https://distube.js.org
|
|
3324
|
+
"See: https://distube.js.org/classes/DisTube.html#error and https://nodejs.org/api/events.html#events_error_events"
|
|
3265
3325
|
);
|
|
3266
3326
|
}
|
|
3267
3327
|
}
|
|
@@ -3304,6 +3364,7 @@ var DisTube = _DisTube;
|
|
|
3304
3364
|
Song,
|
|
3305
3365
|
StreamType,
|
|
3306
3366
|
TaskQueue,
|
|
3367
|
+
checkFFmpeg,
|
|
3307
3368
|
checkIntents,
|
|
3308
3369
|
checkInvalidKey,
|
|
3309
3370
|
chooseBestVideoFormat,
|