Compare commits

...

11 Commits

Author SHA1 Message Date
Yuzu
45fefec624
Update package.json 2024-06-19 11:44:41 +07:00
Yuzu
60d5ea6700
Update package.json 2024-06-19 11:44:01 +07:00
Yuzu
2bfbfe6dec 🐛 fix: Temporary patched to iOS client 2024-06-18 15:19:56 +07:00
AtariTom
6a8569feb8 Fixed find chapter error, soundcloud 403 and watch playlists 2023-09-24 13:59:51 -04:00
AtariTom
76c237346e
Merge pull request #354 from karyeet/album-isrc-sto-patch
SimplifiedTrackObject from album does not have external_ids
2023-07-12 17:37:10 -04:00
Kareem
58f79fcacc
SimplifiedTrackObject from album does not have external_ids 2023-07-09 01:45:47 -07:00
AtariTom
1ae7ba8fce
Merge pull request #311 from KingRainbow44/main
Save the ISRC to `SpotifyTrack`
2022-10-31 20:05:31 -04:00
AtariTom
3147d98760 Type fix and workflow update 2022-10-30 18:30:26 -04:00
AtariTom
9661d8f17a npm security fix 2022-10-29 22:40:33 -04:00
AtariTom
fc6007b472 defaultIcon and music fix 2022-10-29 22:26:56 -04:00
KingRainbow44
5dc1eff4eb
Save the ISRC to SpotifyTrack 2022-07-17 12:07:40 -04:00
8 changed files with 89 additions and 68 deletions

View File

@ -2,7 +2,6 @@ name: Publish NPM package + Docs
on: on:
release: release:
types: [created] types: [created]
workflow_dispatch:
jobs: jobs:
publish_npm: publish_npm:
runs-on: ubuntu-latest runs-on: ubuntu-latest

28
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "play-dl", "name": "play-dl",
"version": "1.9.5", "version": "1.9.7",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "play-dl", "name": "play-dl",
"version": "1.9.5", "version": "1.9.7",
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"play-audio": "^0.5.2" "play-audio": "^0.5.2"
@ -971,9 +971,9 @@
} }
}, },
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "3.0.4", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
@ -1518,9 +1518,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "4.8.4", "version": "4.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
"dev": true, "dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
@ -2204,9 +2204,9 @@
"dev": true "dev": true
}, },
"minimatch": { "minimatch": {
"version": "3.0.4", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true, "dev": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
@ -2572,9 +2572,9 @@
"requires": {} "requires": {}
}, },
"typescript": { "typescript": {
"version": "4.8.4", "version": "4.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
"dev": true "dev": true
}, },
"vscode-oniguruma": { "vscode-oniguruma": {

View File

@ -1,6 +1,6 @@
{ {
"name": "play-dl", "name": "play-dl",
"version": "1.9.5", "version": "1.9.7",
"description": "YouTube, SoundCloud, Spotify, Deezer searching and streaming for discord-js bots", "description": "YouTube, SoundCloud, Spotify, Deezer searching and streaming for discord-js bots",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
@ -39,7 +39,8 @@
}, },
"homepage": "https://github.com/play-dl/play-dl#readme", "homepage": "https://github.com/play-dl/play-dl#readme",
"files": [ "files": [
"dist/*" "dist/*",
"play-dl/*"
], ],
"devDependencies": { "devDependencies": {
"@types/node": "^18.7.23", "@types/node": "^18.7.23",

View File

@ -111,10 +111,14 @@ export async function stream(url: string, quality?: number): Promise<SoundCloudS
* @returns client ID * @returns client ID
*/ */
export async function getFreeClientID(): Promise<string> { export async function getFreeClientID(): Promise<string> {
const data = await request('https://soundcloud.com/'); const data: any = await request('https://soundcloud.com/', {headers: {}}).catch(err => err);
if (data instanceof Error)
throw new Error("Failed to get response from soundcloud.com: " + data.message);
const splitted = data.split('<script crossorigin src="'); const splitted = data.split('<script crossorigin src="');
const urls: string[] = []; const urls: string[] = [];
splitted.forEach((r) => { splitted.forEach((r: string) => {
if (r.startsWith('https')) { if (r.startsWith('https')) {
urls.push(r.split('"')[0]); urls.push(r.split('"')[0]);
} }

View File

@ -85,6 +85,10 @@ export class SpotifyTrack {
* Spotify Track ID * Spotify Track ID
*/ */
id: string; id: string;
/**
* Spotify Track ISRC
*/
isrc: string;
/** /**
* Spotify Track url * Spotify Track url
*/ */
@ -124,6 +128,7 @@ export class SpotifyTrack {
constructor(data: any) { constructor(data: any) {
this.name = data.name; this.name = data.name;
this.id = data.id; this.id = data.id;
this.isrc = data.external_ids?.isrc || '';
this.type = 'track'; this.type = 'track';
this.url = data.external_urls.spotify; this.url = data.external_urls.spotify;
this.explicit = data.explicit; this.explicit = data.explicit;

View File

@ -24,7 +24,7 @@ export interface SpotifyDataOptions {
file?: boolean; file?: boolean;
} }
const pattern = /^((https:)?\/\/)?open.spotify.com\/(track|album|playlist)\//; const pattern = /^((https:)?\/\/)?open\.spotify\.com\/(?:intl\-.{2}\/)?(track|album|playlist)\//;
/** /**
* Gets Spotify url details. * Gets Spotify url details.
* *
@ -55,7 +55,9 @@ export async function spotify(url: string): Promise<Spotify> {
return err; return err;
}); });
if (response instanceof Error) throw response; if (response instanceof Error) throw response;
return new SpotifyTrack(JSON.parse(response)); const resObj = JSON.parse(response);
if (resObj.error) throw new Error(`Got ${resObj.error.status} from the spotify request: ${resObj.error.message}`);
return new SpotifyTrack(resObj);
} else if (url_.indexOf('album/') !== -1) { } else if (url_.indexOf('album/') !== -1) {
const albumID = url.split('album/')[1].split('&')[0].split('?')[0]; const albumID = url.split('album/')[1].split('&')[0].split('?')[0];
const response = await request(`https://api.spotify.com/v1/albums/${albumID}?market=${spotifyData.market}`, { const response = await request(`https://api.spotify.com/v1/albums/${albumID}?market=${spotifyData.market}`, {
@ -66,7 +68,9 @@ export async function spotify(url: string): Promise<Spotify> {
return err; return err;
}); });
if (response instanceof Error) throw response; if (response instanceof Error) throw response;
return new SpotifyAlbum(JSON.parse(response), spotifyData, false); const resObj = JSON.parse(response);
if (resObj.error) throw new Error(`Got ${resObj.error.status} from the spotify request: ${resObj.error.message}`);
return new SpotifyAlbum(resObj, spotifyData, false);
} else if (url_.indexOf('playlist/') !== -1) { } else if (url_.indexOf('playlist/') !== -1) {
const playlistID = url.split('playlist/')[1].split('&')[0].split('?')[0]; const playlistID = url.split('playlist/')[1].split('&')[0].split('?')[0];
const response = await request( const response = await request(
@ -80,7 +84,9 @@ export async function spotify(url: string): Promise<Spotify> {
return err; return err;
}); });
if (response instanceof Error) throw response; if (response instanceof Error) throw response;
return new SpotifyPlaylist(JSON.parse(response), spotifyData, false); const resObj = JSON.parse(response);
if (resObj.error) throw new Error(`Got ${resObj.error.status} from the spotify request: ${resObj.error.message}`);
return new SpotifyPlaylist(resObj, spotifyData, false);
} else throw new Error('URL is out of scope for play-dl.'); } else throw new Error('URL is out of scope for play-dl.');
} }
/** /**

View File

@ -7,16 +7,12 @@ import { YouTubeThumbnail } from './Thumbnail';
* The property names change depending on your region's language. * The property names change depending on your region's language.
*/ */
interface VideoMusic { interface VideoMusic {
song?: string | MusicEntry; song?: string;
artist?: string | MusicEntry; url?: string | null;
artist?: string;
album?: string; album?: string;
writers?: string; writers?: string;
license?: string; licenses?: string;
}
interface MusicEntry {
text?: string;
url?: string;
} }
interface VideoOptions { interface VideoOptions {

View File

@ -20,7 +20,7 @@ const video_id_pattern = /^[a-zA-Z\d_-]{11,12}$/;
const playlist_id_pattern = /^(PL|UU|LL|RD|OL)[a-zA-Z\d_-]{10,}$/; const playlist_id_pattern = /^(PL|UU|LL|RD|OL)[a-zA-Z\d_-]{10,}$/;
const DEFAULT_API_KEY = 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8'; const DEFAULT_API_KEY = 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8';
const video_pattern = const video_pattern =
/^((?:https?:)?\/\/)?(?:(?:www|m|music)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|shorts\/|embed\/|v\/)?)([\w\-]+)(\S+)?$/; /^((?:https?:)?\/\/)?(?:(?:www|m|music)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|shorts\/|embed\/|live\/|v\/)?)([\w\-]+)(\S+)?$/;
const playlist_pattern = const playlist_pattern =
/^((?:https?:)?\/\/)?(?:(?:www|m|music)\.)?((?:youtube\.com|youtu.be))\/(?:(playlist|watch))?(.*)?((\?|\&)list=)(PL|UU|LL|RD|OL)[a-zA-Z\d_-]{10,}(&.*)?$/; /^((?:https?:)?\/\/)?(?:(?:www|m|music)\.)?((?:youtube\.com|youtu.be))\/(?:(playlist|watch))?(.*)?((\?|\&)list=)(PL|UU|LL|RD|OL)[a-zA-Z\d_-]{10,}(&.*)?$/;
/** /**
@ -81,6 +81,8 @@ function extractVideoId(urlOrId: string): string | false {
id = urlOrId.split('youtube.com/embed/')[1].split(/(\?|\/|&)/)[0]; id = urlOrId.split('youtube.com/embed/')[1].split(/(\?|\/|&)/)[0];
} else if (urlOrId.includes('youtube.com/shorts/')) { } else if (urlOrId.includes('youtube.com/shorts/')) {
id = urlOrId.split('youtube.com/shorts/')[1].split(/(\?|\/|&)/)[0]; id = urlOrId.split('youtube.com/shorts/')[1].split(/(\?|\/|&)/)[0];
} else if (urlOrId.includes('youtube.com/live/')) {
id = urlOrId.split('youtube.com/live/')[1].split(/(\?|\/|&)/)[0];
} else { } else {
id = (urlOrId.split('watch?v=')[1] ?? urlOrId.split('&v=')[1]).split(/(\?|\/|&)/)[0]; id = (urlOrId.split('watch?v=')[1] ?? urlOrId.split('&v=')[1]).split(/(\?|\/|&)/)[0];
} }
@ -212,28 +214,26 @@ export async function video_basic_info(url: string, options: InfoOptions = {}):
} }
); );
const microformat = player_response.microformat.playerMicroformatRenderer; const microformat = player_response.microformat.playerMicroformatRenderer;
const musicInfo = const musicInfo = initial_response.engagementPanels.find((item: any) => item?.engagementPanelSectionListRenderer?.panelIdentifier == 'engagement-panel-structured-description')?.engagementPanelSectionListRenderer.content.structuredDescriptionContentRenderer.items
initial_response.contents.twoColumnWatchNextResults.results.results.contents?.[1]?.videoSecondaryInfoRenderer .find((el: any) => el.videoDescriptionMusicSectionRenderer)?.videoDescriptionMusicSectionRenderer.carouselLockups;
?.metadataRowContainer?.metadataRowContainerRenderer?.rows;
const music: any[] = []; const music: any[] = [];
if (musicInfo) { if (musicInfo) {
musicInfo.forEach((x: any) => { musicInfo.forEach((x: any) => {
if (!x.metadataRowRenderer) return; if (!x.carouselLockupRenderer) return;
const row = x.metadataRowRenderer; const row = x.carouselLockupRenderer;
const title = row.title.simpleText ?? row.title.runs[0].text; const song = row.videoLockup?.compactVideoRenderer.title.simpleText ?? row.videoLockup?.compactVideoRenderer.title.runs?.find((x:any) => x.text)?.text;
const contents = row.contents[0].simpleText ?? row.contents[0]?.runs?.[0]?.text; const metadata = row.infoRows?.map((info: any) => [info.infoRowRenderer.title.simpleText.toLowerCase(), ((info.infoRowRenderer.expandedMetadata ?? info.infoRowRenderer.defaultMetadata)?.runs?.map((i:any) => i.text).join("")) ?? info.infoRowRenderer.defaultMetadata?.simpleText ?? info.infoRowRenderer.expandedMetadata?.simpleText ?? ""]);
const url = row.contents[0]?.runs?.[0]?.navigationEndpoint?.commandMetadata?.webCommandMetadata.url; const contents = Object.fromEntries(metadata ?? {});
const id = row.videoLockup?.compactVideoRenderer.navigationEndpoint?.watchEndpoint.videoId
?? row.infoRows?.find((x: any) => x.infoRowRenderer.title.simpleText.toLowerCase() == "song")?.infoRowRenderer.defaultMetadata.runs?.find((x: any) => x.navigationEndpoint)?.navigationEndpoint.watchEndpoint?.videoId;
if (music.length === 0) music.push({}); music.push({song, url: id ? `https://www.youtube.com/watch?v=${id}` : null, ...contents})
music[music.length - 1][title.toLowerCase()] = url ? {text: contents, url: `https://www.youtube.com${url}`} : contents;
if (row.hasDividerLine) music.push({});
}); });
} }
const rawChapters = const rawChapters =
initial_response.playerOverlays.playerOverlayRenderer.decoratedPlayerBarRenderer?.decoratedPlayerBarRenderer.playerBar?.multiMarkersPlayerBarRenderer.markersMap.find( initial_response.playerOverlays.playerOverlayRenderer.decoratedPlayerBarRenderer?.decoratedPlayerBarRenderer.playerBar?.multiMarkersPlayerBarRenderer.markersMap?.find(
(m: any) => m.key === 'DESCRIPTION_CHAPTERS' (m: any) => m.key === 'DESCRIPTION_CHAPTERS'
)?.value?.chapters; )?.value?.chapters;
const chapters: VideoChapter[] = []; const chapters: VideoChapter[] = [];
@ -258,6 +258,13 @@ export async function video_basic_info(url: string, options: InfoOptions = {}):
upcomingDate = new Date(parseInt(timestamp) * 1000); upcomingDate = new Date(parseInt(timestamp) * 1000);
} }
} }
const likeRenderer = initial_response.contents.twoColumnWatchNextResults.results.results.contents
.find((content: any) => content.videoPrimaryInfoRenderer)
?.videoPrimaryInfoRenderer.videoActions.menuRenderer.topLevelButtons?.find(
(button: any) => button.toggleButtonRenderer?.defaultIcon.iconType === 'LIKE' || button.segmentedLikeDislikeButtonRenderer?.likeButton.toggleButtonRenderer?.defaultIcon.iconType === 'LIKE'
)
const video_details = new YouTubeVideo({ const video_details = new YouTubeVideo({
id: vid.videoId, id: vid.videoId,
title: vid.title, title: vid.title,
@ -279,12 +286,8 @@ export async function video_basic_info(url: string, options: InfoOptions = {}):
views: vid.viewCount, views: vid.viewCount,
tags: vid.keywords, tags: vid.keywords,
likes: parseInt( likes: parseInt(
initial_response.contents.twoColumnWatchNextResults.results.results.contents likeRenderer?.toggleButtonRenderer?.defaultText.accessibility?.accessibilityData.label.replace(/\D+/g, '') ??
.find((content: any) => content.videoPrimaryInfoRenderer) likeRenderer?.segmentedLikeDislikeButtonRenderer?.likeButton.toggleButtonRenderer?.defaultText.accessibility?.accessibilityData.label.replace(/\D+/g, '') ?? 0
?.videoPrimaryInfoRenderer.videoActions.menuRenderer.topLevelButtons?.find(
(button: any) => button.toggleButtonRenderer.defaultIcon.iconType === 'LIKE'
)
?.toggleButtonRenderer.defaultText.accessibility?.accessibilityData.label.replace(/\D+/g, '') ?? 0
), ),
live: vid.isLiveContent, live: vid.isLiveContent,
private: vid.isPrivate, private: vid.isPrivate,
@ -294,15 +297,17 @@ export async function video_basic_info(url: string, options: InfoOptions = {}):
}); });
let format = []; let format = [];
if (!upcoming) { if (!upcoming) {
format.push(...(player_response.streamingData.formats ?? [])); // TODO: Properly handle the formats, for now ignore and use iOS formats
format.push(...(player_response.streamingData.adaptiveFormats ?? [])); //format.push(...(player_response.streamingData.formats ?? []));
//format.push(...(player_response.streamingData.adaptiveFormats ?? []));
// get the formats for the android player for legacy videos // get the formats for the android player for legacy videos
// fixes the stream being closed because not enough data // fixes the stream being closed because not enough data
// arrived in time for ffmpeg to be able to extract audio data // arrived in time for ffmpeg to be able to extract audio data
if (parseAudioFormats(format).length === 0 && !options.htmldata) { //if (parseAudioFormats(format).length === 0 && !options.htmldata) {
format = await getAndroidFormats(vid.videoId, cookieJar, body); // format = await getAndroidFormats(vid.videoId, cookieJar, body);
} //}
format = await getIosFormats(vid.videoId, cookieJar, body);
} }
const LiveStreamData = { const LiveStreamData = {
isLive: video_details.live, isLive: video_details.live,
@ -401,15 +406,17 @@ export async function video_stream_info(url: string, options: InfoOptions = {}):
}; };
let format = []; let format = [];
if (!upcoming) { if (!upcoming) {
format.push(...(player_response.streamingData.formats ?? [])); // TODO: Properly handle the formats, for now ignore and use iOS formats
format.push(...(player_response.streamingData.adaptiveFormats ?? [])); //format.push(...(player_response.streamingData.formats ?? []));
//format.push(...(player_response.streamingData.adaptiveFormats ?? []));
// get the formats for the android player for legacy videos // get the formats for the android player for legacy videos
// fixes the stream being closed because not enough data // fixes the stream being closed because not enough data
// arrived in time for ffmpeg to be able to extract audio data // arrived in time for ffmpeg to be able to extract audio data
if (parseAudioFormats(format).length === 0 && !options.htmldata) { //if (parseAudioFormats(format).length === 0 && !options.htmldata) {
format = await getAndroidFormats(player_response.videoDetails.videoId, cookieJar, body); // format = await getAndroidFormats(player_response.videoDetails.videoId, cookieJar, body);
} //}
format = await getIosFormats(player_response.videoDetails.videoId, cookieJar, body);
} }
const LiveStreamData = { const LiveStreamData = {
@ -541,7 +548,7 @@ export async function playlist_info(url: string, options: PlaylistOptions = {}):
throw new Error(`While parsing playlist url\n${response.alerts[0].alertRenderer.text.runs[0].text}`); throw new Error(`While parsing playlist url\n${response.alerts[0].alertRenderer.text.runs[0].text}`);
else throw new Error('While parsing playlist url\nUnknown Playlist Error'); else throw new Error('While parsing playlist url\nUnknown Playlist Error');
} }
if (url_.indexOf('watch?v=') !== -1) { if (response.currentVideoEndpoint) {
return getWatchPlaylist(response, body, url_); return getWatchPlaylist(response, body, url_);
} else return getNormalPlaylist(response, body); } else return getNormalPlaylist(response, body);
} }
@ -628,7 +635,7 @@ async function acceptViewerDiscretion(
}, },
nextEndpoint: { nextEndpoint: {
urlEndpoint: { urlEndpoint: {
url: `watch?v=${videoId}` url: `/watch?v=${videoId}&has_verified=1`
} }
}, },
setControvercy: true setControvercy: true
@ -677,7 +684,7 @@ async function acceptViewerDiscretion(
return { streamingData }; return { streamingData };
} }
async function getAndroidFormats(videoId: string, cookieJar: { [key: string]: string }, body: string): Promise<any[]> { async function getIosFormats(videoId: string, cookieJar: { [key: string]: string }, body: string): Promise<any[]> {
const apiKey = const apiKey =
body.split('INNERTUBE_API_KEY":"')[1]?.split('"')[0] ?? body.split('INNERTUBE_API_KEY":"')[1]?.split('"')[0] ??
body.split('innertubeApiKey":"')[1]?.split('"')[0] ?? body.split('innertubeApiKey":"')[1]?.split('"')[0] ??
@ -688,8 +695,10 @@ async function getAndroidFormats(videoId: string, cookieJar: { [key: string]: st
body: JSON.stringify({ body: JSON.stringify({
context: { context: {
client: { client: {
clientName: 'ANDROID', clientName: 'IOS',
clientVersion: '16.49', clientVersion: '19.09.3',
deviceModel: 'iPhone16,1',
userAgent: 'com.google.ios.youtube/19.09.3 (iPhone; CPU iPhone OS 17_5 like Mac OS X)',
hl: 'en', hl: 'en',
timeZone: 'UTC', timeZone: 'UTC',
utcOffsetMinutes: 0 utcOffsetMinutes: 0
@ -704,7 +713,8 @@ async function getAndroidFormats(videoId: string, cookieJar: { [key: string]: st
cookieJar cookieJar
}); });
return JSON.parse(response).streamingData.formats; return JSON.parse(response).streamingData.adaptiveFormats;
//return JSON.parse(response).streamingData.formats;
} }
function getWatchPlaylist(response: any, body: any, url: string): YouTubePlayList { function getWatchPlaylist(response: any, body: any, url: string): YouTubePlayList {