@hunghg255/yt-dlp
Version:
yt-dlp plugin for DisTube.js.org
118 lines (114 loc) • 4.63 kB
JavaScript
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