ytmusic_api_unofficial
Advanced tools
Comparing version 1.1.0-beta.1.6.2 to 1.1.0-beta.1.10.0
@@ -9,3 +9,7 @@ "use strict"; | ||
INVALID_ARGUMENT: 'INVALID_ARGUMENT', | ||
INVALID_TYPE_SEARCH: 'INVALID_TYPE_SEARCH', | ||
INVALID_TYPE_DOWNLOAD: 'INVALID_TYPE_DOWNLOAD', | ||
INVALID_TYPE_QUALITY: 'INVALID_TYPE_QUALITY', | ||
DOWNLOAD_LINK_NOT_FOUND: 'DOWNLOAD_LINK_NOT_FOUND', | ||
}; | ||
exports.default = ErrorCode; |
@@ -13,3 +13,7 @@ "use strict"; | ||
[errorCodes_1.default.INVALID_ARGUMENT]: (message) => `The argument was invalid. Message: ${message}`, | ||
[errorCodes_1.default.INVALID_TYPE_SEARCH]: (error) => `The type of search was invalid. Type Available: ${error.typesAvailable}. Type Requested: ${error.typeRequested}`, | ||
[errorCodes_1.default.INVALID_TYPE_DOWNLOAD]: (error) => `The type of download was invalid. Type Available: ${error.typesAvailable}. Type Requested: ${error.typeRequested}`, | ||
[errorCodes_1.default.INVALID_TYPE_QUALITY]: (error) => `The type of quality was invalid. Type Available: ${error.typesAvailable}. Type Requested: ${error.typeRequested}`, | ||
[errorCodes_1.default.DOWNLOAD_LINK_NOT_FOUND]: (error) => `The download link was not found for the parameters Type: ${error.typeRequested} and Quality: ${error.qualityRequested}`, | ||
}; | ||
exports.default = Messages; |
@@ -0,4 +1,8 @@ | ||
import { DownloadQuality_param } from "../types/DownloadQuality"; | ||
import { DownloadType_param } from "../types/DownloadType"; | ||
declare const _default: { | ||
getWebm: (id: string) => Promise<any>; | ||
getMp3: (id: string) => Promise<any>; | ||
download(id: string, type?: DownloadType_param, quality?: DownloadQuality_param): Promise<any>; | ||
}; | ||
export default _default; |
@@ -11,5 +11,15 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const requestManager_1 = require("../utils/requestManager"); | ||
const fs_1 = __importDefault(require("fs")); | ||
const path_1 = __importDefault(require("path")); | ||
const decodeCipher_1 = require("../utils/decodeCipher"); | ||
const DownloadQuality_1 = require("../types/DownloadQuality"); | ||
const DownloadType_1 = require("../types/DownloadType"); | ||
const errors_1 = require("../errors"); | ||
const errorCodes_1 = __importDefault(require("../errors/errorCodes")); | ||
const Download_1 = require("../models/Download"); | ||
exports.default = { | ||
@@ -27,2 +37,48 @@ getWebm: (id) => __awaiter(void 0, void 0, void 0, function* () { | ||
}), | ||
getMp3: (id) => __awaiter(void 0, void 0, void 0, function* () { | ||
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () { | ||
getPlayer(id).then((res) => { | ||
if (!res.streamingData) | ||
return reject(res.playabilityStatus); | ||
let mp3 = res.streamingData.adaptiveFormats.filter((item) => item.mimeType.includes('audio/mp4')).sort((a, b) => b.bitrate - a.bitrate)[0]; | ||
mp3.url = (0, decodeCipher_1.decode)(mp3); | ||
resolve(mp3); | ||
}); | ||
})); | ||
}), | ||
download(id, type = 'mp3', quality) { | ||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { | ||
if (!DownloadType_1.DownloadType_arr.includes(type)) | ||
throw new errors_1.YTjsErrorError(errorCodes_1.default.INVALID_TYPE_DOWNLOAD, { typeRequested: type, typesAvailable: DownloadType_1.DownloadType_arr }); | ||
if (quality && !DownloadQuality_1.DownloadQuality_arr.includes(quality)) | ||
throw new errors_1.YTjsErrorError(errorCodes_1.default.INVALID_TYPE_QUALITY, { typeRequested: quality, typesAvailable: DownloadQuality_1.DownloadQuality_arr }); | ||
type = type.replace('mp3', 'mp4'); | ||
getPlayer(id).then((res) => { | ||
if (!res.streamingData) | ||
return reject(res.playabilityStatus); | ||
fs_1.default.writeFileSync(path_1.default.join(__dirname, './test.json'), JSON.stringify(res, null, 2)); | ||
let download = res.streamingData.adaptiveFormats.filter((item) => { | ||
if ((type === 'mp4' || type === 'webm') && !!item.audioQuality) | ||
return item.mimeType.includes(type); | ||
}); | ||
if (quality === 'high') { | ||
download = download.sort((a, b) => b.bitrate - a.bitrate)[0]; | ||
} | ||
else if (quality === 'low') { | ||
download = download.sort((a, b) => a.bitrate - b.bitrate)[0]; | ||
} | ||
else if (quality === 'medium') { | ||
download = download.sort((a, b) => b.bitrate - a.bitrate)[Math.round(download.length / 2) - 1]; | ||
} | ||
else { | ||
download = download.sort((a, b) => b.bitrate - a.bitrate)[Math.round(download.length / 2) - 1]; | ||
} | ||
if (!download) | ||
return reject(new errors_1.YTjsErrorError(errorCodes_1.default.DOWNLOAD_LINK_NOT_FOUND, { typeRequested: type, qualityRequested: quality || 'default' })); | ||
download.url = (0, decodeCipher_1.decode)(download); | ||
download.expireDate = new Date(parseInt(download.url.split('expire=')[1].split('&')[0]) * 1000); | ||
resolve(new Download_1.Download(download)); | ||
}); | ||
})); | ||
} | ||
}; | ||
@@ -29,0 +85,0 @@ function getPlayer(videoId, body = {}) { |
@@ -5,3 +5,3 @@ import { Music } from "../models/Music"; | ||
declare const _default: { | ||
search: (query: string, type: TypeSearch) => Promise<Array<Music>>; | ||
search: (query: string, type: TypeSearch_param) => Promise<Array<Music>>; | ||
getHomePage: () => Promise<Home>; | ||
@@ -14,7 +14,7 @@ relative: (ID: string) => Promise<Array<Music>>; | ||
export default _default; | ||
declare const TypeSearch_arr: string[]; | ||
type TypeSearch_param = typeof TypeSearch_arr[number]; | ||
export declare class TypeSearch { | ||
static readonly MUSIC = "MUSIC"; | ||
static readonly VIDEO = "VIDEO"; | ||
static readonly MUSIC_values: string[]; | ||
static readonly VIDEO_values: string[]; | ||
static MUSIC: TypeSearch_param; | ||
static VIDEO: TypeSearch_param; | ||
} |
@@ -26,3 +26,6 @@ "use strict"; | ||
search: (query, type) => __awaiter(void 0, void 0, void 0, function* () { | ||
var _a, _b; | ||
var _a, _b, _c, _d, _e; | ||
// Check If type is valid with TypeSearch | ||
if (!TypeSearch_arr.includes(type)) | ||
throw new errors_1.YTjsErrorError(errorCodes_1.default.INVALID_TYPE_SEARCH, { typeRequested: type, typesAvailable: TypeSearch_arr }); | ||
if ((_a = query.match(/^(?:https?:\/\/)?(?:www\.)?.*(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/watch\?.+&v=))([\w-]{11})(?:.+)?$/)) === null || _a === void 0 ? void 0 : _a[1]) { | ||
@@ -32,22 +35,24 @@ return [new Music_1.Music(yield GetData((_b = query.match(/^(?:https?:\/\/)?(?:www\.)?.*(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/watch\?.+&v=))([\w-]{11})(?:.+)?$/)) === null || _b === void 0 ? void 0 : _b[1]))]; | ||
else { | ||
return (0, requestManager_1.requestToYtApi)('search', { | ||
"query": query, | ||
}).then((res) => __awaiter(void 0, void 0, void 0, function* () { | ||
var _c, _d, _e, _f, _g, _h; | ||
let data = res.data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content.sectionListRenderer.contents.filter((item) => { var _a, _b, _c; return ((_c = (_b = (_a = item === null || item === void 0 ? void 0 : item.musicShelfRenderer) === null || _a === void 0 ? void 0 : _a.title) === null || _b === void 0 ? void 0 : _b.runs[0]) === null || _c === void 0 ? void 0 : _c.text) === 'Songs'; })[0].musicShelfRenderer.contents; | ||
if ((_c = res.data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content.sectionListRenderer.contents.filter((item) => { var _a, _b, _c; return ((_c = (_b = (_a = item === null || item === void 0 ? void 0 : item.musicCardShelfRenderer) === null || _a === void 0 ? void 0 : _a.subtitle) === null || _b === void 0 ? void 0 : _b.runs[0]) === null || _c === void 0 ? void 0 : _c.text) === 'Song'; })[0]) === null || _c === void 0 ? void 0 : _c.musicCardShelfRenderer) | ||
data.unshift({ musicResponsiveListItemRenderer: Object.assign({}, res.data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content.sectionListRenderer.contents.filter((item) => { var _a, _b, _c; return ((_c = (_b = (_a = item === null || item === void 0 ? void 0 : item.musicCardShelfRenderer) === null || _a === void 0 ? void 0 : _a.subtitle) === null || _b === void 0 ? void 0 : _b.runs[0]) === null || _c === void 0 ? void 0 : _c.text) === 'Song'; })[0].musicCardShelfRenderer) }); | ||
const resp_data = []; | ||
let data; | ||
const resp_data = []; | ||
if (type === TypeSearch.MUSIC || type === TypeSearch.VIDEO) { | ||
if (type === TypeSearch.MUSIC) { | ||
data = data.filter((item) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; return TypeSearch.MUSIC_values.includes((_j = (_h = (_g = (_f = (_e = (_d = (_c = (_b = (_a = item === null || item === void 0 ? void 0 : item.musicResponsiveListItemRenderer) === null || _a === void 0 ? void 0 : _a.overlay) === null || _b === void 0 ? void 0 : _b.musicItemThumbnailOverlayRenderer) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.musicPlayButtonRenderer) === null || _e === void 0 ? void 0 : _e.playNavigationEndpoint) === null || _f === void 0 ? void 0 : _f.watchEndpoint) === null || _g === void 0 ? void 0 : _g.watchEndpointMusicSupportedConfigs) === null || _h === void 0 ? void 0 : _h.watchEndpointMusicConfig) === null || _j === void 0 ? void 0 : _j.musicVideoType) || TypeSearch.MUSIC_values.includes((_k = item === null || item === void 0 ? void 0 : item.musicResponsiveListItemRenderer) === null || _k === void 0 ? void 0 : _k.title.runs[0].navigationEndpoint.watchEndpoint.watchEndpointMusicSupportedConfigs.watchEndpointMusicConfig.musicVideoType); }); | ||
const music_data = yield (0, requestManager_1.requestToYtApi)('search', { | ||
"query": query, | ||
"params": MUSIC_param, | ||
}); | ||
data = music_data.data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content.sectionListRenderer.contents.filter((item) => { var _a, _b, _c; return ((_c = (_b = (_a = item === null || item === void 0 ? void 0 : item.musicShelfRenderer) === null || _a === void 0 ? void 0 : _a.title) === null || _b === void 0 ? void 0 : _b.runs[0]) === null || _c === void 0 ? void 0 : _c.text) === 'Songs'; })[0].musicShelfRenderer.contents; | ||
} | ||
else if (type === TypeSearch.VIDEO) { | ||
data = data.filter((item) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; return TypeSearch.VIDEO_values.includes((_j = (_h = (_g = (_f = (_e = (_d = (_c = (_b = (_a = item === null || item === void 0 ? void 0 : item.musicResponsiveListItemRenderer) === null || _a === void 0 ? void 0 : _a.overlay) === null || _b === void 0 ? void 0 : _b.musicItemThumbnailOverlayRenderer) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.musicPlayButtonRenderer) === null || _e === void 0 ? void 0 : _e.playNavigationEndpoint) === null || _f === void 0 ? void 0 : _f.watchEndpoint) === null || _g === void 0 ? void 0 : _g.watchEndpointMusicSupportedConfigs) === null || _h === void 0 ? void 0 : _h.watchEndpointMusicConfig) === null || _j === void 0 ? void 0 : _j.musicVideoType) || TypeSearch.VIDEO_values.includes((_k = item === null || item === void 0 ? void 0 : item.musicResponsiveListItemRenderer) === null || _k === void 0 ? void 0 : _k.title.runs[0].navigationEndpoint.watchEndpoint.watchEndpointMusicSupportedConfigs.watchEndpointMusicConfig.musicVideoType); }); | ||
const music_data = yield (0, requestManager_1.requestToYtApi)('search', { | ||
"query": query, | ||
"params": VIDEO_param, | ||
}); | ||
data = music_data.data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content.sectionListRenderer.contents.filter((item) => { var _a, _b, _c; return ((_c = (_b = (_a = item === null || item === void 0 ? void 0 : item.musicShelfRenderer) === null || _a === void 0 ? void 0 : _a.title) === null || _b === void 0 ? void 0 : _b.runs[0]) === null || _c === void 0 ? void 0 : _c.text) === 'Videos'; })[0].musicShelfRenderer.contents; | ||
} | ||
console.log((_e = (_d = data[0].musicResponsiveListItemRenderer) === null || _d === void 0 ? void 0 : _d.playlistItemData) === null || _e === void 0 ? void 0 : _e.videoId); | ||
for (const item of data) { | ||
resp_data.push(new Music_1.Music((0, extract_1.extract_dataFromGetData)(yield GetData(((_g = (_f = item.musicResponsiveListItemRenderer) === null || _f === void 0 ? void 0 : _f.playlistItemData) === null || _g === void 0 ? void 0 : _g.videoId) || ((_h = item.musicResponsiveListItemRenderer) === null || _h === void 0 ? void 0 : _h.onTap.watchEndpoint.videoId))))); | ||
resp_data.push(new Music_1.Music((0, extract_1.extract_dataFromGetData)(yield GetData(((_d = (_c = item.musicResponsiveListItemRenderer) === null || _c === void 0 ? void 0 : _c.playlistItemData) === null || _d === void 0 ? void 0 : _d.videoId) || ((_e = item.musicResponsiveListItemRenderer) === null || _e === void 0 ? void 0 : _e.onTap.watchEndpoint.videoId))))); | ||
} | ||
return resp_data; | ||
})); | ||
} | ||
return resp_data; | ||
} | ||
@@ -71,12 +76,12 @@ }), | ||
new Promise((resolve4) => __awaiter(void 0, void 0, void 0, function* () { | ||
var _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w; | ||
var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t; | ||
for (let x = 0; music.contents.length > x; x++) { | ||
let musicdt = music.contents[x]; | ||
if (musicdt) { | ||
if (!((_k = (_j = musicdt === null || musicdt === void 0 ? void 0 : musicdt.musicResponsiveListItemRenderer) === null || _j === void 0 ? void 0 : _j.playlistItemData) === null || _k === void 0 ? void 0 : _k.videoId)) { | ||
if ((_o = (_m = (_l = musicdt.musicTwoRowItemRenderer) === null || _l === void 0 ? void 0 : _l.navigationEndpoint) === null || _m === void 0 ? void 0 : _m.browseEndpoint) === null || _o === void 0 ? void 0 : _o.browseId) | ||
resp_data.playlist.push(yield getPlaylist((_r = (_q = (_p = musicdt.musicTwoRowItemRenderer) === null || _p === void 0 ? void 0 : _p.navigationEndpoint) === null || _q === void 0 ? void 0 : _q.browseEndpoint) === null || _r === void 0 ? void 0 : _r.browseId)); | ||
if (!((_g = (_f = musicdt === null || musicdt === void 0 ? void 0 : musicdt.musicResponsiveListItemRenderer) === null || _f === void 0 ? void 0 : _f.playlistItemData) === null || _g === void 0 ? void 0 : _g.videoId)) { | ||
if ((_k = (_j = (_h = musicdt.musicTwoRowItemRenderer) === null || _h === void 0 ? void 0 : _h.navigationEndpoint) === null || _j === void 0 ? void 0 : _j.browseEndpoint) === null || _k === void 0 ? void 0 : _k.browseId) | ||
resp_data.playlist.push(yield getPlaylist((_o = (_m = (_l = musicdt.musicTwoRowItemRenderer) === null || _l === void 0 ? void 0 : _l.navigationEndpoint) === null || _m === void 0 ? void 0 : _m.browseEndpoint) === null || _o === void 0 ? void 0 : _o.browseId)); | ||
} | ||
else { | ||
let title_music_list = (_w = (_v = (_u = (_t = (_s = music === null || music === void 0 ? void 0 : music.header) === null || _s === void 0 ? void 0 : _s.musicCarouselShelfBasicHeaderRenderer) === null || _t === void 0 ? void 0 : _t.title) === null || _u === void 0 ? void 0 : _u.runs) === null || _v === void 0 ? void 0 : _v[0]) === null || _w === void 0 ? void 0 : _w.text; | ||
let title_music_list = (_t = (_s = (_r = (_q = (_p = music === null || music === void 0 ? void 0 : music.header) === null || _p === void 0 ? void 0 : _p.musicCarouselShelfBasicHeaderRenderer) === null || _q === void 0 ? void 0 : _q.title) === null || _r === void 0 ? void 0 : _r.runs) === null || _s === void 0 ? void 0 : _s[0]) === null || _t === void 0 ? void 0 : _t.text; | ||
if (!resp_data.music_list.find((e) => e.title === title_music_list)) | ||
@@ -201,2 +206,3 @@ resp_data.music_list.push({ title: title_music_list, musics: [] }); | ||
} | ||
const TypeSearch_arr = ['MUSIC', 'VIDEO']; | ||
class TypeSearch { | ||
@@ -206,4 +212,3 @@ } | ||
TypeSearch.VIDEO = 'VIDEO'; | ||
TypeSearch.MUSIC_values = ['MUSIC_VIDEO_TYPE_ATV', 'MUSIC_VIDEO_TYPE_OMV', 'MUSIC_VIDEO_TYPE_SONG']; | ||
TypeSearch.VIDEO_values = ['MUSIC_VIDEO_TYPE_VIDEO', 'MUSIC_VIDEO_TYPE_CONCERT', 'MUSIC_VIDEO_TYPE_COVER', 'MUSIC_VIDEO_TYPE_PARODY', 'MUSIC_VIDEO_TYPE_PERFORMANCE', 'MUSIC_VIDEO_TYPE_REMIX', 'MUSIC_VIDEO_TYPE_USER_GENERATED', 'MUSIC_VIDEO_TYPE_VIDEO_CLIP', 'MUSIC_VIDEO_TYPE_VIDEO_OTHER', 'MUSIC_VIDEO_TYPE_VIDEO_WITH_MUSIC', 'MUSIC_VIDEO_TYPE_VISUALIZER']; | ||
exports.TypeSearch = TypeSearch; | ||
const MUSIC_param = 'EgWKAQIIAWoOEAMQBBAJEA4QChAFEBU%3D', VIDEO_param = 'EgWKAQIQAWoOEAkQBRADEAQQDhAKEBU%3D'; |
@@ -0,4 +1,7 @@ | ||
/// <reference types="node" /> | ||
import { Artwork } from "./Artwork"; | ||
import { Artist } from "./Artist"; | ||
import { Duration } from "./Duration"; | ||
import { DownloadType_param } from "../types/DownloadType"; | ||
import { DownloadQuality_param } from "../types/DownloadQuality"; | ||
export declare class Music { | ||
@@ -16,3 +19,3 @@ artworks: Array<Artwork>; | ||
getLyrics(): Promise<Lyrics | NoLyrics>; | ||
getRelative(): Promise<Array<Music>>; | ||
download(type: DownloadType_param, quality?: DownloadQuality_param): Promise<Buffer>; | ||
} | ||
@@ -19,0 +22,0 @@ declare class Lyrics { |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Music = void 0; | ||
const requestManager_1 = require("../utils/requestManager"); | ||
const downloadManager_1 = __importDefault(require("../managers/downloadManager")); | ||
class Music { | ||
@@ -41,4 +45,5 @@ constructor(data, autoMix) { | ||
} | ||
getRelative() { | ||
download(type, quality) { | ||
return new Promise((resolve, reject) => { | ||
downloadManager_1.default.download(this.id, type, quality).then(resolve).catch(reject); | ||
}); | ||
@@ -48,13 +53,2 @@ } | ||
exports.Music = Music; | ||
function extractArtistData(data) { | ||
return data.longBylineText.runs.find((item) => { var _a, _b, _c, _d; return ((_d = (_c = (_b = (_a = item.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint) === null || _b === void 0 ? void 0 : _b.browseEndpointContextSupportedConfigs) === null || _c === void 0 ? void 0 : _c.browseEndpointContextMusicConfig) === null || _d === void 0 ? void 0 : _d.pageType) === 'MUSIC_PAGE_TYPE_ARTIST'; }); | ||
} | ||
function timeToSec(time) { | ||
const time_split = time.split(':'); | ||
let time_sec = 0; | ||
for (let i = 0; i < time_split.length; i++) { | ||
time_sec += parseInt(time_split[i]) * Math.pow(60, time_split.length - i - 1); | ||
} | ||
return time_sec; | ||
} | ||
class Lyrics { | ||
@@ -61,0 +55,0 @@ } |
{ | ||
"name": "ytmusic_api_unofficial", | ||
"version": "1.1.0-beta.1.6.2", | ||
"version": "1.1.0-beta.1.10.0", | ||
"description": "A simple API to get music from YouTube Music", | ||
@@ -5,0 +5,0 @@ "scripts": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
801886
61
7043
1
1