getTrackDownloadUrl: return track data in json format

This commit is contained in:
Namkhai B 2021-08-03 15:43:39 -05:00
parent 48ddf3b6d4
commit 0940987809
No known key found for this signature in database
GPG Key ID: 9DC021F538318528
3 changed files with 33 additions and 25 deletions

View File

@ -1,7 +1,7 @@
import test from 'ava';
import axios from 'axios';
import * as api from '../src';
import {trackIsEncrypted, decryptDownload} from '../src/lib/decrypt';
import {decryptDownload} from '../src/lib/decrypt';
import {downloadAlbumCover} from '../src/metadata-writer/abumCover';
import {getLyricsMusixmatch} from '../src/metadata-writer/musixmatchLyrics';
import {getTrackDownloadUrl} from '../src/lib/get-url';
@ -146,14 +146,14 @@ test('SEARCH TRACK, ALBUM & ARTIST', async (t) => {
if (process.env.CI) {
test('DOWNLOAD TRACK128 & ADD METADATA', async (t) => {
const track = await api.getTrackInfo(SNG_ID);
const url = await getTrackDownloadUrl(track, 1);
const {data} = await axios.get(url, {responseType: 'arraybuffer'});
const trackData = await getTrackDownloadUrl(track, 1);
const {data} = await axios.get(trackData.trackUrl, {responseType: 'arraybuffer'});
t.truthy(data);
t.true(Buffer.isBuffer(data));
t.is(data.length, 3596119);
const decryptedTrack: Buffer = trackIsEncrypted(url) ? decryptDownload(data, track.SNG_ID) : data;
const decryptedTrack: Buffer = trackData.isEncrypted ? decryptDownload(data, track.SNG_ID) : data;
t.true(Buffer.isBuffer(decryptedTrack));
t.is(decryptedTrack.length, 3596119);
@ -164,14 +164,14 @@ if (process.env.CI) {
// test('TRACK128 WITHOUT ALBUM INFO', async (t) => {
// const track = await api.getTrackInfo('912254892');
// const url = await getTrackDownloadUrl(track, 1);
// const {data} = await axios.get(url, {responseType: 'arraybuffer'});
// const trackData = await getTrackDownloadUrl(track, 1);
// const {data} = await axios.get(trackData.trackUrl, {responseType: 'arraybuffer'});
// t.truthy(data);
// t.true(Buffer.isBuffer(data));
// t.is(data.length, 3262170);
// const decryptedTrack: Buffer = trackIsEncrypted(url) ? decryptDownload(data, track.SNG_ID) : data;
// const decryptedTrack: Buffer = trackData.isEncrypted ? decryptDownload(data, track.SNG_ID) : data;
// t.true(Buffer.isBuffer(decryptedTrack));
// t.is(decryptedTrack.length, 3262170);
@ -184,14 +184,14 @@ if (process.env.CI) {
test('DOWNLOAD TRACK320 & ADD METADATA', async (t) => {
const track = await api.getTrackInfo(SNG_ID);
const url = await getTrackDownloadUrl(track, 3);
const {data} = await axios.get(url, {responseType: 'arraybuffer'});
const trackData = await getTrackDownloadUrl(track, 3);
const {data} = await axios.get(trackData.trackUrl, {responseType: 'arraybuffer'});
t.truthy(data);
t.true(Buffer.isBuffer(data));
t.is(data.length, 8990301);
const decryptedTrack: Buffer = trackIsEncrypted(url) ? decryptDownload(data, track.SNG_ID) : data;
const decryptedTrack: Buffer = trackData.isEncrypted ? decryptDownload(data, track.SNG_ID) : data;
t.true(Buffer.isBuffer(decryptedTrack));
t.is(decryptedTrack.length, 8990301);
@ -202,14 +202,14 @@ if (process.env.CI) {
test('DOWNLOAD TRACK1411 & ADD METADATA', async (t) => {
const track = await api.getTrackInfo(SNG_ID);
const url = await getTrackDownloadUrl(track, 9);
const {data} = await axios.get(url, {responseType: 'arraybuffer'});
const trackData = await getTrackDownloadUrl(track, 9);
const {data} = await axios.get(trackData.trackUrl, {responseType: 'arraybuffer'});
t.truthy(data);
t.true(Buffer.isBuffer(data));
t.is(data.length, 25418289);
const decryptedTrack: Buffer = trackIsEncrypted(url) ? decryptDownload(data, track.SNG_ID) : data;
const decryptedTrack: Buffer = trackData.isEncrypted ? decryptDownload(data, track.SNG_ID) : data;
t.true(Buffer.isBuffer(decryptedTrack));
t.is(data.length, 25418289);

View File

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

View File

@ -65,7 +65,7 @@ const getTrackUrlFromServer = async (track_token: string, format: string): Promi
* @param track Track info json returned from `getTrackInfo`
* @param quality 1 = 128kbps, 3 = 320kbps and 9 = flac (around 1411kbps)
*/
export const getTrackDownloadUrl = async (track: trackType, quality: number): Promise<string> => {
export const getTrackDownloadUrl = async (track: trackType, quality: number): Promise<{trackUrl: string, isEncrypted: boolean, fileSize: number}> => {
let formatName: string;
switch (quality) {
case 9:
@ -84,8 +84,15 @@ export const getTrackDownloadUrl = async (track: trackType, quality: number): Pr
// Get URL with the official API
try {
const url = await getTrackUrlFromServer(track.TRACK_TOKEN, formatName);
if (url && (await testUrl(url))) {
return url;
if (url) {
const fileSize = await testUrl(url);
if (fileSize > 0) {
return {
trackUrl: url,
isEncrypted: url.includes('/mobile/') || url.includes('/media/'),
fileSize: fileSize,
};
}
}
} catch (err) {
if (err instanceof WrongLicense) {
@ -98,17 +105,22 @@ export const getTrackDownloadUrl = async (track: trackType, quality: number): Pr
// Fallback to the old method
const filename = getSongFileName(track, quality); // encrypted file name
const url = `https://e-cdns-proxy-${track.MD5_ORIGIN[0]}.dzcdn.net/mobile/1/${filename}`;
if (await testUrl(url)) {
return url;
const fileSize = await testUrl(url);
if (fileSize > 0) {
return {
trackUrl: url,
isEncrypted: url.includes('/mobile/') || url.includes('/media/'),
fileSize: fileSize,
};
}
throw new Error(`Forbidden to access ${url}`);
};
const testUrl = async (url: string): Promise<boolean> => {
const testUrl = async (url: string): Promise<number> => {
try {
let response = await axios.head(url);
return Number(response.headers['content-length']) > 0 ? true : false;
return Number(response.headers['content-length']);
} catch (err) {
return false;
return 0;
}
};