UNPKG

@hunghg255/yt-dlp

Version:

yt-dlp plugin for DisTube.js.org

118 lines (114 loc) 4.63 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // src/wrapper.ts import dargs from "dargs"; import execa from "execa"; import mkdirp from "mkdirp"; import fs from "node:fs/promises"; import { request } from "undici"; // src/env.ts import path from "path"; var e = /* @__PURE__ */ __name((key) => process.env[key], "e"); var YTDLP_DISABLE_DOWNLOAD = !!e("YTDLP_DISABLE_DOWNLOAD"); var YTDLP_URL = e("YTDLP_URL") || "https://api.github.com/repos/yt-dlp/yt-dlp/releases?per_page=1"; var YTDLP_IS_WINDOWS = e("YTDLP_IS_WINDOWS") || process.platform === "win32"; var YTDLP_DIR = e("YTDLP_DIR") || path.join(__dirname, "..", "bin"); var YTDLP_FILENAME = e("YTDLP_FILENAME") || `yt-dlp${YTDLP_IS_WINDOWS ? ".exe" : ""}`; var YTDLP_PATH = path.join(YTDLP_DIR, YTDLP_FILENAME); // src/wrapper.ts var makeRequest = /* @__PURE__ */ __name(async (url) => { const response = await request(url, { headers: { "user-agent": "distube" } }); if (!response.statusCode) throw new Error(`Cannot make requests to '${url}'`); if (response.statusCode.toString().startsWith("3")) { if (!response.headers.location) throw new Error(`Cannot redirect to '${url}'`); for await (const _chunk of response.body) { } return makeRequest(response.headers.location); } if (response.statusCode.toString().startsWith("2")) return response; throw new Error(`${url} Status code ${response.statusCode.toString()}`); }, "makeRequest"); var args = /* @__PURE__ */ __name((url, flags = {}) => [url].concat(dargs(flags, { useEquals: false })).filter(Boolean), "args"); var raw = /* @__PURE__ */ __name((url, flags, options) => execa(YTDLP_PATH, args(url, flags), options), "raw"); var json = /* @__PURE__ */ __name((url, flags, options) => raw(url, flags, options).then(({ stdout }) => JSON.parse(stdout)), "json"); var binContentTypes = ["binary/octet-stream", "application/octet-stream", "application/x-binary"]; var getBinary = /* @__PURE__ */ __name(async (url) => { const response = await makeRequest(url); const contentType = response.headers["content-type"]; if (binContentTypes.includes(contentType ?? "")) return { buffer: await response.body.arrayBuffer(), version: "N/A" }; const [{ assets, tag_name }] = await response.body.json(); const { browser_download_url } = assets.find(({ name }) => name === YTDLP_FILENAME); return await makeRequest(browser_download_url).then(async (r) => ({ buffer: await r.body.arrayBuffer(), version: typeof tag_name === "string" ? tag_name : "N/A" })); }, "getBinary"); var download = /* @__PURE__ */ __name(() => Promise.all([getBinary(YTDLP_URL), mkdirp(YTDLP_DIR)]).then(([{ buffer, version }]) => { fs.writeFile(YTDLP_PATH, Buffer.from(buffer), { mode: 493 }); return version; }), "download"); // src/index.ts import { DisTubeError, ExtractorPlugin, Playlist, Song } from "@hunghg255/distube"; var isPlaylist = /* @__PURE__ */ __name((i) => Array.isArray(i.entries), "isPlaylist"); var YtDlpPlugin = class extends ExtractorPlugin { constructor({ update } = {}) { super(); if (update ?? true) download().catch(() => void 0); } validate() { return true; } async resolve(url, { member, metadata }) { const info = await json(url, { dumpSingleJson: true, noWarnings: true, noCallHome: true, preferFreeFormats: true, skipDownload: true, simulate: true }).catch((e2) => { throw new DisTubeError("YTDLP_ERROR", `${e2.stderr || e2}`); }); if (isPlaylist(info)) { if (info.entries.length === 0) throw new DisTubeError("YTDLP_ERROR", "The playlist is empty"); const playlist = { ...info, source: info.extractor, songs: info.entries.map((i) => new Song(i, { member, source: i.extractor, metadata })) }; return new Playlist(playlist, { member, metadata }); } return new Song(info, { member, source: info.extractor, metadata }); } async getStreamURL(url) { const info = await json(url, { dumpSingleJson: true, noWarnings: true, noCallHome: true, preferFreeFormats: true, skipDownload: true, simulate: true, format: "ba/ba*" }).catch((e2) => { throw new DisTubeError("YTDLP_ERROR", `${e2.stderr || e2}`); }); if (isPlaylist(info)) throw new DisTubeError("YTDLP_ERROR", "Cannot get stream URL of a entire playlist"); return info.url; } }; __name(YtDlpPlugin, "YtDlpPlugin"); export { YtDlpPlugin, download, json, raw }; //# sourceMappingURL=index.mjs.map