magmastream 2.10.2-alpha.7 → 2.10.2-alpha.9
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.
|
@@ -16,6 +16,7 @@ export declare enum AutoPlayPlatform {
|
|
|
16
16
|
Tidal = "tidal",
|
|
17
17
|
VKMusic = "vkmusic",
|
|
18
18
|
Qobuz = "qobuz",
|
|
19
|
+
Yandex = "yandex",
|
|
19
20
|
YouTube = "youtube"
|
|
20
21
|
}
|
|
21
22
|
/**
|
|
@@ -55,6 +56,7 @@ export declare enum LoadTypes {
|
|
|
55
56
|
*/
|
|
56
57
|
export declare enum SearchPlatform {
|
|
57
58
|
AppleMusic = "amsearch",
|
|
59
|
+
Yandex = "ymsearch",
|
|
58
60
|
Audius = "audsearch",
|
|
59
61
|
Bandcamp = "bcsearch",
|
|
60
62
|
Deezer = "dzsearch",
|
|
@@ -103,6 +105,7 @@ export declare enum TrackSourceTypes {
|
|
|
103
105
|
TikTok = "TikTok",
|
|
104
106
|
Flowertts = "Flowertts",
|
|
105
107
|
Ocremix = "Ocremix",
|
|
108
|
+
Yandex = "Yandex",
|
|
106
109
|
Mixcloud = "Mixcloud",
|
|
107
110
|
Soundgasm = "Soundgasm",
|
|
108
111
|
Reddit = "Reddit",
|
package/dist/structures/Enums.js
CHANGED
|
@@ -21,6 +21,7 @@ var AutoPlayPlatform;
|
|
|
21
21
|
AutoPlayPlatform["Tidal"] = "tidal";
|
|
22
22
|
AutoPlayPlatform["VKMusic"] = "vkmusic";
|
|
23
23
|
AutoPlayPlatform["Qobuz"] = "qobuz";
|
|
24
|
+
AutoPlayPlatform["Yandex"] = "yandex";
|
|
24
25
|
AutoPlayPlatform["YouTube"] = "youtube";
|
|
25
26
|
})(AutoPlayPlatform || (exports.AutoPlayPlatform = AutoPlayPlatform = {}));
|
|
26
27
|
/**
|
|
@@ -63,6 +64,7 @@ var LoadTypes;
|
|
|
63
64
|
var SearchPlatform;
|
|
64
65
|
(function (SearchPlatform) {
|
|
65
66
|
SearchPlatform["AppleMusic"] = "amsearch";
|
|
67
|
+
SearchPlatform["Yandex"] = "ymsearch";
|
|
66
68
|
SearchPlatform["Audius"] = "audsearch";
|
|
67
69
|
SearchPlatform["Bandcamp"] = "bcsearch";
|
|
68
70
|
SearchPlatform["Deezer"] = "dzsearch";
|
|
@@ -113,6 +115,7 @@ var TrackSourceTypes;
|
|
|
113
115
|
TrackSourceTypes["TikTok"] = "TikTok";
|
|
114
116
|
TrackSourceTypes["Flowertts"] = "Flowertts";
|
|
115
117
|
TrackSourceTypes["Ocremix"] = "Ocremix";
|
|
118
|
+
TrackSourceTypes["Yandex"] = "Yandex";
|
|
116
119
|
TrackSourceTypes["Mixcloud"] = "Mixcloud";
|
|
117
120
|
TrackSourceTypes["Soundgasm"] = "Soundgasm";
|
|
118
121
|
TrackSourceTypes["Reddit"] = "Reddit";
|
|
@@ -372,7 +372,8 @@ class Player {
|
|
|
372
372
|
if (typeof optionsOrTrack !== "undefined" && Utils_1.TrackUtils.validate(optionsOrTrack)) {
|
|
373
373
|
await this.queue.setCurrent(optionsOrTrack);
|
|
374
374
|
}
|
|
375
|
-
|
|
375
|
+
const currentTrack = await this.queue.getCurrent();
|
|
376
|
+
if (!currentTrack) {
|
|
376
377
|
const error = new MagmastreamError_1.MagmaStreamError({
|
|
377
378
|
code: Enums_1.MagmaStreamErrorCode.PLAYER_QUEUE_EMPTY,
|
|
378
379
|
message: "The queue is empty.",
|
|
@@ -384,16 +385,17 @@ class Player {
|
|
|
384
385
|
const finalOptions = playOptions ? playOptions : isPlayOptions(optionsOrTrack) ? optionsOrTrack : {};
|
|
385
386
|
await this.node.rest.updatePlayer({
|
|
386
387
|
guildId: this.guildId,
|
|
388
|
+
noReplace: finalOptions.noReplace,
|
|
387
389
|
data: {
|
|
388
390
|
track: {
|
|
389
|
-
encoded:
|
|
391
|
+
encoded: currentTrack.track,
|
|
390
392
|
},
|
|
391
|
-
...finalOptions,
|
|
392
|
-
|
|
393
|
+
...(typeof finalOptions.startTime === "number" && { position: finalOptions.startTime }),
|
|
394
|
+
...(typeof finalOptions.endTime === "number" && finalOptions.endTime > 0 && { endTime: finalOptions.endTime }),
|
|
393
395
|
},
|
|
394
396
|
});
|
|
395
397
|
this.playing = true;
|
|
396
|
-
this.position = finalOptions.startTime
|
|
398
|
+
this.position = finalOptions.startTime ?? 0;
|
|
397
399
|
return this;
|
|
398
400
|
}
|
|
399
401
|
/**
|
|
@@ -683,7 +685,8 @@ class Player {
|
|
|
683
685
|
*/
|
|
684
686
|
async restart() {
|
|
685
687
|
// Check if there is a current track in the queue
|
|
686
|
-
|
|
688
|
+
const currentTrack = await this.queue.getCurrent();
|
|
689
|
+
if (!currentTrack?.track) {
|
|
687
690
|
// If the queue has tracks, play the next one
|
|
688
691
|
if (await this.queue.size())
|
|
689
692
|
await this.play();
|
|
@@ -695,8 +698,8 @@ class Player {
|
|
|
695
698
|
data: {
|
|
696
699
|
position: 0,
|
|
697
700
|
track: {
|
|
698
|
-
encoded:
|
|
699
|
-
userData:
|
|
701
|
+
encoded: currentTrack.track,
|
|
702
|
+
userData: currentTrack.requester,
|
|
700
703
|
},
|
|
701
704
|
},
|
|
702
705
|
});
|
|
@@ -837,7 +840,8 @@ class Player {
|
|
|
837
840
|
* @emits {PlayerStateUpdate} - With {@link PlayerStateEventTypes.TrackChange} as the change type.
|
|
838
841
|
*/
|
|
839
842
|
async seek(position) {
|
|
840
|
-
|
|
843
|
+
const currentTrack = await this.queue.getCurrent();
|
|
844
|
+
if (!currentTrack)
|
|
841
845
|
return undefined;
|
|
842
846
|
position = Number(position);
|
|
843
847
|
// Check if the position is valid.
|
|
@@ -850,8 +854,8 @@ class Player {
|
|
|
850
854
|
// Get the old player state.
|
|
851
855
|
const oldPlayer = this ? { ...this } : null;
|
|
852
856
|
// Clamp the position to ensure it is within the valid range.
|
|
853
|
-
if (position < 0 || position >
|
|
854
|
-
position = Math.max(Math.min(position,
|
|
857
|
+
if (position < 0 || position > currentTrack.duration) {
|
|
858
|
+
position = Math.max(Math.min(position, currentTrack.duration), 0);
|
|
855
859
|
}
|
|
856
860
|
// Update the player's position.
|
|
857
861
|
this.position = position;
|
|
@@ -925,7 +929,7 @@ class Player {
|
|
|
925
929
|
}
|
|
926
930
|
try {
|
|
927
931
|
const playerPosition = this.position;
|
|
928
|
-
const currentTrack =
|
|
932
|
+
const currentTrack = await this.queue.getCurrent();
|
|
929
933
|
// Safely get voice state properties with null checks
|
|
930
934
|
const sessionId = this.voiceState?.sessionId;
|
|
931
935
|
const token = this.voiceState?.event?.token;
|
package/dist/structures/Utils.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.JSONUtils = exports.Structure = exports.PlayerUtils = exports.AutoPlayUtils = exports.TrackUtils = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
6
|
-
const axios_1 =
|
|
6
|
+
const axios_1 = require("axios");
|
|
7
7
|
const jsdom_1 = require("jsdom");
|
|
8
8
|
const Enums_1 = require("./Enums");
|
|
9
9
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
@@ -250,7 +250,7 @@ class AutoPlayUtils {
|
|
|
250
250
|
if (!title) {
|
|
251
251
|
// No title provided, search for the artist's top tracks
|
|
252
252
|
const noTitleUrl = `https://ws.audioscrobbler.com/2.0/?method=artist.getTopTracks&artist=${artist}&autocorrect=1&api_key=${apiKey}&format=json`;
|
|
253
|
-
const response = await axios_1.
|
|
253
|
+
const response = await (0, axios_1.get)(noTitleUrl);
|
|
254
254
|
if (response.data.error || !response.data.toptracks?.track?.length) {
|
|
255
255
|
return [];
|
|
256
256
|
}
|
|
@@ -263,7 +263,7 @@ class AutoPlayUtils {
|
|
|
263
263
|
if (!artist) {
|
|
264
264
|
// No artist provided, search for the track title
|
|
265
265
|
const noArtistUrl = `https://ws.audioscrobbler.com/2.0/?method=track.search&track=${title}&api_key=${apiKey}&format=json`;
|
|
266
|
-
const response = await axios_1.
|
|
266
|
+
const response = await (0, axios_1.get)(noArtistUrl);
|
|
267
267
|
artist = response.data.results.trackmatches?.track?.[0]?.artist;
|
|
268
268
|
if (!artist) {
|
|
269
269
|
return [];
|
|
@@ -274,7 +274,7 @@ class AutoPlayUtils {
|
|
|
274
274
|
const url = `https://ws.audioscrobbler.com/2.0/?method=track.getSimilar&artist=${artist}&track=${title}&limit=10&autocorrect=1&api_key=${apiKey}&format=json`;
|
|
275
275
|
let response;
|
|
276
276
|
try {
|
|
277
|
-
response = await axios_1.
|
|
277
|
+
response = await (0, axios_1.get)(url);
|
|
278
278
|
}
|
|
279
279
|
catch (error) {
|
|
280
280
|
console.error("[AutoPlay] Error fetching similar tracks from Last.fm:", error);
|
|
@@ -283,7 +283,7 @@ class AutoPlayUtils {
|
|
|
283
283
|
if (response.data.error || !response.data.similartracks?.track?.length) {
|
|
284
284
|
// Retry the request if the first attempt fails
|
|
285
285
|
const retryUrl = `https://ws.audioscrobbler.com/2.0/?method=artist.getTopTracks&artist=${artist}&autocorrect=1&api_key=${apiKey}&format=json`;
|
|
286
|
-
const retryResponse = await axios_1.
|
|
286
|
+
const retryResponse = await (0, axios_1.get)(retryUrl);
|
|
287
287
|
if (retryResponse.data.error || !retryResponse.data.toptracks?.track?.length) {
|
|
288
288
|
return [];
|
|
289
289
|
}
|
|
@@ -357,7 +357,7 @@ class AutoPlayUtils {
|
|
|
357
357
|
track = resolvedTrack;
|
|
358
358
|
}
|
|
359
359
|
try {
|
|
360
|
-
const recommendedRes = await axios_1.
|
|
360
|
+
const recommendedRes = await (0, axios_1.get)(`${track.uri}/recommended`).catch((err) => {
|
|
361
361
|
console.error(`[AutoPlay] Failed to fetch SoundCloud recommendations. Status: ${err.response?.status || "Unknown"}`, err.message);
|
|
362
362
|
return null;
|
|
363
363
|
});
|
|
@@ -465,6 +465,19 @@ class AutoPlayUtils {
|
|
|
465
465
|
const tracks = this.buildTracksFromResponse(recommendedResult, requester);
|
|
466
466
|
return tracks;
|
|
467
467
|
}
|
|
468
|
+
case Enums_1.AutoPlayPlatform.Yandex: {
|
|
469
|
+
const allowedYandexHosts = ["music.yandex.ru", "yandex.ru", "www.yandex.ru"];
|
|
470
|
+
if (!allowedYandexHosts.includes(parsedURL.host)) {
|
|
471
|
+
const resolvedTrack = await this.resolveFirstTrackFromQuery(`${track.author} - ${track.title}`, Enums_1.SearchPlatform.Yandex, requester);
|
|
472
|
+
if (!resolvedTrack)
|
|
473
|
+
return [];
|
|
474
|
+
track = resolvedTrack;
|
|
475
|
+
}
|
|
476
|
+
const identifier = `ymrec:${track.identifier}`;
|
|
477
|
+
const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
|
|
478
|
+
const tracks = this.buildTracksFromResponse(recommendedResult, requester);
|
|
479
|
+
return tracks;
|
|
480
|
+
}
|
|
468
481
|
default:
|
|
469
482
|
return [];
|
|
470
483
|
}
|
package/dist/utils/nodeCheck.js
CHANGED
|
@@ -16,7 +16,7 @@ function nodeCheck(options) {
|
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
const { host, identifier, password, port, enableSessionResumeOption, sessionTimeoutSeconds, maxRetryAttempts, retryDelayMs, useSSL, nodePriority } = options;
|
|
19
|
-
if (typeof host !== "string"
|
|
19
|
+
if (!host || typeof host !== "string") {
|
|
20
20
|
throw new MagmastreamError_1.MagmaStreamError({
|
|
21
21
|
code: Enums_1.MagmaStreamErrorCode.NODE_INVALID_CONFIG,
|
|
22
22
|
message: 'Node option "host" must be present and be a non-empty string.',
|