pretty code

This commit is contained in:
killer069
2021-11-23 09:56:08 +05:30
parent 6fe9372989
commit 32b9fdbf65
19 changed files with 601 additions and 515 deletions

View File

@@ -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;
}
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;
}

View File

@@ -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() {

View File

@@ -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<YouTubePlayList> {
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[]
}
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[];
}

View File

@@ -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
};
}
}
}

View File

@@ -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

View File

@@ -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';

View File

@@ -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<formatData>[]
video_details : YouTubeVideo
related_videos: string[]
}
export interface InfoData {
LiveStreamData: LiveStreamData;
html5player: string;
format: Partial<formatData>[];
video_details: YouTubeVideo;
related_videos: string[];
}

View File

@@ -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();
}

View File

@@ -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<InfoData> {
export async function video_basic_info(url: string, options: InfoOptions = {}): Promise<InfoData> {
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,

View File

@@ -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'))
},