From c24b417f39bebba15783d90a0aaecfa31def5cce Mon Sep 17 00:00:00 2001 From: killer069 <65385476+killer069@users.noreply.github.com> Date: Tue, 23 Nov 2021 09:49:22 +0530 Subject: [PATCH 1/7] Channel Icons Fixed --- play-dl/YouTube/classes/Channel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play-dl/YouTube/classes/Channel.ts b/play-dl/YouTube/classes/Channel.ts index 51196f9..8ca5539 100644 --- a/play-dl/YouTube/classes/Channel.ts +++ b/play-dl/YouTube/classes/Channel.ts @@ -60,7 +60,7 @@ export class YouTubeChannel { this.artist = !!data.artist || false; this.id = data.id || null; this.url = data.url || null; - this.icons = data.icon || [{ url: null, width: 0, height: 0 }]; + this.icons = data.icons || [{ url: null, width: 0, height: 0 }]; this.subscribers = data.subscribers || null; } From 6fe9372989ea89a0fdc4f77d0125657320da7c36 Mon Sep 17 00:00:00 2001 From: killer069 <65385476+killer069@users.noreply.github.com> Date: Tue, 23 Nov 2021 09:50:44 +0530 Subject: [PATCH 2/7] Removed useless function - cookiesHeaders --- play-dl/YouTube/index.ts | 1 - play-dl/YouTube/utils/cookie.ts | 25 ------------------------- play-dl/index.ts | 1 - 3 files changed, 27 deletions(-) diff --git a/play-dl/YouTube/index.ts b/play-dl/YouTube/index.ts index 586baaf..54f5d91 100644 --- a/play-dl/YouTube/index.ts +++ b/play-dl/YouTube/index.ts @@ -1,7 +1,6 @@ export { stream, stream_from_info, YouTubeStream } from './stream'; export * from './utils'; export { YouTube } from './search'; -export { cookieHeaders } from './utils/cookie'; export { YouTubeVideo } from './classes/Video' export { YouTubePlayList } from './classes/Playlist' export { YouTubeChannel } from './classes/Channel' diff --git a/play-dl/YouTube/utils/cookie.ts b/play-dl/YouTube/utils/cookie.ts index c391f7c..e4cf712 100644 --- a/play-dl/YouTube/utils/cookie.ts +++ b/play-dl/YouTube/utils/cookie.ts @@ -46,28 +46,3 @@ export function setCookieToken(options: { cookie: string }) { youtubeData = { cookie }; youtubeData.file = false; } -/** - * Updates cookies locally either in file or in memory. - * - * Example - * ```ts - * const response = ... // Any https package get function. - * - * play.cookieHeaders(response.headers['set-cookie']) - * ``` - * @param headCookie response headers['set-cookie'] array - * @returns Nothing - */ -export function cookieHeaders(headCookie: string[]): void { - if (!youtubeData?.cookie) return; - headCookie.forEach((x: string) => { - x.split(';').forEach((z) => { - const arr = z.split('='); - if (arr.length <= 1) return; - const key = arr.shift()?.trim() as string; - const value = arr.join('=').trim(); - setCookie(key, value); - }); - }); - uploadCookie(); -} diff --git a/play-dl/index.ts b/play-dl/index.ts index 3ca0ff4..082b46c 100644 --- a/play-dl/index.ts +++ b/play-dl/index.ts @@ -7,7 +7,6 @@ export { extractID, YouTube, YouTubeStream, - cookieHeaders, YouTubeChannel, YouTubePlayList, YouTubeVideo From 32b9fdbf65581e36eae7a7a3406dd6b87913c641 Mon Sep 17 00:00:00 2001 From: killer069 <65385476+killer069@users.noreply.github.com> Date: Tue, 23 Nov 2021 09:56:08 +0530 Subject: [PATCH 3/7] pretty code --- play-dl/Deezer/index.ts | 2 +- play-dl/SoundCloud/classes.ts | 24 +-- play-dl/SoundCloud/constants.ts | 168 ++++++++++----------- play-dl/SoundCloud/index.ts | 14 +- play-dl/Spotify/classes.ts | 88 +++++------ play-dl/Spotify/constants.ts | 206 +++++++++++++------------- play-dl/Spotify/index.ts | 14 +- play-dl/YouTube/classes/Channel.ts | 64 ++++---- play-dl/YouTube/classes/LiveStream.ts | 42 +++--- play-dl/YouTube/classes/Playlist.ts | 124 ++++++++-------- play-dl/YouTube/classes/Thumbnail.ts | 32 ++-- play-dl/YouTube/classes/Video.ts | 114 +++++++------- play-dl/YouTube/index.ts | 6 +- play-dl/YouTube/utils/constants.ts | 62 ++++---- play-dl/YouTube/utils/cookie.ts | 26 ++++ play-dl/YouTube/utils/extractor.ts | 19 ++- play-dl/YouTube/utils/parser.ts | 4 +- play-dl/index.ts | 97 +++++++++--- play-dl/token.ts | 10 +- 19 files changed, 601 insertions(+), 515 deletions(-) diff --git a/play-dl/Deezer/index.ts b/play-dl/Deezer/index.ts index d827a12..9b77793 100644 --- a/play-dl/Deezer/index.ts +++ b/play-dl/Deezer/index.ts @@ -256,4 +256,4 @@ export async function dz_advanced_track_search(options: DeezerAdvancedSearchOpti return results; } -export { DeezerTrack, DeezerAlbum, DeezerPlaylist } \ No newline at end of file +export { DeezerTrack, DeezerAlbum, DeezerPlaylist }; diff --git a/play-dl/SoundCloud/classes.ts b/play-dl/SoundCloud/classes.ts index a7b3c63..958378b 100644 --- a/play-dl/SoundCloud/classes.ts +++ b/play-dl/SoundCloud/classes.ts @@ -182,7 +182,7 @@ export class SoundCloudTrack { * Converts class to JSON * @returns JSON parsed Data */ - toJSON() : SoundTrackJSON { + toJSON(): SoundTrackJSON { return { name: this.name, id: this.id, @@ -288,7 +288,7 @@ export class SoundCloudPlaylist { } /** * Fetches all unfetched songs in a playlist. - * + * * For fetching songs and getting all songs, see `fetched_tracks` property. * @returns playlist class */ @@ -325,14 +325,14 @@ export class SoundCloudPlaylist { } /** * Get all fetched tracks as a array. - * + * * For getting all feetched tracks - * + * * ```ts * const playlist = await play.soundcloud("playlist url") - * + * * await playlist.fetch() - * + * * const result = playlist.fetched_tracks * ``` */ @@ -370,9 +370,9 @@ export class SoundCloudStream { * Readable Stream through which data passes */ stream: Readable; - /** - * Type of audio data that we recieved from normal youtube url. - */ + /** + * Type of audio data that we recieved from normal youtube url. + */ type: StreamType; /** * Dash Url containing segment urls. @@ -396,7 +396,7 @@ export class SoundCloudStream { private downloaded_segments: number; /** * Incoming message that we recieve. - * + * * Storing this is essential. * This helps to destroy the TCP connection completely if you stopped player in between the stream * @private @@ -503,7 +503,7 @@ export class SoundCloudStream { } /** * This cleans every used variable in class. - * + * * This is used to prevent re-use of this class and helping garbage collector to collect it. */ private cleanup() { @@ -519,7 +519,7 @@ export class SoundCloudStream { /** * Pauses timer. * Stops running of loop. - * + * * Useful if you don't want to get excess data to be stored in stream. */ pause() { diff --git a/play-dl/SoundCloud/constants.ts b/play-dl/SoundCloud/constants.ts index 440b125..04f1c35 100644 --- a/play-dl/SoundCloud/constants.ts +++ b/play-dl/SoundCloud/constants.ts @@ -1,93 +1,93 @@ -import { SoundCloudTrack, SoundCloudTrackDeprecated, SoundCloudTrackFormat, SoundCloudUser } from "./classes"; +import { SoundCloudTrack, SoundCloudTrackDeprecated, SoundCloudTrackFormat, SoundCloudUser } from './classes'; -export interface SoundTrackJSON{ +export interface SoundTrackJSON { /** * SoundCloud Track Name */ - name: string; - /** - * SoundCloud Track ID - */ - id: number; - /** - * SoundCloud Track url - */ - url: string; - /** - * SoundCloud Track fetched status - */ - fetched: boolean; - /** - * SoundCloud Track Duration in seconds - */ - durationInSec: number; - /** - * SoundCloud Track Duration in miili seconds - */ - durationInMs: number; - /** - * SoundCloud Track formats data - */ - formats: SoundCloudTrackFormat[]; - /** - * SoundCloud Track Publisher Data - */ - publisher: { - name: string; - id: number; - artist: string; - contains_music: boolean; - writer_composer: string; - } | null; - /** - * SoundCloud Track thumbnail - */ - thumbnail: string; - /** - * SoundCloud Track user data - */ - user: SoundCloudUser; + name: string; + /** + * SoundCloud Track ID + */ + id: number; + /** + * SoundCloud Track url + */ + url: string; + /** + * SoundCloud Track fetched status + */ + fetched: boolean; + /** + * SoundCloud Track Duration in seconds + */ + durationInSec: number; + /** + * SoundCloud Track Duration in miili seconds + */ + durationInMs: number; + /** + * SoundCloud Track formats data + */ + formats: SoundCloudTrackFormat[]; + /** + * SoundCloud Track Publisher Data + */ + publisher: { + name: string; + id: number; + artist: string; + contains_music: boolean; + writer_composer: string; + } | null; + /** + * SoundCloud Track thumbnail + */ + thumbnail: string; + /** + * SoundCloud Track user data + */ + user: SoundCloudUser; } -export interface PlaylistJSON{ +export interface PlaylistJSON { /** * SoundCloud Playlist Name */ - name: string; - /** - * SoundCloud Playlist ID - */ - id: number; - /** - * SoundCloud Playlist URL - */ - url: string; - /** - * SoundCloud Playlist Sub type. == "album" for soundcloud albums - */ - sub_type: string; - /** - * SoundCloud Playlist Total Duration in seconds - */ - durationInSec: number; - /** - * SoundCloud Playlist Total Duration in milli seconds - */ - durationInMs: number; - /** - * SoundCloud Playlist user data - */ - user: SoundCloudUser; - /** - * SoundCloud Playlist tracks [ It can be fetched or not fetched ] - */ - tracks: SoundCloudTrack[] | SoundCloudTrackDeprecated[]; - /** - * SoundCloud Playlist tracks number - */ - tracksCount: number; - /** - * SoundCloud Client ID provided by user - * @private - */ -} \ No newline at end of file + name: string; + /** + * SoundCloud Playlist ID + */ + id: number; + /** + * SoundCloud Playlist URL + */ + url: string; + /** + * SoundCloud Playlist Sub type. == "album" for soundcloud albums + */ + sub_type: string; + /** + * SoundCloud Playlist Total Duration in seconds + */ + durationInSec: number; + /** + * SoundCloud Playlist Total Duration in milli seconds + */ + durationInMs: number; + /** + * SoundCloud Playlist user data + */ + user: SoundCloudUser; + /** + * SoundCloud Playlist tracks [ It can be fetched or not fetched ] + */ + tracks: SoundCloudTrack[] | SoundCloudTrackDeprecated[]; + /** + * SoundCloud Playlist tracks number + */ + tracksCount: number; + /** + * SoundCloud Client ID provided by user + * @private + */ +} diff --git a/play-dl/SoundCloud/index.ts b/play-dl/SoundCloud/index.ts index 239ddd6..9f28534 100644 --- a/play-dl/SoundCloud/index.ts +++ b/play-dl/SoundCloud/index.ts @@ -14,12 +14,12 @@ interface SoundDataOptions { const pattern = /^(?:(https?):\/\/)?(?:(?:www|m)\.)?(api\.soundcloud\.com|soundcloud\.com|snd\.sc)\/(.*)$/; /** * Gets info from a soundcloud url. - * + * * ```ts * let sound = await play.soundcloud('soundcloud url') - * + * * // sound.type === "track" | "playlist" | "user" - * + * * if (sound.type === "track") { * spot = spot as play.SoundCloudTrack * // Code with SoundCloud track class. @@ -97,9 +97,9 @@ export async function stream(url: string, quality?: number): Promise play.setToken({ * soundcloud : { @@ -156,7 +156,7 @@ export async function check_id(id: string): Promise { /** * Validates a soundcloud url * @param url soundcloud url - * @returns + * @returns * ```ts * false | 'track' | 'playlist' * ``` @@ -192,4 +192,4 @@ export function setSoundCloudToken(options: SoundDataOptions) { soundData = options; } -export { SoundCloudTrack, SoundCloudPlaylist, SoundCloudStream } \ No newline at end of file +export { SoundCloudTrack, SoundCloudPlaylist, SoundCloudStream }; diff --git a/play-dl/Spotify/classes.ts b/play-dl/Spotify/classes.ts index f637a1f..f5b0185 100644 --- a/play-dl/Spotify/classes.ts +++ b/play-dl/Spotify/classes.ts @@ -115,7 +115,7 @@ export class SpotifyTrack { thumbnail: SpotifyThumbnail | undefined; /** * Constructor for Spotify Track - * @param data + * @param data */ constructor(data: any) { this.name = data.name; @@ -149,7 +149,7 @@ export class SpotifyTrack { else this.thumbnail = data.album.images[0]; } - toJSON() : TrackJSON { + toJSON(): TrackJSON { return { name: this.name, id: this.id, @@ -205,13 +205,13 @@ export class SpotifyPlaylist { tracksCount: number; /** * Spotify Playlist Spotify data - * + * * @private */ private spotifyData: SpotifyDataOptions; /** * Spotify Playlist fetched tracks Map - * + * * @private */ private fetched_tracks: Map; @@ -244,7 +244,7 @@ export class SpotifyPlaylist { } /** * Fetches Spotify Playlist tracks more than 100 tracks. - * + * * For getting all tracks in playlist, see `total_pages` property. * @returns Playlist Class. */ @@ -283,18 +283,18 @@ export class SpotifyPlaylist { } /** * Spotify Playlist tracks are divided in pages. - * + * * For example getting data of 101 - 200 videos in a playlist, - * + * * ```ts * const playlist = await play.spotify('playlist url') - * + * * await playlist.fetch() - * + * * const result = playlist.page(2) * ``` * @param num Page Number - * @returns + * @returns */ page(num: number) { if (!num) throw new Error('Page number is not provided'); @@ -303,16 +303,16 @@ export class SpotifyPlaylist { } /** * Spotify Playlist total no of pages in a playlist - * + * * For getting all songs in a playlist, - * + * * ```ts * const playlist = await play.spotify('playlist url') - * + * * await playlist.fetch() - * + * * const result = [] - * + * * for (let i = 0; i <= playlist.tota_pages; i++) { * result.push(playlist.page(i)) * } @@ -332,7 +332,7 @@ export class SpotifyPlaylist { * Converts Class to JSON * @returns JSON data */ - toJSON() : PlaylistJSON{ + toJSON(): PlaylistJSON { return { name: this.name, collaborative: this.collaborative, @@ -341,7 +341,7 @@ export class SpotifyPlaylist { id: this.id, thumbnail: this.thumbnail, owner: this.owner, - tracksCount : this.tracksCount + tracksCount: this.tracksCount }; } } @@ -391,21 +391,21 @@ export class SpotifyAlbum { tracksCount: number; /** * Spotify Album Spotify data - * + * * @private */ - private spotifyData: SpotifyDataOptions; - /** - * Spotify Album fetched tracks Map - * - * @private - */ - private fetched_tracks: Map; - /** - * Constructor for Spotify Album Class - * @param data Json parsed album data - * @param spotifyData Spotify credentials - */ + private spotifyData: SpotifyDataOptions; + /** + * Spotify Album fetched tracks Map + * + * @private + */ + private fetched_tracks: Map; + /** + * Constructor for Spotify Album Class + * @param data Json parsed album data + * @param spotifyData Spotify credentials + */ constructor(data: any, spotifyData: SpotifyDataOptions) { this.name = data.name; this.type = 'album'; @@ -435,7 +435,7 @@ export class SpotifyAlbum { } /** * Fetches Spotify Album tracks more than 50 tracks. - * + * * For getting all tracks in album, see `total_pages` property. * @returns Album Class. */ @@ -474,18 +474,18 @@ export class SpotifyAlbum { } /** * Spotify Album tracks are divided in pages. - * + * * For example getting data of 51 - 100 videos in a album, - * + * * ```ts * const album = await play.spotify('album url') - * + * * await album.fetch() - * + * * const result = album.page(2) * ``` * @param num Page Number - * @returns + * @returns */ page(num: number) { if (!num) throw new Error('Page number is not provided'); @@ -494,16 +494,16 @@ export class SpotifyAlbum { } /** * Spotify Album total no of pages in a album - * + * * For getting all songs in a album, - * + * * ```ts * const album = await play.spotify('album url') - * + * * await album.fetch() - * + * * const result = [] - * + * * for (let i = 0; i <= album.tota_pages; i++) { * result.push(album.page(i)) * } @@ -520,10 +520,10 @@ export class SpotifyAlbum { return (page_number - 1) * 100 + (this.fetched_tracks.get(`${page_number}`) as SpotifyTrack[]).length; } - toJSON() : AlbumJSON { + toJSON(): AlbumJSON { return { name: this.name, - id : this.id, + id: this.id, type: this.type, url: this.url, thumbnail: this.thumbnail, @@ -531,7 +531,7 @@ export class SpotifyAlbum { copyrights: this.copyrights, release_date: this.release_date, release_date_precision: this.release_date_precision, - tracksCount : this.tracksCount + tracksCount: this.tracksCount }; } } diff --git a/play-dl/Spotify/constants.ts b/play-dl/Spotify/constants.ts index 8f4428c..8c901ba 100644 --- a/play-dl/Spotify/constants.ts +++ b/play-dl/Spotify/constants.ts @@ -1,118 +1,118 @@ -import { SpotifyArtists, SpotifyCopyright, SpotifyThumbnail, SpotifyTrackAlbum } from './classes' +import { SpotifyArtists, SpotifyCopyright, SpotifyThumbnail, SpotifyTrackAlbum } from './classes'; -export interface TrackJSON{ +export interface TrackJSON { /** * Spotify Track Name */ - name: string; - /** - * Spotify Track ID - */ - id: string; - /** - * Spotify Track url - */ - url: string; - /** - * Spotify Track explicit info. - */ - explicit: boolean; - /** - * Spotify Track Duration in seconds - */ - durationInSec: number; - /** - * Spotify Track Duration in milli seconds - */ - durationInMs: number; - /** - * Spotify Track Artists data [ array ] - */ - artists: SpotifyArtists[]; - /** - * Spotify Track Album data - */ - album: SpotifyTrackAlbum | undefined; - /** - * Spotify Track Thumbnail Data - */ - thumbnail: SpotifyThumbnail | undefined; + name: string; + /** + * Spotify Track ID + */ + id: string; + /** + * Spotify Track url + */ + url: string; + /** + * Spotify Track explicit info. + */ + explicit: boolean; + /** + * Spotify Track Duration in seconds + */ + durationInSec: number; + /** + * Spotify Track Duration in milli seconds + */ + durationInMs: number; + /** + * Spotify Track Artists data [ array ] + */ + artists: SpotifyArtists[]; + /** + * Spotify Track Album data + */ + album: SpotifyTrackAlbum | undefined; + /** + * Spotify Track Thumbnail Data + */ + thumbnail: SpotifyThumbnail | undefined; } export interface PlaylistJSON { /** * Spotify Playlist Name */ - name: string; - /** - * Spotify Playlist collaborative boolean. - */ - collaborative: boolean; - /** - * Spotify Playlist Description - */ - description: string; - /** - * Spotify Playlist URL - */ - url: string; - /** - * Spotify Playlist ID - */ - id: string; - /** - * Spotify Playlist Thumbnail Data - */ - thumbnail: SpotifyThumbnail; - /** - * Spotify Playlist Owner Artist data - */ - owner: SpotifyArtists; - /** - * Spotify Playlist total tracks Count - */ - tracksCount: number; + name: string; + /** + * Spotify Playlist collaborative boolean. + */ + collaborative: boolean; + /** + * Spotify Playlist Description + */ + description: string; + /** + * Spotify Playlist URL + */ + url: string; + /** + * Spotify Playlist ID + */ + id: string; + /** + * Spotify Playlist Thumbnail Data + */ + thumbnail: SpotifyThumbnail; + /** + * Spotify Playlist Owner Artist data + */ + owner: SpotifyArtists; + /** + * Spotify Playlist total tracks Count + */ + tracksCount: number; } -export interface AlbumJSON{ +export interface AlbumJSON { /** * Spotify Album Name */ - name: string; - /** - * Spotify Class type. == "album" - */ - type: 'track' | 'playlist' | 'album'; - /** - * Spotify Album url - */ - url: string; - /** - * Spotify Album id - */ - id: string; - /** - * Spotify Album Thumbnail data - */ - thumbnail: SpotifyThumbnail; - /** - * Spotify Album artists [ array ] - */ - artists: SpotifyArtists[]; - /** - * Spotify Album copyright data [ array ] - */ - copyrights: SpotifyCopyright[]; - /** - * Spotify Album Release date - */ - release_date: string; - /** - * Spotify Album Release Date **precise** - */ - release_date_precision: string; - /** - * Spotify Album total no of tracks - */ - tracksCount: number; -} \ No newline at end of file + name: string; + /** + * Spotify Class type. == "album" + */ + type: 'track' | 'playlist' | 'album'; + /** + * Spotify Album url + */ + url: string; + /** + * Spotify Album id + */ + id: string; + /** + * Spotify Album Thumbnail data + */ + thumbnail: SpotifyThumbnail; + /** + * Spotify Album artists [ array ] + */ + artists: SpotifyArtists[]; + /** + * Spotify Album copyright data [ array ] + */ + copyrights: SpotifyCopyright[]; + /** + * Spotify Album Release date + */ + release_date: string; + /** + * Spotify Album Release Date **precise** + */ + release_date_precision: string; + /** + * Spotify Album total no of tracks + */ + tracksCount: number; +} diff --git a/play-dl/Spotify/index.ts b/play-dl/Spotify/index.ts index 69b65b2..f538450 100644 --- a/play-dl/Spotify/index.ts +++ b/play-dl/Spotify/index.ts @@ -27,12 +27,12 @@ export interface SpotifyDataOptions { const pattern = /^((https:)?\/\/)?open.spotify.com\/(track|album|playlist)\//; /** * Gets Spotify url details. - * + * * ```ts * let spot = await play.spotify('spotify url') - * + * * // spot.type === "track" | "playlist" | "album" - * + * * if (spot.type === "track") { * spot = spot as play.SpotifyTrack * // Code with spotify track class. @@ -85,7 +85,7 @@ export async function spotify(url: string): Promise { /** * Validate Spotify url * @param url Spotify URL - * @returns + * @returns * ```ts * 'track' | 'playlist' | 'album' | 'search' | false * ``` @@ -144,7 +144,7 @@ export async function SpotifyAuthorize(data: SpotifyDataOptions, file: boolean): } /** * Checks if spotify token is expired or not. - * + * * Update token if returned false. * ```ts * if (!play.is_expired()) { @@ -206,7 +206,7 @@ export async function sp_search( } /** * Refreshes Token - * + * * ```ts * if (!play.is_expired()) { * await play.refreshToken() @@ -243,4 +243,4 @@ export function setSpotifyToken(options: SpotifyDataOptions) { refreshToken(); } -export { SpotifyTrack, SpotifyAlbum, SpotifyPlaylist } \ No newline at end of file +export { SpotifyTrack, SpotifyAlbum, SpotifyPlaylist }; diff --git a/play-dl/YouTube/classes/Channel.ts b/play-dl/YouTube/classes/Channel.ts index 8ca5539..fc6d981 100644 --- a/play-dl/YouTube/classes/Channel.ts +++ b/play-dl/YouTube/classes/Channel.ts @@ -86,7 +86,7 @@ export class YouTubeChannel { * Converts Channel Class to JSON format * @returns json data of the channel */ - toJSON() : ChannelJSON { + toJSON(): ChannelJSON { return { name: this.name, verified: this.verified, @@ -100,37 +100,37 @@ export class YouTubeChannel { } } -interface ChannelJSON{ +interface ChannelJSON { /** * YouTube Channel Title */ - name?: string; - /** - * YouTube Channel Verified status. - */ - verified?: boolean; - /** - * YouTube Channel artist if any. - */ - artist?: boolean; - /** - * YouTube Channel ID. - */ - id?: string; - /** - * Type of Class [ Channel ] - */ - type: 'video' | 'playlist' | 'channel'; - /** - * YouTube Channel Url - */ - url?: string; - /** - * YouTube Channel Icon data. - */ - icons?: ChannelIconInterface[]; - /** - * YouTube Channel subscribers count. - */ - subscribers?: string; -} \ No newline at end of file + name?: string; + /** + * YouTube Channel Verified status. + */ + verified?: boolean; + /** + * YouTube Channel artist if any. + */ + artist?: boolean; + /** + * YouTube Channel ID. + */ + id?: string; + /** + * Type of Class [ Channel ] + */ + type: 'video' | 'playlist' | 'channel'; + /** + * YouTube Channel Url + */ + url?: string; + /** + * YouTube Channel Icon data. + */ + icons?: ChannelIconInterface[]; + /** + * YouTube Channel subscribers count. + */ + subscribers?: string; +} diff --git a/play-dl/YouTube/classes/LiveStream.ts b/play-dl/YouTube/classes/LiveStream.ts index 25defbf..c47925a 100644 --- a/play-dl/YouTube/classes/LiveStream.ts +++ b/play-dl/YouTube/classes/LiveStream.ts @@ -47,19 +47,19 @@ export class LiveStream { private video_url: string; /** * Timer used to update dash url so as to avoid 404 errors after long hours of streaming. - * + * * It updates dash_url every 30 minutes. */ private dash_timer: Timer; /** * Segments of url that we recieve in dash file. - * + * * base_url + segment_urls[0] = One complete url for one segment. */ private segments_urls: string[]; /** * Incoming message that we recieve. - * + * * Storing this is essential. * This helps to destroy the TCP connection completely if you stopped player in between the stream */ @@ -94,7 +94,7 @@ export class LiveStream { } /** * Updates dash url. - * + * * Used by dash_timer for updating dash_url every 30 minutes. */ private async dash_updater() { @@ -109,7 +109,7 @@ export class LiveStream { } /** * Parses data recieved from dash_url. - * + * * Updates base_url , segments_urls array. */ private async dash_getter() { @@ -126,7 +126,7 @@ export class LiveStream { } /** * This cleans every used variable in class. - * + * * This is used to prevent re-use of this class and helping garbage collector to collect it. */ private cleanup() { @@ -143,7 +143,7 @@ export class LiveStream { } /** * This starts function in Live Stream Class. - * + * * Gets data from dash url and pass it to dash getter function. * Get data from complete segment url and pass data to Stream. */ @@ -197,14 +197,14 @@ export class Stream { /** * Readable Stream through which data passes */ - stream: Readable; - /** - * Type of audio data that we recieved from normal youtube url. - */ - type: StreamType; - /** - * Audio Endpoint Format Url to get data from. - */ + stream: Readable; + /** + * Type of audio data that we recieved from normal youtube url. + */ + type: StreamType; + /** + * Audio Endpoint Format Url to get data from. + */ private url: string; /** * Used to calculate no of bytes data that we have recieved @@ -236,7 +236,7 @@ export class Stream { private proxy: Proxy[] | undefined; /** * Incoming message that we recieve. - * + * * Storing this is essential. * This helps to destroy the TCP connection completely if you stopped player in between the stream */ @@ -288,7 +288,7 @@ export class Stream { } /** * This cleans every used variable in class. - * + * * This is used to prevent re-use of this class and helping garbage collector to collect it. */ private cleanup() { @@ -298,7 +298,7 @@ export class Stream { } /** * Getting data from audio endpoint url and passing it to stream. - * + * * If 404 or 403 occurs, it will retry again. */ private async loop() { @@ -354,7 +354,7 @@ export class Stream { /** * Pauses timer. * Stops running of loop. - * + * * Useful if you don't want to get excess data to be stored in stream. */ pause() { @@ -370,7 +370,7 @@ export class Stream { } /** * Timer Class. - * + * * setTimeout + extra features ( re-starting, pausing, resuming ). */ export class Timer { @@ -456,7 +456,7 @@ export class Timer { } /** * Destroy timer. - * + * * It can't be used again. */ destroy() { diff --git a/play-dl/YouTube/classes/Playlist.ts b/play-dl/YouTube/classes/Playlist.ts index e599bc3..da60033 100644 --- a/play-dl/YouTube/classes/Playlist.ts +++ b/play-dl/YouTube/classes/Playlist.ts @@ -47,7 +47,7 @@ export class YouTubePlayList { /** * YouTube Playlist thumbnail Data */ - thumbnail?: YouTubeThumbnail + thumbnail?: YouTubeThumbnail; /** * Videos array containing data of first 100 videos */ @@ -121,7 +121,7 @@ export class YouTubePlayList { /** * Parses next segment of videos from playlist and returns parsed data. * @param limit Total no of videos to parse. - * + * * Default = Infinity * @returns Array of YouTube Video Class */ @@ -157,12 +157,12 @@ export class YouTubePlayList { } /** * Fetches remaining data from playlist - * + * * For fetching and getting all songs data, see `total_pages` property. * @param max Max no of videos to fetch - * + * * Default = Infinity - * @returns + * @returns */ async fetch(max = Infinity): Promise { const continuation = this._continuation.token; @@ -173,7 +173,7 @@ export class YouTubePlayList { this.__count++; const res = await this.next(); max -= res.length; - if(max <= 0) break; + if (max <= 0) break; if (!res.length) break; } @@ -181,14 +181,14 @@ export class YouTubePlayList { } /** * YouTube Playlist is divided into pages. - * + * * For example, if you want to get 101 - 200 songs - * + * * ```ts * const playlist = await play.playlist_info('playlist url') - * + * * await playlist.fetch() - * + * * const result = playlist.page(2) * ``` * @param number Page number @@ -201,16 +201,16 @@ export class YouTubePlayList { } /** * Gets total no of pages in that playlist class. - * + * * For getting all songs in a playlist - * + * * ```ts * const playlist = await play.playlist_info('playlist url'); - * + * * await playlist.fetch(); - * + * * let result = []; - * + * * for (let i = 0; i <= playlist.total_pages; i++) { * result.push(playlist.page(i)); * } @@ -221,7 +221,7 @@ export class YouTubePlayList { } /** * This tells total no of videos that have been fetched so far. - * + * * This can be equal to videosCount if all videos in playlist have been fetched and they are not hidden. */ get total_videos() { @@ -230,9 +230,9 @@ export class YouTubePlayList { } /** * Converts Playlist Class to a json parsed data. - * @returns + * @returns */ - toJSON() : PlaylistJSON { + toJSON(): PlaylistJSON { return { id: this.id, title: this.title, @@ -244,50 +244,50 @@ export class YouTubePlayList { } } -interface PlaylistJSON{ +interface PlaylistJSON { /** * YouTube Playlist ID */ - id?: string; - /** - * YouTube Playlist Name - */ - title?: string; - /** - * Total no of videos in that playlist - */ - videoCount?: number; - /** - * Time when playlist was last updated - */ - lastUpdate?: string; - /** - * Total views of that playlist - */ - views?: number; - /** - * YouTube Playlist url - */ - url?: string; - /** - * YouTube Playlist url with starting video url. - */ - link?: string; - /** - * YouTube Playlist channel data - */ - channel?: YouTubeChannel; - /** - * YouTube Playlist thumbnail Data - */ - thumbnail?: { - id: string | undefined; - width: number | undefined; - height: number | undefined; - url: string | undefined; - }; - /** - * first 100 videos in that playlist - */ - videos? : YouTubeVideo[] -} \ No newline at end of file + id?: string; + /** + * YouTube Playlist Name + */ + title?: string; + /** + * Total no of videos in that playlist + */ + videoCount?: number; + /** + * Time when playlist was last updated + */ + lastUpdate?: string; + /** + * Total views of that playlist + */ + views?: number; + /** + * YouTube Playlist url + */ + url?: string; + /** + * YouTube Playlist url with starting video url. + */ + link?: string; + /** + * YouTube Playlist channel data + */ + channel?: YouTubeChannel; + /** + * YouTube Playlist thumbnail Data + */ + thumbnail?: { + id: string | undefined; + width: number | undefined; + height: number | undefined; + url: string | undefined; + }; + /** + * first 100 videos in that playlist + */ + videos?: YouTubeVideo[]; +} diff --git a/play-dl/YouTube/classes/Thumbnail.ts b/play-dl/YouTube/classes/Thumbnail.ts index 39eefe6..b675eda 100644 --- a/play-dl/YouTube/classes/Thumbnail.ts +++ b/play-dl/YouTube/classes/Thumbnail.ts @@ -1,22 +1,22 @@ export class YouTubeThumbnail { - id : string; - url : string; - width : number; - height : number; + id: string; + url: string; + width: number; + height: number; - constructor(data : any){ - this.id = data.id - this.url = data.url - this.width = data.width - this.height = data.height + constructor(data: any) { + this.id = data.id; + this.url = data.url; + this.width = data.width; + this.height = data.height; } - toJSON(){ + toJSON() { return { - id : this.id, - url : this.url, - width : this.width, - height : this.height - } + id: this.id, + url: this.url, + width: this.width, + height: this.height + }; } -} \ No newline at end of file +} diff --git a/play-dl/YouTube/classes/Video.ts b/play-dl/YouTube/classes/Video.ts index 4e4b0fa..b61bf3f 100644 --- a/play-dl/YouTube/classes/Video.ts +++ b/play-dl/YouTube/classes/Video.ts @@ -5,68 +5,68 @@ interface VideoOptions { /** * YouTube Video ID */ - id?: string; - /** - * YouTube video url - */ - url: string; - /** - * YouTube Video title - */ - title?: string; - /** - * YouTube Video description. - */ - description?: string; - /** - * YouTube Video Duration Formatted - */ - durationRaw: string; - /** - * YouTube Video Duration in seconds - */ - durationInSec: number; - /** - * YouTube Video Uploaded Date - */ - uploadedAt?: string; - /** - * YouTube Views - */ - views: number; - /** - * YouTube Thumbnail Data - */ - thumbnail?: { + id?: string; + /** + * YouTube video url + */ + url: string; + /** + * YouTube Video title + */ + title?: string; + /** + * YouTube Video description. + */ + description?: string; + /** + * YouTube Video Duration Formatted + */ + durationRaw: string; + /** + * YouTube Video Duration in seconds + */ + durationInSec: number; + /** + * YouTube Video Uploaded Date + */ + uploadedAt?: string; + /** + * YouTube Views + */ + views: number; + /** + * YouTube Thumbnail Data + */ + thumbnail?: { id: string | undefined; width: number | undefined; height: number | undefined; url: string | undefined; }; - /** - * YouTube Video's uploader Channel Data - */ - channel?: YouTubeChannel; - /** - * YouTube Video's likes - */ - likes: number; - /** - * YouTube Video's dislikes - */ - dislikes: number; - /** - * YouTube Video live status - */ - live: boolean; - /** - * YouTube Video private status - */ - private: boolean; - /** - * YouTube Video tags - */ - tags: string[]; + /** + * YouTube Video's uploader Channel Data + */ + channel?: YouTubeChannel; + /** + * YouTube Video's likes + */ + likes: number; + /** + * YouTube Video's dislikes + */ + dislikes: number; + /** + * YouTube Video live status + */ + live: boolean; + /** + * YouTube Video private status + */ + private: boolean; + /** + * YouTube Video tags + */ + tags: string[]; } /** * Class for YouTube Video url diff --git a/play-dl/YouTube/index.ts b/play-dl/YouTube/index.ts index 54f5d91..d9c6850 100644 --- a/play-dl/YouTube/index.ts +++ b/play-dl/YouTube/index.ts @@ -1,6 +1,6 @@ export { stream, stream_from_info, YouTubeStream } from './stream'; export * from './utils'; export { YouTube } from './search'; -export { YouTubeVideo } from './classes/Video' -export { YouTubePlayList } from './classes/Playlist' -export { YouTubeChannel } from './classes/Channel' +export { YouTubeVideo } from './classes/Video'; +export { YouTubePlayList } from './classes/Playlist'; +export { YouTubeChannel } from './classes/Channel'; diff --git a/play-dl/YouTube/utils/constants.ts b/play-dl/YouTube/utils/constants.ts index c837ad5..23c746a 100644 --- a/play-dl/YouTube/utils/constants.ts +++ b/play-dl/YouTube/utils/constants.ts @@ -1,39 +1,39 @@ -import { YouTubeVideo } from "../classes/Video"; +import { YouTubeVideo } from '../classes/Video'; export interface LiveStreamData { isLive: boolean; - dashManifestUrl: string | null - hlsManifestUrl: string | null + dashManifestUrl: string | null; + hlsManifestUrl: string | null; } export interface formatData { - itag: number; - mimeType: string - bitrate: number - width: number - height: number - lastModified: string - contentLength: string - quality: string - fps: number - qualityLabel: string - projectionType: string - averageBitrate: number - audioQuality: string - approxDurationMs: string - audioSampleRate: string - audioChannels: number - url : string - signatureCipher : string; - cipher : string; - loudnessDb : number; - targetDurationSec : number; + itag: number; + mimeType: string; + bitrate: number; + width: number; + height: number; + lastModified: string; + contentLength: string; + quality: string; + fps: number; + qualityLabel: string; + projectionType: string; + averageBitrate: number; + audioQuality: string; + approxDurationMs: string; + audioSampleRate: string; + audioChannels: number; + url: string; + signatureCipher: string; + cipher: string; + loudnessDb: number; + targetDurationSec: number; } -export interface InfoData{ - LiveStreamData : LiveStreamData - html5player : string - format : Partial[] - video_details : YouTubeVideo - related_videos: string[] -} \ No newline at end of file +export interface InfoData { + LiveStreamData: LiveStreamData; + html5player: string; + format: Partial[]; + video_details: YouTubeVideo; + related_videos: string[]; +} diff --git a/play-dl/YouTube/utils/cookie.ts b/play-dl/YouTube/utils/cookie.ts index e4cf712..c6d8922 100644 --- a/play-dl/YouTube/utils/cookie.ts +++ b/play-dl/YouTube/utils/cookie.ts @@ -46,3 +46,29 @@ export function setCookieToken(options: { cookie: string }) { youtubeData = { cookie }; youtubeData.file = false; } + +/** + * Updates cookies locally either in file or in memory. + * + * Example + * ```ts + * const response = ... // Any https package get function. + * + * play.cookieHeaders(response.headers['set-cookie']) + * ``` + * @param headCookie response headers['set-cookie'] array + * @returns Nothing + */ + export function cookieHeaders(headCookie: string[]): void { + if (!youtubeData?.cookie) return; + headCookie.forEach((x: string) => { + x.split(';').forEach((z) => { + const arr = z.split('='); + if (arr.length <= 1) return; + const key = arr.shift()?.trim() as string; + const value = arr.join('=').trim(); + setCookie(key, value); + }); + }); + uploadCookie(); +} diff --git a/play-dl/YouTube/utils/extractor.ts b/play-dl/YouTube/utils/extractor.ts index 6a2798f..5ed241b 100644 --- a/play-dl/YouTube/utils/extractor.ts +++ b/play-dl/YouTube/utils/extractor.ts @@ -23,9 +23,9 @@ const playlist_pattern = /^((?:https?:)?\/\/)?(?:(?:www|m)\.)?(youtube\.com)\/(?:(playlist|watch))(.*)?((\?|\&)list=)(PL|UU|LL|RD|OL)[a-zA-Z\d_-]{16,41}(.*)?$/; /** * Validate YouTube URL or ID. - * + * * **CAUTION :** If your search word is 11-12 long, you might get it validated as video ID. - * + * * To avoid above, add one more condition to yt_validate * ```ts * if (url.startsWith('https') && yt_validate(url) === 'video') { @@ -33,7 +33,7 @@ const playlist_pattern = * } * ``` * @param url YouTube URL OR ID - * @returns + * @returns * ``` * 'playlist' | 'video' | 'search' | false * ``` @@ -114,7 +114,7 @@ export function extractID(url: string): string { * - `boolean` htmldata : given data is html data or not * @returns Video Basic Info {@link InfoData}. */ -export async function video_basic_info(url: string, options: InfoOptions = {}) : Promise { +export async function video_basic_info(url: string, options: InfoOptions = {}): Promise { let body: string; if (options.htmldata) { body = url; @@ -147,11 +147,10 @@ export async function video_basic_info(url: string, options: InfoOptions = {}) : player_response.playabilityStatus.errorScreen.playerKavRenderer?.reason.simpleText }` ); - const ownerInfo = initial_response.contents.twoColumnWatchNextResults.results?.results?.contents[1]?.videoSecondaryInfoRenderer - ?.owner?.videoOwnerRenderer - const badge = - ownerInfo?.badges && - ownerInfo?.badges[0]; + const ownerInfo = + initial_response.contents.twoColumnWatchNextResults.results?.results?.contents[1]?.videoSecondaryInfoRenderer + ?.owner?.videoOwnerRenderer; + const badge = ownerInfo?.badges && ownerInfo?.badges[0]; const html5player = `https://www.youtube.com${body.split('"jsUrl":"')[1].split('"')[0]}`; const related: string[] = []; initial_response.contents.twoColumnWatchNextResults.secondaryResults.secondaryResults.results.forEach( @@ -178,7 +177,7 @@ export async function video_basic_info(url: string, options: InfoOptions = {}) : url: `https://www.youtube.com/channel/${vid.channelId}`, verified: Boolean(badge?.metadataBadgeRenderer?.style?.toLowerCase().includes('verified')), artist: Boolean(badge?.metadataBadgeRenderer?.style?.toLowerCase().includes('artist')), - icons : ownerInfo?.thumbnail?.thumbnails || undefined + icons: ownerInfo?.thumbnail?.thumbnails || undefined }, views: vid.viewCount, tags: vid.keywords, diff --git a/play-dl/YouTube/utils/parser.ts b/play-dl/YouTube/utils/parser.ts index 0062bb6..6da4134 100644 --- a/play-dl/YouTube/utils/parser.ts +++ b/play-dl/YouTube/utils/parser.ts @@ -134,8 +134,8 @@ export function parseVideo(data?: any): YouTubeVideo { data.videoRenderer.ownerText.runs[0].navigationEndpoint.browseEndpoint.canonicalBaseUrl || data.videoRenderer.ownerText.runs[0].navigationEndpoint.commandMetadata.webCommandMetadata.url }`, - icons : data.videoRenderer.channelThumbnailSupportedRenderers.channelThumbnailWithLinkRenderer.thumbnail - .thumbnails, + icons: data.videoRenderer.channelThumbnailSupportedRenderers.channelThumbnailWithLinkRenderer.thumbnail + .thumbnails, verified: Boolean(badge?.metadataBadgeRenderer?.style?.toLowerCase().includes('verified')), artist: Boolean(badge?.metadataBadgeRenderer?.style?.toLowerCase().includes('artist')) }, diff --git a/play-dl/index.ts b/play-dl/index.ts index 082b46c..e318e5c 100644 --- a/play-dl/index.ts +++ b/play-dl/index.ts @@ -11,9 +11,34 @@ export { YouTubePlayList, YouTubeVideo } from './YouTube'; -export { spotify, sp_validate, refreshToken, is_expired, SpotifyAlbum, SpotifyPlaylist, SpotifyTrack, Spotify } from './Spotify'; -export { soundcloud, so_validate, SoundCloud, SoundCloudStream, getFreeClientID, SoundCloudPlaylist, SoundCloudTrack } from './SoundCloud'; -export { deezer, dz_validate, dz_advanced_track_search, Deezer, DeezerTrack, DeezerPlaylist, DeezerAlbum } from './Deezer'; +export { + spotify, + sp_validate, + refreshToken, + is_expired, + SpotifyAlbum, + SpotifyPlaylist, + SpotifyTrack, + Spotify +} from './Spotify'; +export { + soundcloud, + so_validate, + SoundCloud, + SoundCloudStream, + getFreeClientID, + SoundCloudPlaylist, + SoundCloudTrack +} from './SoundCloud'; +export { + deezer, + dz_validate, + dz_advanced_track_search, + Deezer, + DeezerTrack, + DeezerPlaylist, + DeezerAlbum +} from './Deezer'; export { setToken } from './token'; enum AudioPlayerStatus { @@ -83,6 +108,56 @@ export async function stream(url: string, options: StreamOptions = {}): Promise< else return await yt_stream(url, options); } +export async function search( + query: string, + options: { source: { deezer: 'album' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { deezer: 'playlist' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { deezer: 'track' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { soundcloud: 'albums' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { soundcloud: 'playlists' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { soundcloud: 'tracks' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { spotify: 'album' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { spotify: 'playlist' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { spotify: 'track' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { youtube: 'channel' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { youtube: 'playlist' } } & SearchOptions +): Promise; +export async function search( + query: string, + options: { source: { youtube: 'video' } } & SearchOptions +): Promise; +export async function search(query: string, options: { limit: number } & SearchOptions): Promise; +export async function search(query: string, options?: SearchOptions): Promise; /** * Main Search Command for searching through various sources * @param query string to search. @@ -90,20 +165,6 @@ export async function stream(url: string, options: StreamOptions = {}): Promise< * @returns Array of YouTube or Spotify or SoundCloud or Deezer deezer?: 'track' | 'playlist' | 'album'; */ -export async function search( query: string, options: { source : { deezer : "album" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { deezer : "playlist" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { deezer : "track" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { soundcloud : "albums" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { soundcloud : "playlists" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { soundcloud : "tracks" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { spotify : "album" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { spotify : "playlist" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { spotify : "track" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { youtube : "channel" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { youtube : "playlist" } } & SearchOptions) : Promise; -export async function search( query: string, options: { source : { youtube : "video" } } & SearchOptions) : Promise; -export async function search( query: string, options: { limit : number } & SearchOptions ) : Promise; -export async function search( query: string, options? : SearchOptions) : Promise; export async function search( query: string, options: SearchOptions = {} @@ -114,7 +175,7 @@ export async function search( else if (options.source.spotify) return await sp_search(query, options.source.spotify, options.limit); else if (options.source.soundcloud) return await so_search(query, options.source.soundcloud, options.limit); else if (options.source.deezer) - return await dz_search(query, { limit: options.limit, type: options.source.deezer, fuzzy : options.fuzzy }); + return await dz_search(query, { limit: options.limit, type: options.source.deezer, fuzzy: options.fuzzy }); else throw new Error('Not possible to reach Here LOL. Easter Egg of play-dl if someone get this.'); } diff --git a/play-dl/token.ts b/play-dl/token.ts index 89600b8..9722765 100644 --- a/play-dl/token.ts +++ b/play-dl/token.ts @@ -17,14 +17,14 @@ interface tokenOptions { }; } /** - * Sets - * + * Sets + * * i> YouTube :- cookies. - * + * * ii> SoundCloud :- client ID. - * + * * iii> Spotify :- client ID, client secret, refresh token, market. - * + * * locally in memory. * @param options {@link tokenOptions} */ From bfbcc69e92ee7335c4fa0d12c8be1b43a190bf8a Mon Sep 17 00:00:00 2001 From: killer069 <65385476+killer069@users.noreply.github.com> Date: Tue, 23 Nov 2021 11:05:13 +0530 Subject: [PATCH 4/7] Documentation 100% complete --- play-dl/index.ts | 144 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 125 insertions(+), 19 deletions(-) diff --git a/play-dl/index.ts b/play-dl/index.ts index e318e5c..cafc997 100644 --- a/play-dl/index.ts +++ b/play-dl/index.ts @@ -87,10 +87,25 @@ import { SpotifyAlbum, SpotifyPlaylist, SpotifyTrack } from './Spotify/classes'; import { DeezerAlbum, DeezerPlaylist, DeezerTrack } from './Deezer/classes'; /** - * Main stream Command for streaming through various sources - * @param url The video / track url to make stream of - * @param options contains quality, cookie and proxy to set for stream - * @returns YouTube / SoundCloud Stream to play + * Creates a Stream [ YouTube or SoundCloud ] class from a url for playing. + * + * Example + * ```ts + * const source = await play.stream('youtube video URL') // YouTube Video Stream + * + * const source = await play.stream('soundcloud track URL') // SoundCloud Track Stream + * + * const resource = createAudioResource(source.stream, { + * inputType : source.type + * }) // Use discordjs voice createAudioResource function. + * ``` + * @param url Video / Track URL + * @param options + * + * - `number` quality : Quality number. [ 0 = Lowest, 1 = Medium, 2 = Highest ] + * - `Proxy[]` proxy : sends data through a proxy + * - `boolean` htmldata : given data is html data or not + * @returns A {@link YouTubeStream} or {@link SoundCloudStream} Stream to play */ export async function stream(url: string, options: StreamOptions = {}): Promise { if (url.length === 0) throw new Error('Stream URL has a length of 0. Check your url again.'); @@ -108,6 +123,35 @@ export async function stream(url: string, options: StreamOptions = {}): Promise< else return await yt_stream(url, options); } +/** + * Searches through a particular source and gives respective info. + * + * Example + * ```ts + * const searched = await play.search('Rick Roll', { source : { youtube : "video" } }) // YouTube Video Search + * + * const searched = await play.search('Rick Roll', { limit : 1 }) // YouTube Video Search but returns only 1 video. + * + * const searched = await play.search('Rick Roll', { source : { spotify : "track" } }) // Spotify Track Search + * + * const searched = await play.search('Rick Roll', { source : { soundcloud : "tracks" } }) // SoundCloud Track Search + * + * const searched = await play.search('Rick Roll', { source : { deezer : "track" } }) // Deezer Track Search + * ``` + * @param query string to search. + * @param options + * + * - `number` limit : No of searches you want to have. + * - `boolean` fuzzy : Whether the search should be fuzzy or only return exact matches. Defaults to `true`. [ for `Deezer` Only ] + * - `Object` source : Contains type of source and type of result you want to have + * ```ts + * - youtube : 'video' | 'playlist' | 'channel'; + - spotify : 'album' | 'playlist' | 'track'; + - soundcloud : 'tracks' | 'playlists' | 'albums'; + - deezer : 'track' | 'playlist' | 'album'; + ``` + * @returns Array of {@link YouTube} or {@link Spotify} or {@link SoundCloud} or {@link Deezer} type + */ export async function search( query: string, options: { source: { deezer: 'album' } } & SearchOptions @@ -157,13 +201,35 @@ export async function search( options: { source: { youtube: 'video' } } & SearchOptions ): Promise; export async function search(query: string, options: { limit: number } & SearchOptions): Promise; -export async function search(query: string, options?: SearchOptions): Promise; +export async function search(query: string, options? : SearchOptions ): Promise; /** - * Main Search Command for searching through various sources + * Searches through a particular source and gives respective info. + * + * Example + * ```ts + * const searched = await play.search('Rick Roll', { source : { youtube : "video" } }) // YouTube Video Search + * + * const searched = await play.search('Rick Roll', { limit : 1 }) // YouTube Video Search but returns only 1 video. + * + * const searched = await play.search('Rick Roll', { source : { spotify : "track" } }) // Spotify Track Search + * + * const searched = await play.search('Rick Roll', { source : { soundcloud : "tracks" } }) // SoundCloud Track Search + * + * const searched = await play.search('Rick Roll', { source : { deezer : "track" } }) // Deezer Track Search + * ``` * @param query string to search. - * @param options contains limit and source to choose. - * @returns Array of YouTube or Spotify or SoundCloud or Deezer - deezer?: 'track' | 'playlist' | 'album'; + * @param options + * + * - `number` limit : No of searches you want to have. + * - `boolean` fuzzy : Whether the search should be fuzzy or only return exact matches. Defaults to `true`. [ for `Deezer` Only ] + * - `Object` source : Contains type of source and type of result you want to have + * ```ts + * - youtube : 'video' | 'playlist' | 'channel'; + - spotify : 'album' | 'playlist' | 'track'; + - soundcloud : 'tracks' | 'playlists' | 'albums'; + - deezer : 'track' | 'playlist' | 'album'; + ``` + * @returns Array of {@link YouTube} or {@link Spotify} or {@link SoundCloud} or {@link Deezer} type */ export async function search( query: string, @@ -180,11 +246,27 @@ export async function search( } /** - * stream Command for streaming through various sources using data from video_info or soundcloud - * SoundCloud Track is only supported - * @param info video_info data or SoundCloud Track data. - * @param options contains quality, cookie and proxy to set for stream - * @returns YouTube / SoundCloud Stream to play + * Creates a Stream [ YouTube or SoundCloud ] class from video or track info for playing. + * + * Example + * ```ts + * const info = await video_info('youtube URL') + * const source = await play.stream_from_info(info) // YouTube Video Stream + * + * const soundInfo = await play.soundcloud('SoundCloud URL') + * const source = await play.stream_from_info(soundInfo) // SoundCloud Track Stream + * + * const resource = createAudioResource(source.stream, { + * inputType : source.type + * }) // Use discordjs voice createAudioResource function. + * ``` + * @param info YouTube video info OR SoundCloud track Class + * @param options + * + * - `number` quality : Quality number. [ 0 = Lowest, 1 = Medium, 2 = Highest ] + * - `Proxy[]` proxy : sends data through a proxy + * - `boolean` htmldata : given data is html data or not + * @returns A {@link YouTubeStream} or {@link SoundCloudStream} Stream to play */ export async function stream_from_info( info: InfoData | SoundCloudTrack, @@ -194,9 +276,17 @@ export async function stream_from_info( else return await yt_stream_info(info, options); } /** - * Command to validate the provided url. It checks whether it supports play-dl or not. - * @param url url to validate - * @returns On failure, returns false else type of url. + * Validates url that play-dl supports. + * + * - `so` - SoundCloud + * - `sp` - Spotify + * - `dz` - Deezer + * - `yt` - YouTube + * @param url URL + * @returns + * ```ts + * 'so_playlist' / 'so_track' | 'sp_track' | 'sp_album' | 'sp_playlist' | 'dz_track' | 'dz_playlist' | 'dz_album' | 'yt_video' | 'yt_playlist' | 'search' | false + * ``` */ export async function validate( url: string @@ -231,7 +321,17 @@ export async function validate( } } /** - * Authorization interface for Spotify and SoundCloud. + * Authorization interface for Spotify, SoundCloud and YouTube. + * + * Either stores info in `.data` folder or shows relevant data to be used in `setToken` function. + * + * ```ts + * const play = require('play-dl) + * + * play.authorization() + * ``` + * + * Just run the above command and you will get a interface asking some questions. */ export function authorization(): void { const ask = readline.createInterface({ @@ -345,7 +445,13 @@ export function authorization(): void { }); }); } - +/** + * Attaches paused, playing, autoPaused Listeners to discordjs voice AudioPlayer. + * + * Useful if you don't want extra data to be downloaded by play-dl. + * @param player discordjs voice AudioPlayer + * @param resource A {@link YouTubeStream} or {@link SoundCloudStream} + */ export function attachListeners(player: EventEmitter, resource: YouTubeStream | SoundCloudStream) { const pauseListener = () => resource.pause(); const resumeListener = () => resource.resume(); From 15b3af73b62ec82b1e9597e8297755f415f02d4c Mon Sep 17 00:00:00 2001 From: killer069 <65385476+killer069@users.noreply.github.com> Date: Tue, 23 Nov 2021 11:08:36 +0530 Subject: [PATCH 5/7] Added example in README file --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e95c537..ac409a4 100644 --- a/README.md +++ b/README.md @@ -29,4 +29,5 @@ import * as play from 'play-dl' // ES-6 import or TS import const play = require('play-dl') //JS importing ``` -## [Documentation](https://play-dl.github.io/modules.html) +### [Documentation](https://play-dl.github.io/modules.html) +### [Examples](./examples) From 147e25e64775d5acc54f09732b42fdd99b3b56bb Mon Sep 17 00:00:00 2001 From: killer069 <65385476+killer069@users.noreply.github.com> Date: Tue, 23 Nov 2021 11:21:43 +0530 Subject: [PATCH 6/7] Instructions added --- README.md | 1 + examples/authorize.js | 3 -- instructions/README.md | 78 ++++++++++++++++++++++++++++++++++++++++++ play-dl/index.ts | 2 +- 4 files changed, 80 insertions(+), 4 deletions(-) delete mode 100644 examples/authorize.js create mode 100644 instructions/README.md diff --git a/README.md b/README.md index ac409a4..46b7339 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,4 @@ const play = require('play-dl') //JS importing ### [Documentation](https://play-dl.github.io/modules.html) ### [Examples](./examples) +### [Instructions](./instructions) diff --git a/examples/authorize.js b/examples/authorize.js deleted file mode 100644 index 4e86661..0000000 --- a/examples/authorize.js +++ /dev/null @@ -1,3 +0,0 @@ -const { authorization } = require('play-dl'); - -authorization() \ No newline at end of file diff --git a/instructions/README.md b/instructions/README.md new file mode 100644 index 0000000..61ea3c4 --- /dev/null +++ b/instructions/README.md @@ -0,0 +1,78 @@ + +## YouTube Cookies + +Steps : - + +- Open your browser, then open dev-tools [ Option + ⌘ + J (on macOS), or Shift + CTRL + J (on Windows/Linux). ] + +- Then go to Network Tab +![image](https://user-images.githubusercontent.com/65385476/131779512-0f5773a2-f7b5-4f9d-afcb-a6d5cd97931c.png) + +- Go to any YouTube URL and find the first request and open it +First Request :- +![image](https://user-images.githubusercontent.com/65385476/131779664-9b63bca0-7036-4405-9945-a51049303665.png) + + **The first request would be watch?v="Your video ID"** + +- Now go to Request Headers +![image](https://user-images.githubusercontent.com/65385476/131779800-adc6f5b9-23e8-4252-aee5-f492d0916baa.png) + +- find cookie in request headers +![image](https://user-images.githubusercontent.com/65385476/131779829-30ffce93-536a-43c2-9266-419c7b9b745b.png) + +- Now just create a new file with this code : + ```ts + const play = require('play-dl'); + + play.authorization(); + ``` + And run this file. You will get a interface asking some question. + +## Spotify + +1. Go to [ Spotify Dashboard ](https://developer.spotify.com/dashboard/login) and create a new application or use old one. +![image](https://user-images.githubusercontent.com/65385476/132643880-a6831ee6-d8f7-4404-b749-0e3f3d611a64.png) + +2. Open that application. You will be given 2 things [ Client ID and Client Secret ( click on `Show Client Secret` to get info ) ]. Note these 2 things somewhere. + +3. Click on Edit Settings and go to Redirect URIs +![image](https://user-images.githubusercontent.com/65385476/132644797-d66b07dc-58cc-4fbd-80a9-6b938be138a9.png) + +4. Add this Redirect URI : `http://127.0.0.1/index.html` or any url according to you. [ Also note this somewhere ] + +5. Now create a `authorize.js` file and add this code : + ```ts + const play = require('play-dl'); + + play.authorization(); + ``` + and run it `node authorize.js` + +6. You will be asked :- + - Saving INFO in file or not. [ If selected no, you will have to use `setToken` function after you get refresh-Token ] + - Client ID + - Client Secret + - Redirect URI or Redirect URL + - Market [ Choose 2 letter code on left side of your country name from [url](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements) ] + - You will be given a link for authorizing. Just paste it in your browser and click on authorize and copy the link that you are redirected to. [ Redirected Link should start with Redirect URI / Redirect URL that you have provided ] + - Paste the url in Redirected URL + +7. You have completed Authorization part. Now you can delete authorize js file. + +You will notice that a folder named `.data` has been created. **Do not delete this**, this contains all your spotify data. [ Only applicable if save in file is set to yes. ] + +## SoundCloud + +## Getting Free Client ID + +``` ts +const play = require('play-dl') + +play.getFreeClientID().then((clientID) => { + play.setToken({ + soundcloud : { + client_id : clientID + } + }) +}) +``` \ No newline at end of file diff --git a/play-dl/index.ts b/play-dl/index.ts index cafc997..ff44b7f 100644 --- a/play-dl/index.ts +++ b/play-dl/index.ts @@ -326,7 +326,7 @@ export async function validate( * Either stores info in `.data` folder or shows relevant data to be used in `setToken` function. * * ```ts - * const play = require('play-dl) + * const play = require('play-dl') * * play.authorization() * ``` From 45c8b80b5a0a6c69e44e1b9d8a97d4550ce6f85e Mon Sep 17 00:00:00 2001 From: killer069 <65385476+killer069@users.noreply.github.com> Date: Tue, 23 Nov 2021 11:24:06 +0530 Subject: [PATCH 7/7] easy.js has been added as a function --- examples/SoundCloud/easy.js | 56 ------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 examples/SoundCloud/easy.js diff --git a/examples/SoundCloud/easy.js b/examples/SoundCloud/easy.js deleted file mode 100644 index 98efedb..0000000 --- a/examples/SoundCloud/easy.js +++ /dev/null @@ -1,56 +0,0 @@ -const https = require('https') -const play = require('play-dl'); - -(async() => { - let data = await request('https://soundcloud.com/') - let splitted = data.split('