More Docs Added

This commit is contained in:
killer069 2021-11-19 13:49:21 +05:30
parent b5e0097b70
commit c0d3dc68bf
9 changed files with 215 additions and 31 deletions

View File

@ -255,3 +255,5 @@ export async function dz_advanced_track_search(options: DeezerAdvancedSearchOpti
return results; return results;
} }
export { DeezerTrack, DeezerAlbum, DeezerPlaylist }

View File

@ -3,7 +3,7 @@ import { Readable } from 'node:stream';
import { IncomingMessage } from 'node:http'; import { IncomingMessage } from 'node:http';
import { StreamType } from '../YouTube/stream'; import { StreamType } from '../YouTube/stream';
import { Timer } from '../YouTube/classes/LiveStream'; import { Timer } from '../YouTube/classes/LiveStream';
import { SoundTrackJSON } from './constants'; import { PlaylistJSON, SoundTrackJSON } from './constants';
export interface SoundCloudUser { export interface SoundCloudUser {
/** /**
@ -178,7 +178,10 @@ export class SoundCloudTrack {
}; };
this.thumbnail = data.artwork_url; this.thumbnail = data.artwork_url;
} }
/**
* Converts class to JSON
* @returns JSON parsed Data
*/
toJSON() : SoundTrackJSON { toJSON() : SoundTrackJSON {
return { return {
name: this.name, name: this.name,
@ -198,17 +201,56 @@ export class SoundCloudTrack {
* SoundCloud Playlist Class * SoundCloud Playlist Class
*/ */
export class SoundCloudPlaylist { export class SoundCloudPlaylist {
/**
* SoundCloud Playlist Name
*/
name: string; name: string;
/**
* SoundCloud Playlist ID
*/
id: number; id: number;
/**
* SoundCloud Playlist URL
*/
url: string; url: string;
/**
* SoundCloud Class type. == "playlist"
*/
type: 'track' | 'playlist' | 'user'; type: 'track' | 'playlist' | 'user';
/**
* SoundCloud Playlist Sub type. == "album" for soundcloud albums
*/
sub_type: string; sub_type: string;
/**
* SoundCloud Playlist Total Duration in seconds
*/
durationInSec: number; durationInSec: number;
/**
* SoundCloud Playlist Total Duration in milli seconds
*/
durationInMs: number; durationInMs: number;
client_id: string; /**
* SoundCloud Playlist user data
*/
user: SoundCloudUser; user: SoundCloudUser;
/**
* SoundCloud Playlist tracks [ It can be fetched or not fetched ]
*/
tracks: SoundCloudTrack[] | SoundCloudTrackDeprecated[]; tracks: SoundCloudTrack[] | SoundCloudTrackDeprecated[];
/**
* SoundCloud Playlist tracks number
*/
tracksCount: number; tracksCount: number;
/**
* SoundCloud Client ID provided by user
* @private
*/
private client_id: string;
/**
* Constructor for SoundCloud Playlist
* @param data JSON parsed SoundCloud playlist data
* @param client_id Provided SoundCloud Client ID
*/
constructor(data: any, client_id: string) { constructor(data: any, client_id: string) {
this.name = data.title; this.name = data.title;
this.id = data.id; this.id = data.id;
@ -244,8 +286,13 @@ export class SoundCloudPlaylist {
}); });
this.tracks = tracks; this.tracks = tracks;
} }
/**
async fetch(): Promise<void> { * Fetches all unfetched songs in a playlist.
*
* For fetching songs and getting all songs, see `fetched_tracks` property.
* @returns playlist class
*/
async fetch(): Promise<SoundCloudPlaylist> {
const work: any[] = []; const work: any[] = [];
for (let i = 0; i < this.tracks.length; i++) { for (let i = 0; i < this.tracks.length; i++) {
if (!this.tracks[i].fetched) { if (!this.tracks[i].fetched) {
@ -263,9 +310,12 @@ export class SoundCloudPlaylist {
} }
} }
await Promise.allSettled(work); await Promise.allSettled(work);
return this;
} }
/**
get total_tracks() { * Get total no. of fetched tracks
*/
get total_tracks(): number {
let count = 0; let count = 0;
this.tracks.forEach((track) => { this.tracks.forEach((track) => {
if (track instanceof SoundCloudTrack) count++; if (track instanceof SoundCloudTrack) count++;
@ -273,12 +323,35 @@ export class SoundCloudPlaylist {
}); });
return count; return count;
} }
/**
toJSON() { * 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
* ```
*/
get fetched_tracks(): SoundCloudTrack[] {
let result: SoundCloudTrack[] = [];
this.tracks.forEach((track) => {
if (track instanceof SoundCloudTrack) result.push(track);
else return;
});
return result;
}
/**
* Converts Class to JSON data
* @returns JSON parsed data
*/
toJSON(): PlaylistJSON {
return { return {
name: this.name, name: this.name,
id: this.id, id: this.id,
type: this.type,
sub_type: this.sub_type, sub_type: this.sub_type,
url: this.url, url: this.url,
durationInMs: this.durationInMs, durationInMs: this.durationInMs,
@ -293,17 +366,57 @@ export class SoundCloudPlaylist {
* SoundCloud Stream class * SoundCloud Stream class
*/ */
export class SoundCloudStream { export class SoundCloudStream {
/**
* Readable Stream through which data passes
*/
stream: Readable; stream: Readable;
/**
* Type of audio data that we recieved from normal youtube url.
*/
type: StreamType; type: StreamType;
/**
* Dash Url containing segment urls.
* @private
*/
private url: string; private url: string;
/**
* Total time of downloaded segments data.
* @private
*/
private downloaded_time: number; private downloaded_time: number;
/**
* Timer for looping code every 5 minutes
* @private
*/
private timer: Timer; private timer: Timer;
/**
* Total segments Downloaded so far
* @private
*/
private downloaded_segments: number; 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
*/
private request: IncomingMessage | null; private request: IncomingMessage | null;
/**
* Array of segment time. Useful for calculating downloaded_time.
*/
private time: number[]; private time: number[];
/**
* Array of segment_urls in dash file.
*/
private segment_urls: string[]; private segment_urls: string[];
/**
* Constructor for SoundCloud Stream
* @param url Dash url containing dash file.
* @param type Stream Type
*/
constructor(url: string, type: StreamType = StreamType.Arbitrary) { constructor(url: string, type: StreamType = StreamType.Arbitrary) {
this.stream = new Readable({ highWaterMark: 10 * 1000 * 1000, read() {} }); this.stream = new Readable({ highWaterMark: 5 * 1000 * 1000, read() {} });
this.type = type; this.type = type;
this.url = url; this.url = url;
this.downloaded_time = 0; this.downloaded_time = 0;
@ -320,7 +433,10 @@ export class SoundCloudStream {
}); });
this.start(); this.start();
} }
/**
* Parses SoundCloud dash file.
* @private
*/
private async parser() { private async parser() {
const response = await request(this.url).catch((err: Error) => { const response = await request(this.url).catch((err: Error) => {
return err; return err;
@ -336,7 +452,9 @@ export class SoundCloudStream {
}); });
return; return;
} }
/**
* Starts looping of code for getting all segments urls data
*/
private async start() { private async start() {
if (this.stream.destroyed) { if (this.stream.destroyed) {
this.cleanup(); this.cleanup();
@ -344,12 +462,14 @@ export class SoundCloudStream {
} }
this.time = []; this.time = [];
this.segment_urls = []; this.segment_urls = [];
await this.parser();
this.downloaded_time = 0; this.downloaded_time = 0;
await this.parser();
this.segment_urls.splice(0, this.downloaded_segments); this.segment_urls.splice(0, this.downloaded_segments);
this.loop(); this.loop();
} }
/**
* Main Loop function for getting all segments urls data
*/
private async loop() { private async loop() {
if (this.stream.destroyed) { if (this.stream.destroyed) {
this.cleanup(); this.cleanup();
@ -381,7 +501,11 @@ export class SoundCloudStream {
this.stream.emit('error', err); this.stream.emit('error', err);
}); });
} }
/**
* 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() { private cleanup() {
this.timer.destroy(); this.timer.destroy();
this.request?.destroy(); this.request?.destroy();
@ -392,11 +516,19 @@ export class SoundCloudStream {
this.time = []; this.time = [];
this.segment_urls = []; this.segment_urls = [];
} }
/**
* Pauses timer.
* Stops running of loop.
*
* Useful if you don't want to get excess data to be stored in stream.
*/
pause() { pause() {
this.timer.pause(); this.timer.pause();
} }
/**
* Resumes timer.
* Starts running of loop.
*/
resume() { resume() {
this.timer.resume(); this.timer.resume();
} }

View File

@ -1,4 +1,4 @@
import { SoundCloudTrackFormat, SoundCloudUser } from "./classes"; import { SoundCloudTrack, SoundCloudTrackDeprecated, SoundCloudTrackFormat, SoundCloudUser } from "./classes";
export interface SoundTrackJSON{ export interface SoundTrackJSON{
/** /**
@ -47,8 +47,47 @@ export interface SoundTrackJSON{
* SoundCloud Track user data * SoundCloud Track user data
*/ */
user: SoundCloudUser; user: SoundCloudUser;
}
export interface PlaylistJSON{
/** /**
* Constructor for SoundCloud Track Class * SoundCloud Playlist Name
* @param data JSON parsed track html data */
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
*/ */
} }

View File

@ -2,7 +2,6 @@ import fs from 'node:fs';
import { StreamType } from '../YouTube/stream'; import { StreamType } from '../YouTube/stream';
import { request } from '../Request'; import { request } from '../Request';
import { SoundCloudPlaylist, SoundCloudTrack, SoundCloudTrackFormat, SoundCloudStream } from './classes'; import { SoundCloudPlaylist, SoundCloudTrack, SoundCloudTrackFormat, SoundCloudStream } from './classes';
export { SoundCloudStream }
let soundData: SoundDataOptions; let soundData: SoundDataOptions;
if (fs.existsSync('.data/soundcloud.data')) { if (fs.existsSync('.data/soundcloud.data')) {
soundData = JSON.parse(fs.readFileSync('.data/soundcloud.data').toString()); soundData = JSON.parse(fs.readFileSync('.data/soundcloud.data').toString());
@ -167,3 +166,5 @@ function parseHlsFormats(data: SoundCloudTrackFormat[]) {
export function setSoundCloudToken(options: SoundDataOptions) { export function setSoundCloudToken(options: SoundDataOptions) {
soundData = options; soundData = options;
} }
export { SoundCloudTrack, SoundCloudPlaylist, SoundCloudStream }

View File

@ -214,3 +214,5 @@ export function setSpotifyToken(options: SpotifyDataOptions) {
spotifyData.file = false; spotifyData.file = false;
refreshToken(); refreshToken();
} }
export { SpotifyTrack, SpotifyAlbum, SpotifyPlaylist }

View File

@ -71,7 +71,7 @@ export class LiveStream {
* @param video_url Live Stream video url. * @param video_url Live Stream video url.
*/ */
constructor(dash_url: string, target_interval: number, video_url: string) { constructor(dash_url: string, target_interval: number, video_url: string) {
this.stream = new Readable({ highWaterMark: 10 * 1000 * 1000, read() {} }); this.stream = new Readable({ highWaterMark: 5 * 1000 * 1000, read() {} });
this.type = StreamType.Arbitrary; this.type = StreamType.Arbitrary;
this.url = dash_url; this.url = dash_url;
this.base_url = ''; this.base_url = '';
@ -258,7 +258,7 @@ export class Stream {
video_url: string, video_url: string,
options: StreamOptions options: StreamOptions
) { ) {
this.stream = new Readable({ highWaterMark: 10 * 1000 * 1000, read() {} }); this.stream = new Readable({ highWaterMark: 5 * 1000 * 1000, read() {} });
this.url = url; this.url = url;
this.quality = options.quality as number; this.quality = options.quality as number;
this.proxy = options.proxy || undefined; this.proxy = options.proxy || undefined;

View File

@ -157,6 +157,8 @@ export class YouTubePlayList {
} }
/** /**
* Fetches remaining data from playlist * Fetches remaining data from playlist
*
* For fetching and getting all songs data, see `total_pages` property.
* @param max Max no of videos to fetch * @param max Max no of videos to fetch
* *
* Default = Infinity * Default = Infinity
@ -183,7 +185,7 @@ export class YouTubePlayList {
* For example, if you want to get 101 - 200 songs * For example, if you want to get 101 - 200 songs
* *
* ```ts * ```ts
* const playlist = play.playlist_info('playlist url') * const playlist = await play.playlist_info('playlist url')
* *
* await playlist.fetch() * await playlist.fetch()
* *
@ -203,13 +205,13 @@ export class YouTubePlayList {
* For getting all songs in a playlist * For getting all songs in a playlist
* *
* ```ts * ```ts
* const playlist = play.playlist_info('playlist url'); * const playlist = await play.playlist_info('playlist url');
* *
* await playlist.fetch(); * await playlist.fetch();
* *
* let result = []; * let result = [];
* *
* for (let i = 0; i <= playlist.total_pages;i++) { * for (let i = 0; i <= playlist.total_pages; i++) {
* result.push(playlist.page(i)); * result.push(playlist.page(i));
* } * }
* ``` * ```

View File

@ -2,3 +2,6 @@ export { stream, stream_from_info, YouTubeStream } from './stream';
export * from './utils'; export * from './utils';
export { YouTube } from './search'; export { YouTube } from './search';
export { cookieHeaders } from './utils/cookie'; export { cookieHeaders } from './utils/cookie';
export { YouTubeVideo } from './classes/Video'
export { YouTubePlayList } from './classes/Playlist'
export { YouTubeChannel } from './classes/Channel'

View File

@ -7,11 +7,14 @@ export {
extractID, extractID,
YouTube, YouTube,
YouTubeStream, YouTubeStream,
cookieHeaders cookieHeaders,
YouTubeChannel,
YouTubePlayList,
YouTubeVideo
} from './YouTube'; } from './YouTube';
export { spotify, sp_validate, refreshToken, is_expired, Spotify } from './Spotify'; export { spotify, sp_validate, refreshToken, is_expired, SpotifyAlbum, SpotifyPlaylist, SpotifyTrack, Spotify } from './Spotify';
export { soundcloud, so_validate, SoundCloud, SoundCloudStream, getFreeClientID } from './SoundCloud'; export { soundcloud, so_validate, SoundCloud, SoundCloudStream, getFreeClientID, SoundCloudPlaylist, SoundCloudTrack } from './SoundCloud';
export { deezer, dz_validate, dz_advanced_track_search, Deezer } from './Deezer'; export { deezer, dz_validate, dz_advanced_track_search, Deezer, DeezerTrack, DeezerPlaylist, DeezerAlbum } from './Deezer';
export { setToken } from './token'; export { setToken } from './token';
enum AudioPlayerStatus { enum AudioPlayerStatus {