Some huge changes

This commit is contained in:
killer069
2021-11-18 15:38:25 +05:30
parent e53e892606
commit 81e6bc0092
58 changed files with 648 additions and 181 deletions

View File

@@ -104,7 +104,7 @@ export class LiveStream {
info.LiveStreamData.hlsManifestUrl !== null &&
info.video_details.durationInSec === 0
) {
this.url = info.LiveStreamData.dashManifestUrl;
this.url = info.LiveStreamData.dashManifestUrl as string;
}
}
/**

View File

@@ -2,6 +2,7 @@ import { getPlaylistVideos, getContinuationToken } from '../utils/extractor';
import { request } from '../../Request';
import { YouTubeChannel } from './Channel';
import { YouTubeVideo } from './Video';
import { YouTubeThumbnail } from './Thumbnail';
const BASE_API = 'https://www.youtube.com/youtubei/v1/browse?key=';
/**
* YouTube Playlist Class containing vital informations about playlist.
@@ -46,12 +47,7 @@ export class YouTubePlayList {
/**
* YouTube Playlist thumbnail Data
*/
thumbnail?: {
id: string | undefined;
width: number | undefined;
height: number | undefined;
url: string | undefined;
};
thumbnail?: YouTubeThumbnail
/**
* Videos array containing data of first 100 videos
*/
@@ -238,7 +234,7 @@ export class YouTubePlayList {
return {
id: this.id,
title: this.title,
thumbnail: this.thumbnail,
thumbnail: this.thumbnail?.toJSON() || this.thumbnail,
channel: this.channel,
url: this.url,
videos: this.videos

View File

@@ -0,0 +1,22 @@
export class YouTubeThumbnail {
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
}
toJSON(){
return {
id : this.id,
url : this.url,
width : this.width,
height : this.height
}
}
}

View File

@@ -1,56 +1,145 @@
import { YouTubeChannel } from './Channel';
import { YouTubeThumbnail } from './Thumbnail';
interface VideoOptions {
id?: string;
url?: string;
title?: string;
description?: string;
durationRaw: string;
durationInSec: number;
uploadedAt?: string;
views: number;
thumbnail?: {
/**
* 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 | undefined;
width: number | undefined;
height: number | undefined;
url: string | undefined;
};
channel?: any;
type: string;
ratings: {
likes: number;
dislikes: number;
};
live: boolean;
private: boolean;
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
*/
export class YouTubeVideo {
/**
* YouTube Video ID
*/
id?: string;
/**
* YouTube video url
*/
url: string;
/**
* YouTube Class type. == "video"
*/
type: 'video' | 'playlist' | 'channel';
/**
* 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;
thumbnail?: {
id: string | undefined;
width: number | undefined;
height: number | undefined;
url: string | undefined;
};
/**
* YouTube Thumbnail Data
*/
thumbnail?: YouTubeThumbnail;
/**
* 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[];
/**
* Constructor Class for YouTube Video
* @param data JSON parsed data.
*/
constructor(data: any) {
if (!data) throw new Error(`Can not initiate ${this.constructor.name} without data`);
@@ -71,12 +160,18 @@ export class YouTubeVideo {
this.private = !!data.private;
this.tags = data.tags || [];
}
get toString(): string {
/**
* Converts class to title name of video.
* @returns Title name
*/
toString(): string {
return this.url || '';
}
get toJSON(): VideoOptions {
/**
* Converts class to JSON data
* @returns JSON data.
*/
toJSON(): VideoOptions {
return {
id: this.id,
url: this.url,
@@ -85,15 +180,12 @@ export class YouTubeVideo {
durationInSec: this.durationInSec,
durationRaw: this.durationRaw,
uploadedAt: this.uploadedAt,
thumbnail: this.thumbnail,
thumbnail: this.thumbnail?.toJSON() || this.thumbnail,
channel: this.channel,
views: this.views,
type: this.type,
tags: this.tags,
ratings: {
likes: this.likes,
dislikes: this.dislikes
},
likes: this.likes,
dislikes: this.dislikes,
live: this.live,
private: this.private
};

View File

@@ -1,6 +1,7 @@
import { video_info } from '.';
import { LiveStream, Stream } from './classes/LiveStream';
import { ProxyOptions as Proxy } from './../Request';
import { InfoData } from './utils/constants';
export enum StreamType {
Arbitrary = 'arbitrary',
@@ -16,16 +17,6 @@ export interface StreamOptions {
htmldata?: boolean;
}
export interface InfoData {
LiveStreamData: {
isLive: boolean;
dashManifestUrl: string;
hlsManifestUrl: string;
};
html5player: string;
format: any[];
video_details: any;
}
/**
* Command to find audio formats from given format array
* @param formats Formats to search from
@@ -58,12 +49,12 @@ export async function stream(url: string, options: StreamOptions = {}): Promise<
const final: any[] = [];
if (
info.LiveStreamData.isLive === true &&
info.LiveStreamData.hlsManifestUrl !== null &&
info.LiveStreamData.dashManifestUrl !== null &&
info.video_details.durationInSec === 0
) {
return new LiveStream(
info.LiveStreamData.dashManifestUrl,
info.format[info.format.length - 1].targetDurationSec,
info.format[info.format.length - 1].targetDurationSec as number,
info.video_details.url
);
}
@@ -95,12 +86,12 @@ export async function stream_from_info(info: InfoData, options: StreamOptions =
const final: any[] = [];
if (
info.LiveStreamData.isLive === true &&
info.LiveStreamData.hlsManifestUrl !== null &&
info.LiveStreamData.dashManifestUrl !== null &&
info.video_details.durationInSec === 0
) {
return new LiveStream(
info.LiveStreamData.dashManifestUrl,
info.format[info.format.length - 1].targetDurationSec,
info.format[info.format.length - 1].targetDurationSec as number,
info.video_details.url
);
}

View File

@@ -0,0 +1,39 @@
import { YouTubeVideo } from "../classes/Video";
export interface LiveStreamData {
isLive: boolean;
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;
}
export interface InfoData{
LiveStreamData : LiveStreamData
html5player : string
format : Partial<formatData>[]
video_details : YouTubeVideo
related_videos: string[]
}

View File

@@ -2,7 +2,7 @@ import { ProxyOptions as Proxy, request } from './../../Request/index';
import { format_decipher } from './cipher';
import { YouTubeVideo } from '../classes/Video';
import { YouTubePlayList } from '../classes/Playlist';
import { InfoData } from '../stream';
import { InfoData } from './constants';
interface InfoOptions {
proxy?: Proxy[];
@@ -79,7 +79,7 @@ export function extractID(url: string): string {
* @param options cookie and proxy parameters to add
* @returns Data containing video_details, LiveStreamData and formats of video url.
*/
export async function video_basic_info(url: string, options: InfoOptions = {}) {
export async function video_basic_info(url: string, options: InfoOptions = {}) : Promise<InfoData> {
let body: string;
if (options.htmldata) {
body = url;
@@ -187,7 +187,7 @@ function parseSeconds(seconds: number): string {
* @param options cookie and proxy parameters to add
* @returns Data containing video_details, LiveStreamData and formats of video url.
*/
export async function video_info(url: string, options: InfoOptions = {}) {
export async function video_info(url: string, options: InfoOptions = {}): Promise<InfoData> {
const data = await video_basic_info(url, options);
if (data.LiveStreamData.isLive === true && data.LiveStreamData.hlsManifestUrl !== null) {
return data;