-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
104 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,64 @@ | ||
import { Playlist as youtubePlaylist, type Thumbnail, type Video, YouTube as youtube } from "youtube-sr"; | ||
import { config } from "@components/config"; | ||
import { Song } from "@components/Song"; | ||
import type { CacheType, ChatInputCommandInteraction } from "discord.js"; | ||
//@ts-expect-error | ||
import SpotifyUrlInfo, { Tracks } from "spotify-url-info"; | ||
import { fetch } from "undici"; | ||
import { sp_validate, so_validate, yt_validate, search as playSearch, soundcloud, type SoundCloudPlaylist } from "play-dl"; | ||
import { sp_validate, so_validate, yt_validate, playlist_info, soundcloud, spotify, search as playSearch, type SoundCloudPlaylist, YouTubePlayList, YouTubeVideo, SpotifyPlaylist, SoundCloudTrack, video_basic_info, is_expired, refreshToken } from "play-dl"; | ||
|
||
type dataType = SpotifyPlaylist | YouTubePlayList | SoundCloudPlaylist; | ||
type tracksType = YouTubeVideo[] | SoundCloudTrack[]; | ||
|
||
export class Playlist { | ||
public readonly data: youtubePlaylist; | ||
public readonly data: SpotifyPlaylist | YouTubePlayList | SoundCloudPlaylist; | ||
public readonly videos: Song[]; | ||
|
||
public constructor({ playlist, interaction }: { playlist: youtubePlaylist; interaction: ChatInputCommandInteraction<CacheType>; }) { | ||
this.data = playlist; | ||
public constructor({ playlist, interaction }: { playlist: { data: dataType, tracks: tracksType }; interaction: ChatInputCommandInteraction<CacheType>; }) { | ||
this.data = playlist.data; | ||
|
||
this.videos = this.data.videos | ||
.filter((video) => !["Private video", "Deleted video"].includes(video.title!)) | ||
this.videos = playlist.tracks | ||
.slice(0, config.MAX_PLAYLIST_SIZE) | ||
.map((video) => new Song({ | ||
title: video.title as string, | ||
.map((video) => video instanceof YouTubeVideo ? new Song({ | ||
title: video.title!, | ||
url: video.url, | ||
duration: video.durationInSec, | ||
durationRaw: video.durationRaw, | ||
thumbnail: video.thumbnails[0].url, | ||
req: interaction.user.tag | ||
}) : new Song({ | ||
title: video.name, | ||
url: video.url, | ||
duration: video.duration / 1000, | ||
thumbnail: (video.thumbnail as Thumbnail).url as string, | ||
duration: video.durationInSec, | ||
durationRaw: undefined, | ||
thumbnail: video.thumbnail, | ||
req: interaction.user.tag | ||
})); | ||
} | ||
}; | ||
|
||
public static async from({ url = "", search = "", interaction }: { url: string; search: string; interaction: ChatInputCommandInteraction<CacheType> }): Promise<Playlist> { | ||
const isYoutubeUrl = yt_validate(url) === "playlist"; | ||
const isSpotifyUrl = ["playlist", "album"].includes(sp_validate(url) as string); | ||
const isSoundCloudUrl = await so_validate(url) === "playlist"; | ||
public static async from({ search, interaction }: { search: string; interaction: ChatInputCommandInteraction<CacheType> }): Promise<Playlist> { | ||
const isYoutubeUrl = yt_validate(search) === "playlist"; | ||
const isSpotifyUrl = ["playlist", "album"].includes(sp_validate(search) as string); | ||
const isSoundCloudUrl = await so_validate(search) === "playlist"; | ||
|
||
let playlist: youtubePlaylist; | ||
let pl: { data: dataType, tracks: tracksType } | ||
if (isSpotifyUrl) { | ||
const playlistTrack = await SpotifyUrlInfo(fetch).getTracks(url); | ||
const limitedPlaylistTrack = playlistTrack.slice(0, config.MAX_PLAYLIST_SIZE); | ||
const spotifyPl = Promise.all(limitedPlaylistTrack.map(async (track: Tracks): Promise<Video> => await youtube.searchOne(`${track.name} - ${track.artists ? track.artists[0].name : ""}`, "video"))); | ||
playlist = new youtubePlaylist({ videos: (await spotifyPl).filter((song: Video) => song.title !== undefined || song.duration !== undefined) }); | ||
if (is_expired()) await refreshToken(); | ||
const playlist = await spotify(search) as SpotifyPlaylist | ||
|
||
const ytVideos = await Promise.all((await playlist.all_tracks()).map(async track => (await video_basic_info((await playSearch(`${track.artists[0].name} - ${track.name}`, { source: { youtube: "video" } }))[0].url)).video_details)); | ||
|
||
pl = { data: playlist, tracks: ytVideos }; | ||
} else if (isYoutubeUrl) { | ||
playlist = await youtube.getPlaylist(url); | ||
const playlist = await playlist_info(search, { incomplete: true }); | ||
|
||
pl = { data: playlist, tracks: await playlist.all_videos() }; | ||
} else if (isSoundCloudUrl) { | ||
const scPl = await soundcloud(url) as SoundCloudPlaylist; | ||
const scPlTracks = (await scPl.all_tracks()).map((track) => ({ | ||
title: track.name, | ||
url: track.permalink, | ||
duration: track.durationInSec, | ||
thumbnail: { | ||
url: track.thumbnail | ||
}, | ||
req: interaction.user.tag | ||
})); | ||
playlist = new youtubePlaylist({ videos: scPlTracks, title: scPl.name, url: scPl.url }); | ||
const playlist = await soundcloud(search) as SoundCloudPlaylist; | ||
|
||
pl = { data: playlist, tracks: await playlist.all_tracks() }; | ||
} else { | ||
const result = await playSearch(search, { | ||
source: { | ||
youtube: "playlist" | ||
}, | ||
limit: 1 | ||
}); | ||
playlist = await youtube.getPlaylist(result[0].url as string); | ||
const playlist = await playlist_info(search as string, { incomplete: true }); | ||
|
||
pl = { data: playlist, tracks: await playlist.all_videos() }; | ||
} | ||
|
||
return new this({ playlist, interaction }); | ||
return new this({ playlist: { data: pl.data, tracks: pl.tracks }, interaction }); | ||
} | ||
} |
Oops, something went wrong.