UNPKG

ytmusic_api_unofficial

Version:

A simple API to get music from YouTube Music

252 lines 12.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.countriesCodes = exports.countries = exports.all_TYPES = exports.AvailableQuality = exports.AvailableFormat = exports.StreamPlayer = exports.Player = exports.Playlist = exports.Music = exports.Album = exports.Duration = exports.Artist = exports.Thumbnail = void 0; exports.search = search; exports.get = get; exports.charts = charts; exports.download = download; exports.getPlayers = getPlayers; exports.getUrlDecodeT = getUrlDecodeT; const request_1 = __importDefault(require("./utils/request")); const responseBuilder_1 = require("./utils/responseBuilder"); const utils_1 = require("./utils/utils"); const error_1 = require("./utils/error"); const default_1 = require("./utils/default"); Object.defineProperty(exports, "all_TYPES", { enumerable: true, get: function () { return default_1.all_TYPES; } }); Object.defineProperty(exports, "AvailableFormat", { enumerable: true, get: function () { return default_1.AvailableFormat; } }); Object.defineProperty(exports, "AvailableQuality", { enumerable: true, get: function () { return default_1.AvailableQuality; } }); Object.defineProperty(exports, "countries", { enumerable: true, get: function () { return default_1.countries; } }); Object.defineProperty(exports, "countriesCodes", { enumerable: true, get: function () { return default_1.countriesCodes; } }); const Music_1 = __importDefault(require("./classes/Music")); exports.Music = Music_1.default; const Artist_1 = __importDefault(require("./classes/Artist")); exports.Artist = Artist_1.default; const Playlist_1 = __importDefault(require("./classes/Playlist")); exports.Playlist = Playlist_1.default; const Player_1 = __importDefault(require("./classes/Player")); exports.Player = Player_1.default; const StreamPlayer_1 = __importDefault(require("./classes/StreamPlayer")); exports.StreamPlayer = StreamPlayer_1.default; const countries_1 = require("./utils/countries"); const decode_1 = require("./utils/decode"); const Duration_1 = __importDefault(require("./classes/Duration")); exports.Duration = Duration_1.default; const Album_1 = __importDefault(require("./classes/Album")); exports.Album = Album_1.default; /** * Require for DOC API */ var Thumbnail_1 = require("./classes/Thumbnail"); Object.defineProperty(exports, "Thumbnail", { enumerable: true, get: function () { return Thumbnail_1.Thumbnail; } }); /** * Search for a query in YouTube Music * @param query - ex: "Hello Adele" * @param filter - ex: "SONG" (Check available types) * @param option - You can change country code. This parameter can be used to get a more precise result depending on location demand * @example * ```JS * const search = await client.search("Hello Adele", "SONG") * console.log(search) * ``` */ function search(query, filter, option = default_1.options) { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { var _a; const hasFilter = !!filter; filter = (_a = filter === null || filter === void 0 ? void 0 : filter.toString()) === null || _a === void 0 ? void 0 : _a.toLowerCase(); if (hasFilter && (!default_1.all_TYPES.includes(filter) && !(!!(default_1.TYPE_SEARCH_CODE === null || default_1.TYPE_SEARCH_CODE === void 0 ? void 0 : default_1.TYPE_SEARCH_CODE[filter])))) return reject((0, error_1.error)(1001, `Available types: ${default_1.all_TYPES.join(", ")}`)); const result = { query, filter: hasFilter ? filter : false, content: [] }; if ((0, utils_1.getYTIdFromText)(query).isValidId) { result.content = [yield this.get(query).catch(reject)]; return resolve(result); } (0, request_1.default)('search', { query, params: hasFilter ? default_1.TYPE_SEARCH_CODE[filter] : '' }, {}, option).then((response) => __awaiter(this, void 0, void 0, function* () { try { if (response.content) return resolve(result); else response = response.contents; if (response.tabbedSearchResultsRenderer) response = response.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content; const sectionList = (0, responseBuilder_1.nav)(response, ['sectionListRenderer', 'contents']); if (sectionList.length === 1 && sectionList[0].itemSectionRenderer) return result; for (const res of sectionList) { let shelf_contents = null; let category = null; if (res.musicCardShelfRenderer) { result.content.push((0, utils_1.topResults)(res.musicCardShelfRenderer)); shelf_contents = (0, responseBuilder_1.nav)(res, ["musicCardShelfRenderer", "contents"], true); if (!shelf_contents) continue; if (shelf_contents[0].messageRenderer) category = (0, responseBuilder_1.nav)(shelf_contents.shift(), ['messageRenderer', 'text', 'runs', 0, 'text']); } else if (res.musicShelfRenderer) { shelf_contents = res["musicShelfRenderer"]["contents"]; category = (0, responseBuilder_1.nav)(res, [...responseBuilder_1.MUSIC_SHELF, ...responseBuilder_1.TITLE_TEXT], true); } else if (res.musicResponsiveListItemRenderer) { shelf_contents = res['musicResponsiveListItemRenderer']['contents']; } else continue; shelf_contents = shelf_contents.filter((item) => item.musicResponsiveListItemRenderer || item.musicTwoRowItemRenderer || item.musicMultiRowListItemRenderer); (0, utils_1.parseSearchResults)(shelf_contents, category).forEach((content, i) => { if (!content || (filter && (hasFilter && (default_1.all_TYPES.includes(filter) && (content === null || content === void 0 ? void 0 : content.resultType) !== filter)))) return; else result.content.push(content); }); } result.content = result.content.filter((content) => !!(content === null || content === void 0 ? void 0 : content.id)); if (option.fetch) { result.content = result.content.filter((content) => !!(content === null || content === void 0 ? void 0 : content.id)); const promises = result.content.map((content) => __awaiter(this, void 0, void 0, function* () { if (content.id) return yield this.get(content.id).catch((e) => { if (process.env.YT_DEBUG_MODE === "true") console.error(e); return null; }); else return null; })); result.content = yield Promise.all(promises); result.content = result.content.filter((content) => !!(content === null || content === void 0 ? void 0 : content.id)); } result.content = (0, utils_1.rankingResponse)(result.content, query); if (result.content.length === 0) return reject((0, error_1.error)(1002, { query })); return resolve(result); } catch (e) { reject((0, error_1.error)(5000, { code: 1005, error: e, message: `Please report this issue on the GitHub repository, this is a bug.` })); } })).catch((e) => { reject(e); }); })); } /** * Get music from YouTube Music by URL or ID or search query (Warning: search query length must be different from 11 characters) * @param query - ex: "Hello Adele" or https://music.youtube.com/watch?v=abc * @example * const get = await client.get("Hello Adele") * return: * ```json * { * "thumbnails": [ * { * "url": "https://lh3.googleusercontent.com/...", * "width": 60, * "height": 60 * } * ], * "id": "dQw4w9WgXcQ", * "title": "Never Gonna Give You Up", * "artists": [{ * "name": "Rick Astley", * "id": "MPREb_5eN7fQq3J9_" * }], * "resultType": "song", * "videoType": "MUSIC_VIDEO_TYPE_ATV" * // Other properties * } * ``` */ function get(query) { return new Promise((resolve, reject) => { const id = (0, utils_1.getYTIdFromText)(query, true); const req = { url: '', body: {} }; switch (id.type) { case "song": req.url = 'next'; req.body = { videoId: id.id }; break; case "playlist": case "artist": case "album": req.url = 'browse'; req.body = { browseId: id.id }; break; } if (!!req.url) { (0, request_1.default)(req.url, req.body).then((res) => { resolve((0, utils_1.parseGetResult)(res, id.type)); }).catch(reject); } else reject((0, error_1.error)(1006, { query: query, id: id.id, type: id.type })); }); } /** * Get chart music from YouTube Music by country or global * @param country - The country code (Check available countries) */ function charts(country = 'global') { return new Promise((resolve, reject) => { var _a, _b; country = country === null || country === void 0 ? void 0 : country.toUpperCase(); if (!default_1.countries.includes(country) && !default_1.countriesCodes.includes(country)) return reject((0, error_1.error)(1007, `Available countries: ${default_1.countries.join(", ")}`)); (0, request_1.default)('browse', { browseId: (((_a = countries_1.COUNTRIES.find((c) => c.name === country)) === null || _a === void 0 ? void 0 : _a.id) || ((_b = countries_1.COUNTRIES.find((c) => c.codeCountry === country)) === null || _b === void 0 ? void 0 : _b.id)) }).then((res) => { resolve((0, utils_1.parseGetResult)(res, 'charts')); }).catch(reject); }); } /** * Get a Download link of a music * @param query - The music ID or URL * @param format - The format of the music (Check available formats) * @param quality - The quality of the music (Check available qualities) * @example */ function download(query, format = default_1.AvailableFormat[0], quality = default_1.AvailableQuality[0]) { return new Promise((resolve, reject) => { (0, utils_1.downloadYTDL)(query, format, quality).then((res) => { resolve(res); }).catch(reject); }); } /** * getPlayers is a function that returns the available players (music, video) in all qualities * @param query - The music ID or URL */ function getPlayers(query) { return (0, utils_1.getPlayers_dv)((0, utils_1.getYTIdFromText)(query).isValidId ? (0, utils_1.getYTIdFromText)(query).id : query).catch((e) => { throw e; }); } /** * @hideconstructor * @param format - The format of the music (Check available formats) */ function getUrlDecodeT(format) { return new Promise((resolve, reject) => { (0, decode_1.getUrlDecode)(format).then((decoded) => __awaiter(this, void 0, void 0, function* () { return resolve(decoded); })).catch(reject); }); } //# sourceMappingURL=index.js.map