refactor lib

This commit is contained in:
Sayem Chowdhury 2021-08-04 01:27:11 +06:00
parent 1dc9b37c99
commit 8831fd618d
2 changed files with 43 additions and 49 deletions

View File

@ -69,5 +69,5 @@ export const decryptDownload = (source: Buffer, trackId: string) => {
}; };
export const trackIsEncrypted = (url: string) => { export const trackIsEncrypted = (url: string) => {
return url.includes("/mobile/") || url.includes("/media/"); return url.includes('/mobile/') || url.includes('/media/');
} };

View File

@ -1,19 +1,19 @@
import axios from 'axios'; import axios from 'axios';
import {getSongFileName} from '../lib/decrypt'; import {getSongFileName} from '../lib/decrypt';
import instance from '../lib/request'; import instance from '../lib/request';
import type {trackType} from '../types' import type {trackType} from '../types';
interface userData { interface userData {
license_token: string, license_token: string;
can_stream_lossless: boolean, can_stream_lossless: boolean;
can_stream_hq: boolean, can_stream_hq: boolean;
} }
class WrongLicense extends Error { class WrongLicense extends Error {
constructor(format: string) { constructor(format: string) {
super() super();
this.name = "WrongLicense" this.name = 'WrongLicense';
this.message = `Your account can't stream ${format} tracks` this.message = `Your account can't stream ${format} tracks`;
} }
} }
@ -31,16 +31,15 @@ const dzAuthenticate = async (): Promise<userData> => {
license_token: data.results.USER.OPTIONS.license_token, license_token: data.results.USER.OPTIONS.license_token,
can_stream_lossless: data.results.USER.OPTIONS.web_lossless || data.results.USER.OPTIONS.mobile_loseless, can_stream_lossless: data.results.USER.OPTIONS.web_lossless || data.results.USER.OPTIONS.mobile_loseless,
can_stream_hq: data.results.USER.OPTIONS.web_hq || data.results.USER.OPTIONS.mobile_hq, can_stream_hq: data.results.USER.OPTIONS.web_hq || data.results.USER.OPTIONS.mobile_hq,
} };
return user_data; return user_data;
}; };
const getTrackUrlFromServer = async (track_token: string, format: string): Promise<string | null> => { const getTrackUrlFromServer = async (track_token: string, format: string): Promise<string | null> => {
const user = user_data ? user_data : await dzAuthenticate(); const user = user_data ? user_data : await dzAuthenticate();
if ( if ((format === 'FLAC' && !user.can_stream_lossless) || (format === 'MP3_320' && !user.can_stream_hq)) {
format === "FLAC" && !user.can_stream_lossless || throw new WrongLicense(format);
format === "MP3_320" && !user.can_stream_hq }
) throw new WrongLicense(format);
const {data} = await instance.post('https://media.deezer.com/v1/get_url', { const {data} = await instance.post('https://media.deezer.com/v1/get_url', {
license_token: user.license_token, license_token: user.license_token,
@ -53,9 +52,9 @@ const getTrackUrlFromServer = async (track_token: string, format: string): Promi
track_tokens: [track_token], track_tokens: [track_token],
}); });
if (data.data.length) { if (data.data.length > 0) {
if (data.data[0].errors) { if (data.data[0].errors) {
throw new Error(`Deezer error: ${JSON.stringify(data)}`) throw new Error(`Deezer error: ${JSON.stringify(data)}`);
} }
return data.data[0].media.length > 0 ? data.data[0].media[0].sources[0].url : null; return data.data[0].media.length > 0 ? data.data[0].media[0].sources[0].url : null;
} }
@ -67,52 +66,47 @@ const getTrackUrlFromServer = async (track_token: string, format: string): Promi
* @param quality 1 = 128kbps, 3 = 320kbps and 9 = flac (around 1411kbps) * @param quality 1 = 128kbps, 3 = 320kbps and 9 = flac (around 1411kbps)
*/ */
export const getTrackDownloadUrl = async (track: trackType, quality: number): Promise<string | null> => { export const getTrackDownloadUrl = async (track: trackType, quality: number): Promise<string | null> => {
let url: string | null = null; let formatName: string;
let wrongLicense; switch (quality) {
let formatName; case 9:
if (quality === 9) {
formatName = 'FLAC'; formatName = 'FLAC';
} else if (quality === 3) { break;
case 3:
formatName = 'MP3_320'; formatName = 'MP3_320';
} else { case 1:
formatName = 'MP3_128'; formatName = 'MP3_128';
default:
throw new Error(`Unknow quality ${quality}`);
} }
// Get URL with the official API // Get URL with the official API
try { try {
url = await getTrackUrlFromServer(track.TRACK_TOKEN, formatName) const url = await getTrackUrlFromServer(track.TRACK_TOKEN, formatName);
if (url) { if (url && (await testUrl(url))) {
let isUrlOk = await testUrl(url) return url;
if (isUrlOk) return url;
} }
url = null; } catch (err) {
} catch (e) { if (err instanceof WrongLicense) {
if (e instanceof WrongLicense) { throw new Error(`Your account can't stream ${formatName} tracks`);
wrongLicense = true;
} else { } else {
throw e; throw err;
} }
url = null;
} }
// Fallback to the old method // Fallback to the old method
if (!url) {
const cdn = track.MD5_ORIGIN[0]; // cdn destination
const filename = getSongFileName(track, quality); // encrypted file name const filename = getSongFileName(track, quality); // encrypted file name
url = `https://e-cdns-proxy-${cdn}.dzcdn.net/mobile/1/${filename}`; const url = `https://e-cdns-proxy-${track.MD5_ORIGIN[0]}.dzcdn.net/mobile/1/${filename}`;
let isUrlOk = await testUrl(url) if (await testUrl(url)) {
if (isUrlOk) return url return url;
url = null
}
if (wrongLicense) throw new Error(`Your account can't stream ${formatName} tracks`);
return url
} }
return null;
};
const testUrl = async (url: string): Promise<boolean> => { const testUrl = async (url: string): Promise<boolean> => {
try { try {
let response = await axios.head(url); let response = await axios.head(url);
if (Number(response.headers["content-length"]) > 0) return true; return Number(response.headers['content-length']) > 0 ? true : false;
return false; } catch (err) {
} catch (e) {
return false; return false;
} }
} };