Merge branch 'developer' of https://github.com/play-dl/play-dl into developer
This commit is contained in:
commit
e9ccfb219d
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "play-dl",
|
"name": "play-dl",
|
||||||
"version": "1.6.4",
|
"version": "1.6.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",
|
||||||
|
|||||||
@ -92,7 +92,7 @@ async function internalValidate(url: string): Promise<TypeData> {
|
|||||||
return { type: false };
|
return { type: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((path[1] === 'track' || path[1] === 'album' || path[1] === 'playlist') && path[2].match(/^[0-9]+$/)) {
|
if ((path[1] === 'track' || path[1] === 'album' || path[1] === 'playlist') && path[2].match(/^\d+$/)) {
|
||||||
return {
|
return {
|
||||||
type: path[1],
|
type: path[1],
|
||||||
id: path[2]
|
id: path[2]
|
||||||
@ -105,7 +105,7 @@ async function internalValidate(url: string): Promise<TypeData> {
|
|||||||
if (
|
if (
|
||||||
path.length === 3 &&
|
path.length === 3 &&
|
||||||
(path[1] === 'track' || path[1] === 'album' || path[1] === 'playlist') &&
|
(path[1] === 'track' || path[1] === 'album' || path[1] === 'playlist') &&
|
||||||
path[2].match(/^[0-9]+$/)
|
path[2].match(/^\d+$/)
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
type: path[1],
|
type: path[1],
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
const useragents: string[] = [
|
const useragents: string[] = [
|
||||||
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36 Edg/96.0.1054.43',
|
||||||
'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
|
'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
|
||||||
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
|
||||||
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
|
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
|
||||||
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
|
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
|
||||||
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0',
|
||||||
'Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36.0 (KHTML, like Gecko) Chrome/61.0.0.0 Safari/537.36.0',
|
'Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36.0 (KHTML, like Gecko) Chrome/61.0.0.0 Safari/537.36.0',
|
||||||
'Mozilla/5.0 (Windows; U; Windows NT 6.1) AppleWebKit/531.35.5 (KHTML, like Gecko) Version/4.0.3 Safari/531.35.5',
|
'Mozilla/5.0 (Windows; U; Windows NT 6.1) AppleWebKit/531.35.5 (KHTML, like Gecko) Version/4.0.3 Safari/531.35.5',
|
||||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246',
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246',
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { Readable } from 'node:stream';
|
|||||||
import { IncomingMessage } from 'node:http';
|
import { IncomingMessage } from 'node:http';
|
||||||
import { parseAudioFormats, StreamOptions, StreamType } from '../stream';
|
import { parseAudioFormats, StreamOptions, StreamType } from '../stream';
|
||||||
import { request, request_stream } from '../../Request';
|
import { request, request_stream } from '../../Request';
|
||||||
import { video_info } from '..';
|
import { video_stream_info } from '../utils/extractor';
|
||||||
|
|
||||||
export interface FormatInterface {
|
export interface FormatInterface {
|
||||||
url: string;
|
url: string;
|
||||||
@ -98,7 +98,7 @@ export class LiveStream {
|
|||||||
* Used by dash_timer for updating dash_url every 30 minutes.
|
* Used by dash_timer for updating dash_url every 30 minutes.
|
||||||
*/
|
*/
|
||||||
private async dash_updater() {
|
private async dash_updater() {
|
||||||
const info = await video_info(this.video_url);
|
const info = await video_stream_info(this.video_url);
|
||||||
if (
|
if (
|
||||||
info.LiveStreamData.isLive === true &&
|
info.LiveStreamData.isLive === true &&
|
||||||
info.LiveStreamData.hlsManifestUrl !== null &&
|
info.LiveStreamData.hlsManifestUrl !== null &&
|
||||||
@ -277,7 +277,7 @@ export class Stream {
|
|||||||
* Retry if we get 404 or 403 Errors.
|
* Retry if we get 404 or 403 Errors.
|
||||||
*/
|
*/
|
||||||
private async retry() {
|
private async retry() {
|
||||||
const info = await video_info(this.video_url);
|
const info = await video_stream_info(this.video_url);
|
||||||
const audioFormat = parseAudioFormats(info.format);
|
const audioFormat = parseAudioFormats(info.format);
|
||||||
this.url = audioFormat[this.quality].url;
|
this.url = audioFormat[this.quality].url;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { IncomingMessage } from 'http';
|
import { IncomingMessage } from 'http';
|
||||||
import { request_stream } from '../../Request';
|
import { request_stream } from '../../Request';
|
||||||
import { parseAudioFormats, StreamOptions, StreamType } from '../stream';
|
import { parseAudioFormats, StreamOptions, StreamType } from '../stream';
|
||||||
import { video_info } from '../utils';
|
import { video_stream_info } from '../utils/extractor';
|
||||||
import { Timer } from './LiveStream';
|
import { Timer } from './LiveStream';
|
||||||
import { WebmSeeker, WebmSeekerState } from './WebmSeeker';
|
import { WebmSeeker, WebmSeekerState } from './WebmSeeker';
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ export class SeekStream {
|
|||||||
* Retry if we get 404 or 403 Errors.
|
* Retry if we get 404 or 403 Errors.
|
||||||
*/
|
*/
|
||||||
private async retry() {
|
private async retry() {
|
||||||
const info = await video_info(this.video_url);
|
const info = await video_stream_info(this.video_url);
|
||||||
const audioFormat = parseAudioFormats(info.format);
|
const audioFormat = parseAudioFormats(info.format);
|
||||||
this.url = audioFormat[this.quality].url;
|
this.url = audioFormat[this.quality].url;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ interface formatOptions {
|
|||||||
s?: string;
|
s?: string;
|
||||||
}
|
}
|
||||||
// RegExp for various js functions
|
// RegExp for various js functions
|
||||||
const var_js = '[a-zA-Z_\\$][a-zA-Z_0-9]*';
|
const var_js = '[a-zA-Z_\\$]\\w*';
|
||||||
const singlequote_js = `'[^'\\\\]*(:?\\\\[\\s\\S][^'\\\\]*)*'`;
|
const singlequote_js = `'[^'\\\\]*(:?\\\\[\\s\\S][^'\\\\]*)*'`;
|
||||||
const duoblequote_js = `"[^"\\\\]*(:?\\\\[\\s\\S][^"\\\\]*)*"`;
|
const duoblequote_js = `"[^"\\\\]*(:?\\\\[\\s\\S][^"\\\\]*)*"`;
|
||||||
const quote_js = `(?:${singlequote_js}|${duoblequote_js})`;
|
const quote_js = `(?:${singlequote_js}|${duoblequote_js})`;
|
||||||
|
|||||||
@ -122,12 +122,12 @@ export async function video_basic_info(url: string, options: InfoOptions = {}):
|
|||||||
const player_data = body
|
const player_data = body
|
||||||
.split('var ytInitialPlayerResponse = ')?.[1]
|
.split('var ytInitialPlayerResponse = ')?.[1]
|
||||||
?.split(';</script>')[0]
|
?.split(';</script>')[0]
|
||||||
.split(/;\s*"(var|const|let)"/)[0];
|
.split(/;\s*(var|const|let)\s/)[0];
|
||||||
if (!player_data) throw new Error('Initial Player Response Data is undefined.');
|
if (!player_data) throw new Error('Initial Player Response Data is undefined.');
|
||||||
const initial_data = body
|
const initial_data = body
|
||||||
.split('var ytInitialData = ')?.[1]
|
.split('var ytInitialData = ')?.[1]
|
||||||
?.split(';</script>')[0]
|
?.split(';</script>')[0]
|
||||||
.split(/;\s*"(var|const|let)"/)[0];
|
.split(/;\s*(var|const|let)\s/)[0];
|
||||||
if (!initial_data) throw new Error('Initial Response Data is undefined.');
|
if (!initial_data) throw new Error('Initial Response Data is undefined.');
|
||||||
const player_response = JSON.parse(player_data);
|
const player_response = JSON.parse(player_data);
|
||||||
const initial_response = JSON.parse(initial_data);
|
const initial_response = JSON.parse(initial_data);
|
||||||
@ -226,7 +226,7 @@ export async function video_stream_info(url: string, options: InfoOptions = {}):
|
|||||||
const player_data = body
|
const player_data = body
|
||||||
.split('var ytInitialPlayerResponse = ')?.[1]
|
.split('var ytInitialPlayerResponse = ')?.[1]
|
||||||
?.split(';</script>')[0]
|
?.split(';</script>')[0]
|
||||||
.split(/;\s*(var|const|let)/)[0];
|
.split(/;\s*(var|const|let)\s/)[0];
|
||||||
if (!player_data) throw new Error('Initial Player Response Data is undefined.');
|
if (!player_data) throw new Error('Initial Player Response Data is undefined.');
|
||||||
const player_response = JSON.parse(player_data);
|
const player_response = JSON.parse(player_data);
|
||||||
if (player_response.playabilityStatus.status !== 'OK')
|
if (player_response.playabilityStatus.status !== 'OK')
|
||||||
@ -346,7 +346,7 @@ export async function playlist_info(url: string, options: PlaylistOptions = {}):
|
|||||||
body
|
body
|
||||||
.split('var ytInitialData = ')[1]
|
.split('var ytInitialData = ')[1]
|
||||||
.split(';</script>')[0]
|
.split(';</script>')[0]
|
||||||
.split(/;\s*"(var|const|let)"/)[0]
|
.split(/;\s*(var|const|let)\s/)[0]
|
||||||
);
|
);
|
||||||
if (response.alerts) {
|
if (response.alerts) {
|
||||||
if (response.alerts[0].alertWithButtonRenderer?.type === 'INFO') {
|
if (response.alerts[0].alertWithButtonRenderer?.type === 'INFO') {
|
||||||
@ -463,12 +463,12 @@ function getNormalPlaylist(response: any, body: any): YouTubePlayList {
|
|||||||
if (!data.title.runs || !data.title.runs.length) throw new Error('Failed to Parse Playlist info.');
|
if (!data.title.runs || !data.title.runs.length) throw new Error('Failed to Parse Playlist info.');
|
||||||
|
|
||||||
const author = playlist_details[1]?.playlistSidebarSecondaryInfoRenderer.videoOwner;
|
const author = playlist_details[1]?.playlistSidebarSecondaryInfoRenderer.videoOwner;
|
||||||
const views = data.stats.length === 3 ? data.stats[1].simpleText.replace(/[^0-9]/g, '') : 0;
|
const views = data.stats.length === 3 ? data.stats[1].simpleText.replace(/\D/g, '') : 0;
|
||||||
const lastUpdate =
|
const lastUpdate =
|
||||||
data.stats
|
data.stats
|
||||||
.find((x: any) => 'runs' in x && x['runs'].find((y: any) => y.text.toLowerCase().includes('last update')))
|
.find((x: any) => 'runs' in x && x['runs'].find((y: any) => y.text.toLowerCase().includes('last update')))
|
||||||
?.runs.pop()?.text ?? null;
|
?.runs.pop()?.text ?? null;
|
||||||
const videosCount = data.stats[0].runs[0].text.replace(/[^0-9]/g, '') || 0;
|
const videosCount = data.stats[0].runs[0].text.replace(/\D/g, '') || 0;
|
||||||
|
|
||||||
const res = new YouTubePlayList({
|
const res = new YouTubePlayList({
|
||||||
continuation: {
|
continuation: {
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export function ParseSearchResult(html: string, options?: ParseSearchInterface):
|
|||||||
const data = html
|
const data = html
|
||||||
.split('var ytInitialData = ')?.[1]
|
.split('var ytInitialData = ')?.[1]
|
||||||
?.split(';</script>')[0]
|
?.split(';</script>')[0]
|
||||||
.split(/;\s*"(var|const|let)"/)[0];
|
.split(/;\s*(var|const|let)\s/)[0];
|
||||||
const json_data = JSON.parse(data);
|
const json_data = JSON.parse(data);
|
||||||
const results = [];
|
const results = [];
|
||||||
const details =
|
const details =
|
||||||
@ -146,7 +146,7 @@ export function parseVideo(data?: any): YouTubeVideo {
|
|||||||
artist: Boolean(badge?.includes('artist'))
|
artist: Boolean(badge?.includes('artist'))
|
||||||
},
|
},
|
||||||
uploadedAt: data.videoRenderer.publishedTimeText?.simpleText ?? null,
|
uploadedAt: data.videoRenderer.publishedTimeText?.simpleText ?? null,
|
||||||
views: data.videoRenderer.viewCountText?.simpleText?.replace(/[^0-9]/g, '') ?? 0,
|
views: data.videoRenderer.viewCountText?.simpleText?.replace(/\D/g, '') ?? 0,
|
||||||
live: durationText ? false : true
|
live: durationText ? false : true
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ export function parsePlaylist(data?: any): YouTubePlayList {
|
|||||||
name: channel?.text,
|
name: channel?.text,
|
||||||
url: `https://www.youtube.com${channel?.navigationEndpoint.commandMetadata.webCommandMetadata.url}`
|
url: `https://www.youtube.com${channel?.navigationEndpoint.commandMetadata.webCommandMetadata.url}`
|
||||||
},
|
},
|
||||||
videos: parseInt(data.playlistRenderer.videoCount.replace(/[^0-9]/g, ''))
|
videos: parseInt(data.playlistRenderer.videoCount.replace(/\D/g, ''))
|
||||||
},
|
},
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user