UNPKG

playdl-music-extractor

Version:

PlayDL Music Extractor is a Extractor/Scrapper and Helps Players to fetch data from play-dl or Custom Extractors , as Per reduces extra work and credentials

264 lines (250 loc) 7.17 kB
const { stream, setToken, search } = require('play-dl'); const randomUserAgents = require('random-useragent').getRandom; const ffmpeg = require('prism-media').FFmpeg; const { getLyrics } = require('./__lyrics'); const soundCloud = require('./__soundCloud'); class Track { #raw = {}; constructor(rawBlueprint, __rawPlaydl, playdl, queue, extras) { this.#raw = { ...__rawPlaydl, streamCaches: extras?.streamCaches, queue, }; this.playdl = playdl; this.patch(rawBlueprint, queue); } patch(rawBlueprint, queue) { if (!rawBlueprint?.url) return undefined; this.trackId = rawBlueprint?.trackId; this.url = rawBlueprint?.url; this.videoId = rawBlueprint?.video_Id ?? rawBlueprint?.videoId; this.views = rawBlueprint?.view ?? rawBlueprint?.views; this.title = rawBlueprint?.title; this.description = rawBlueprint?.description; this.author = { name: rawBlueprint?.author, url: rawBlueprint?.author_link, }; this.extractorModel = { orignal: rawBlueprint?.orignal_extractor ?? 'Unknown', custom: rawBlueprint?.custom_extractor ?? 'play-dl', }; this.duration = { ms: rawBlueprint?.duration, readable: rawBlueprint?.human_duration, }; this.thumbnail = { Id: rawBlueprint?.video_Id ?? rawBlueprint?.videoId, url: rawBlueprint?.thumbnail, }; this.channel = { name: rawBlueprint?.channelName ?? rawBlueprint?.author, Id: rawBlueprint?.channelId ?? rawBlueprint?.author, url: rawBlueprint?.channel_url ?? rawBlueprint?.author_link, }; this.isLive = rawBlueprint?.is_live; this.ratings = { likes: parseInt(rawBlueprint?.likes ?? 0) ?? 0, dislikes: parseInt(rawBlueprint?.dislikes ?? 0) ?? 0, }; this.metadata = rawBlueprint?.metadata; this.queue = queue; this.uniqueId = this.#generateId(); return this; } async getStream( streamUrl, ignoreStreamError, reTryonRatelimit = true, assignStream = false, ) { try { let __rawStream = {}; if (!this.url) return undefined; if ( !( (soundCloud.__test(this.#raw?.url) || this.#raw?.url ?.toLowerCase() ?.trim() ?.startsWith('https://www.youtube.com/watch')) && !streamUrl ) ) { __rawStream = await stream(this.#raw?.url, { discordPlayerCompatibility: true, }); } else if ( streamUrl && typeof streamUrl === 'string' && streamUrl !== '' ) { const ffmpegArgs = [ '-i', streamUrl, '-analyzeduration', '0', '-loglevel', '0', '-acodec', 'libopus', '-f', 'opus', '-ar', '48000', '-ac', '2', ]; __rawStream = new ffmpeg({ args: ffmpegArgs, }); } else if ( this.#raw?.url && typeof this.#raw?.url === 'string' && this.#raw?.url !== '' ) { __rawStream = await stream(this.#raw?.url, { discordPlayerCompatibility: true, }); } else return undefined; if (!assignStream) { return { buffer: __rawStream?.stream ?? __rawStream, videoUrl: this.#raw?.url, type: __rawStream?.type, duration: { ms: (this.#raw?.durationInSec ?? 0) * 1000, readable: Track.humanTimeConversion( (this.#raw?.durationInSec ?? 0) * 1000, ), }, videoId: this.#raw?.id, }; } this.stream = { buffer: __rawStream?.stream ?? __rawStream, videoUrl: this.#raw?.url, type: __rawStream?.type, duration: { ms: (this.#raw?.durationInSec ?? 0) * 1000, readable: Track.humanTimeConversion( (this.#raw?.durationInSec ?? 0) * 1000, ), }, videoId: this.#raw?.id, }; return this; } catch (rawError) { if ( (ignoreStreamError || rawError?.message?.includes('429') || `${rawError}`?.includes('429')) && this.playdl && !reTryonRatelimit ) { return void this.playdl.__errorHandling(rawError); } if ( (ignoreStreamError || rawError?.message?.includes('429') || `${rawError}`?.includes('429')) && this.playdl && reTryonRatelimit ) { this.playdl.__errorHandling(rawError); let __rawUserAgents = this.raw?.streamCaches?.userAgents ?? []; __rawUserAgents = [randomUserAgents(), ...__rawUserAgents]; await setToken({ useragent: __rawUserAgents, }); return await this.getStream(streamUrl, ignoreStreamError, false); } throw rawError; } } async getLyrics() { if ( !( this.url && this.#raw?.title && (this.author?.name ?? this.#raw?.author?.name ?? this.#raw?.artist?.name) ) ) { return undefined; } this.lyrics = await getLyrics( this.#raw?.title?.slice(0, 25)?.trim(), this.author?.name ?? this.#raw?.author?.name ?? this.#raw?.artist?.name, ); return this.lyrics; } static humanTimeConversion(__durationMs = 0) { if ( !( __durationMs && !Number.isNaN(__durationMs) && parseInt(__durationMs) > 0 ) ) { return undefined; } __durationMs /= 1000; let __string = ''; for ( let __cacheArray = [ [Math.floor(__durationMs / 31536e3), 'Years'], [Math.floor((__durationMs % 31536e3) / 86400), 'Days'], [Math.floor(((__durationMs % 31536e3) % 86400) / 3600), 'Hours'], [ Math.floor((((__durationMs % 31536e3) % 86400) % 3600) / 60), 'Minutes', ], [ Math.floor((((__durationMs % 31536e3) % 86400) % 3600) % 60), 'Seconds', ], ], __alterArray = 0, __garbageValue = __cacheArray.length; __alterArray < __garbageValue; __alterArray++ ) { __cacheArray[__alterArray][0] !== 0 && (__string += ` ${__cacheArray[__alterArray][0]} ${ __cacheArray[__alterArray][0] === 1 ? __cacheArray[__alterArray][1].substr( 0, __cacheArray[__alterArray][1].length - 1, ) : __cacheArray[__alterArray][1] }`); } return __string.trim(); } get album() { if (!this.queue?.album) return false; return this.queue?.album; } get albumId() { if (!this.queue?.album) return false; return this.queue?.album?.id; } #generateId() { let requestedId = ''; while ( this.queue.tracks.has(requestedId?.trim()) || requestedId?.trim() === '' ) { requestedId = Math.random().toString(36).slice(2, 15); } return requestedId; } get raw() { if (!this.#raw) return undefined; return this.#raw; } } module.exports = Track;