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
219 lines (209 loc) • 7.36 kB
JavaScript
const fetch = require('isomorphic-unfetch');
const { getData, getPreview } = require('spotify-url-info')(fetch);
const { setToken } = require('play-dl');
const playdlEngine = require('./__playdlEngine');
const album = require('./__album');
class spotify {
static __spotifyCachedToken;
static __spotifyRegex = [
/^(?:spotify:|(?:https?:\/\/(?:open|play)\.spotify\.com\/))(?:embed)?\/?(album|track|playlist|show|episode)(?::|\/)((?:[0-9a-zA-Z]){22})/,
];
static __spotifyalbumRegex = /^(?:spotify:|(?:https?:\/\/(?:open|play)\.spotify\.com\/))(?:embed)?\/?(album|playlist)(?::|\/)((?:[0-9a-zA-Z]){22})/;
static __test(rawUrl, returnRegexValue = false) {
try {
if (!(rawUrl && typeof rawUrl === 'string' && rawUrl !== '')) {
return false;
}
return returnRegexValue
&& Boolean(spotify.__spotifyRegex.find((regExp) => regExp.test(rawUrl)))
? rawUrl?.match(
spotify.__spotifyRegex.find((regExp) => rawUrl.match(regExp)),
) ?? false
: Boolean(spotify.__spotifyRegex.find((regExp) => regExp.test(rawUrl)));
} catch {
return false;
}
}
static async __extractor(rawUrl, __scrapperOptions, playdl, queue) {
if (!rawUrl) return undefined;
try {
const __rawData = await getData(rawUrl);
let __arryData;
let __cacheGarbage;
let __cacheCount = 0;
if (
(__rawData?.type
&& ['track', 'episode'].includes(
__rawData?.type?.toLowerCase()?.trim(),
))
|| __rawData?.show
) {
__arryData = [__rawData];
} else if (
__rawData?.tracks?.items
&& Array.isArray(__rawData?.tracks?.items)
&& __rawData?.tracks?.items?.length > 0
) {
__arryData = __rawData?.tracks?.items
?.filter(
(rawVideo) => (rawVideo?.track?.name && rawVideo?.track?.name !== '')
|| (rawVideo?.name && rawVideo?.name !== ''),
)
?.filter(Boolean);
let garbage = new album(
__rawData,
queue,
__arryData?.length,
__scrapperOptions?.eventReturn?.metadata,
);
garbage = null;
}
if (
(__scrapperOptions?.fetchOptions?.tokens?.spotify?.client_id
&& __scrapperOptions?.fetchOptions?.tokens?.spotify?.client_secret
&& __scrapperOptions?.fetchOptions?.tokens?.spotify?.refresh_token
&& __scrapperOptions?.fetchOptions?.tokens?.spotify?.market)
|| spotify.__spotifyCachedToken
) {
return await spotify.__tokenExtractor(
rawUrl,
__scrapperOptions,
playdl,
queue,
);
}
await __arryData?.reduce(async (totalTracks, rawTrack) => {
if (!queue || (queue && queue?.stopped)) return [undefined];
const privTracks = await totalTracks;
if (
!rawTrack
|| (__cacheCount
&& __cacheCount >= __scrapperOptions?.fetchOptions?.fetchLimit
&& !(
Boolean(
__rawData?.tracks?.items
&& Array.isArray(__rawData?.tracks?.items)
&& __rawData?.tracks?.items?.length > 0,
) && Boolean(__scrapperOptions?.fetchOptions?.skipAlbumLimit)
))
) {
return undefined;
}
__cacheGarbage = await spotify.__trackParser(
rawTrack,
++__cacheCount,
__scrapperOptions,
playdl,
queue,
);
if (privTracks && Array.isArray(privTracks) && privTracks?.length > 0) return [...privTracks, __cacheGarbage];
return [__cacheGarbage];
}, Promise.resolve());
return true;
} catch (rawError) {
if (__scrapperOptions?.ignoreInternalError) {
return void playdl.__errorHandling(rawError);
}
throw rawError;
}
}
static async __tokenExtractor(rawUrl, __scrapperOptions, playdl, queue) {
try {
if (
!(
__scrapperOptions?.fetchOptions?.tokens?.spotify?.client_id
&& __scrapperOptions?.fetchOptions?.tokens?.spotify?.client_secret
&& __scrapperOptions?.fetchOptions?.tokens?.spotify?.refresh_token
&& __scrapperOptions?.fetchOptions?.tokens?.spotify?.market
)
&& !(
spotify.__spotifyCachedToken?.client_id
&& spotify.__spotifyCachedToken?.client_secret
&& spotify.__spotifyCachedToken?.refresh_token
&& spotify.__spotifyCachedToken?.market
)
) {
throw new Error(
'spotify Error : Spotify Token Error , Please Check if you provided "client_id","client_secret","refresh_token","market" , just like official "play-dl"',
);
}
await setToken({
spotify: __scrapperOptions?.fetchOptions?.tokens?.spotify,
});
return await playdlEngine.__rawExtractor(
rawUrl,
{ orignal_extractor: 'spotify' },
__scrapperOptions,
playdl,
queue,
);
} catch (rawError) {
if (__scrapperOptions?.ignoreInternalError) {
return void playdl.__errorHandling(rawError);
}
throw rawError;
}
}
static async __trackParser(
rawTrack,
trackIndex,
__scrapperOptions,
playdl,
queue,
) {
if (!(rawTrack?.id || rawTrack?.track?.id)) return undefined;
const __previewCaches = await getPreview(
(rawTrack?.show && rawTrack?.id
? `https://open.spotify.com/episode/${rawTrack.id}`
: undefined)
?? (rawTrack?.id || rawTrack?.track?.id
? `https://open.spotify.com/track/${
rawTrack?.id ?? rawTrack?.track?.id
}`
: undefined),
);
const __trackBlueprint = {
Id: trackIndex ?? 0,
url:
rawTrack?.external_urls?.spotify
?? rawTrack?.track?.external_urls?.spotify
?? __previewCaches?.link,
title: rawTrack?.name ?? rawTrack?.track?.name ?? __previewCaches?.title,
video_Id: rawTrack?.track?.id ?? rawTrack?.id,
author:
__previewCaches?.artist
?? rawTrack?.artists?.[0]?.name
?? rawTrack?.track?.artists?.[0]?.name,
author_link:
rawTrack?.artists?.[0].external_urls?.spotify
?? rawTrack?.track?.artists?.[0].external_urls?.spotify,
description: rawTrack?.description ?? __previewCaches?.description,
duration: rawTrack?.duration_ms ?? rawTrack?.track?.duration_ms,
orignal_extractor: 'spotify',
thumbnail: __previewCaches?.image,
channelId:
__previewCaches?.artist
?? rawTrack?.artists?.[0]?.name
?? rawTrack?.track?.artists?.[0]?.name,
channel_url:
rawTrack?.artists?.[0].external_urls?.spotify
?? rawTrack?.track?.artists?.[0].external_urls?.spotify,
is_live: false,
};
return await playdlEngine.__rawExtractor(
__trackBlueprint?.title
&& __trackBlueprint?.author
&& __trackBlueprint?.title?.length < 16
? `${__trackBlueprint?.title} | ${__trackBlueprint?.author}`
: __trackBlueprint?.title,
__trackBlueprint,
{
...__scrapperOptions,
fetchOptions: { ...__scrapperOptions?.fetchOptions, fetchLimit: 1 },
},
playdl,
queue,
);
}
}
module.exports = spotify;