From 67780503cc062f1df2a3d3fb453c368ce9667e9b Mon Sep 17 00:00:00 2001 From: Mednoob Date: Sun, 21 Jul 2024 20:58:13 +0900 Subject: [PATCH] feat: patch for play-dl strategy --- .gitignore | 1 + index.js | 36 +++++++++++++++++----------------- play-dl-importer/index.d.ts | 14 +++++++++++++ play-dl-importer/index.js | 16 +++++++++++++++ src/utils/handlers/YTDLUtil.ts | 30 +++++++++++++++------------- 5 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 play-dl-importer/index.d.ts create mode 100644 play-dl-importer/index.js diff --git a/.gitignore b/.gitignore index e40fc1d89..8a731f1b1 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,4 @@ dist # Rawon cache directories and files data.json scripts/ +play-dl-fix/ diff --git a/index.js b/index.js index 76b20f75c..690dc8fcd 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,11 @@ -import { downloadExecutable } from "./yt-dlp-utils/index.js"; -import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +/* eslint-disable node/no-sync */ import { execSync } from "node:child_process"; -import { resolve } from "node:path"; +import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs"; import { Server } from "node:http"; -import module from "node:module"; +import nodePath from "node:path"; +import process from "node:process"; import prism from "prism-media"; +import { downloadExecutable } from "./yt-dlp-utils/index.js"; const ensureEnv = arr => arr.every(x => process.env[x] !== undefined); @@ -36,7 +37,7 @@ const isGitHub = ensureEnv([ function npmInstall(deleteDir = false, forceInstall = false, additionalArgs = []) { if (deleteDir) { - const modulesPath = resolve(process.cwd(), "node_modules"); + const modulesPath = nodePath.resolve(process.cwd(), "node_modules"); if (existsSync(modulesPath)) { rmSync(modulesPath, { @@ -50,7 +51,7 @@ function npmInstall(deleteDir = false, forceInstall = false, additionalArgs = [] } if (isGlitch) { - const gitIgnorePath = resolve(process.cwd(), ".gitignore"); + const gitIgnorePath = nodePath.resolve(process.cwd(), ".gitignore"); try { const data = readFileSync(gitIgnorePath, "utf8").toString(); if (data.includes("dev.env")) { @@ -65,7 +66,7 @@ if (isGlitch) { console.info("[INFO] Trying to re-install modules..."); npmInstall(); console.info("[INFO] Modules successfully re-installed."); - } catch (err) { + } catch { console.info("[INFO] Failed to re-install modules, trying to delete node_modules and re-install..."); try { npmInstall(true); @@ -86,8 +87,6 @@ if (isGitHub) { console.warn("[WARN] Running this bot using GitHub is not recommended."); } -const require = module.createRequire(import.meta.url); - try { prism.FFmpeg.getInfo(true); } catch { @@ -100,7 +99,7 @@ if (isGlitch || isReplit) { new Server((req, res) => { const now = new Date().toLocaleString("en-US"); res.end(`OK (200) - ${now}`); - }).listen(Number(process.env.PORT || 3000) || 3000); + }).listen(Number(process.env.PORT || 3_000) || 3_000); console.info(`[INFO] ${isGlitch ? "Glitch" : "Replit"} environment detected, trying to compile...`); execSync(`npm run compile`); @@ -109,14 +108,15 @@ if (isGlitch || isReplit) { const streamStrategy = process.env.STREAM_STRATEGY; if (streamStrategy !== "play-dl") await downloadExecutable(); -if (streamStrategy === "play-dl") { - try { - require("play-dl"); - } catch { - console.info("[INFO] Installing play-dl..."); - npmInstall(false, false, ["play-dl"]); - console.info("[INFO] Play-dl has been installed."); - } +if (streamStrategy === "play-dl" && !existsSync(nodePath.resolve(process.cwd(), "play-dl-fix"))) { + console.log("[INFO] Cloning play-dl fix..."); + execSync("git clone https://github.com/YuzuZensai/play-dl-test.git play-dl-fix && cd play-dl-fix && git reset --hard 2bfbfe6"); + + console.log("[INFO] Installing packages for play-dl..."); + execSync("cd play-dl-fix && npm install"); + + console.log("[INFO] Compiling play-dl..."); + execSync("cd play-dl-fix && npm run build"); } console.info("[INFO] Starting the bot..."); diff --git a/play-dl-importer/index.d.ts b/play-dl-importer/index.d.ts new file mode 100644 index 000000000..9429a323e --- /dev/null +++ b/play-dl-importer/index.d.ts @@ -0,0 +1,14 @@ +import { Readable } from "node:stream"; + +export default { + stream: async (url: string, options: { discordPlayerCompatibility: boolean }): Promise<{ stream: Readable }> => {}, + video_basic_info: async (url: string): Promise<{ + video_details: { + durationInSec: number; + id: string | null; + thumbnails: { url: string; width: number; height: number }[]; + title: string | null; + url: string; + } + }> => {} +}; diff --git a/play-dl-importer/index.js b/play-dl-importer/index.js new file mode 100644 index 000000000..818693931 --- /dev/null +++ b/play-dl-importer/index.js @@ -0,0 +1,16 @@ +import { existsSync } from "node:fs"; +import module from "node:module"; +import nodePath from "node:path"; +import { fileURLToPath } from "node:url"; + +// eslint-disable-next-line import/no-mutable-exports +let mod; + +if (existsSync(nodePath.resolve(fileURLToPath(import.meta.url), "..", "..", "play-dl-fix"))) { + mod = await import("../play-dl-fix/dist/index.mjs"); +} else { + const require = module.createRequire(nodePath.resolve(fileURLToPath(import.meta.url), "..")); + mod = require("play-dl"); +} + +export default mod; diff --git a/src/utils/handlers/YTDLUtil.ts b/src/utils/handlers/YTDLUtil.ts index eebeb16dc..3dd76467f 100644 --- a/src/utils/handlers/YTDLUtil.ts +++ b/src/utils/handlers/YTDLUtil.ts @@ -1,13 +1,15 @@ -/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/naming-convention */ -import { BasicYoutubeVideoInfo } from "../../typings/index.js"; +/* eslint-disable unicorn/filename-case */ +/* eslint-disable typescript/naming-convention */ +import type { Readable } from "node:stream"; import ytdl, { exec } from "../../../yt-dlp-utils/index.js"; import { streamStrategy } from "../../config/index.js"; -import { Rawon } from "../../structures/Rawon.js"; +import type { Rawon } from "../../structures/Rawon.js"; +import type { BasicYoutubeVideoInfo } from "../../typings/index.js"; import { checkQuery } from "./GeneralUtil.js"; -import { Readable } from "node:stream"; -// @ts-expect-error play-dl is optional -const { stream: pldlStream, video_basic_info } = await import("play-dl").catch(() => ({ stream: null, video_basic_info: null })); +type Unpromisify = T extends Promise ? U : T; + +const { stream: pldlStream, video_basic_info } = await import("../../../play-dl-importer/index.js").then(x => x.default).catch(() => ({ stream: null, video_basic_info: null })); export async function getStream(client: Rawon, url: string): Promise { if (streamStrategy === "play-dl") { @@ -15,8 +17,8 @@ export async function getStream(client: Rawon, url: string): Promise { if (isSoundcloudUrl.sourceType === "soundcloud") { return client.soundcloud.util.streamTrack(url) as unknown as Readable; } - const rawPlayDlStream = await pldlStream(url, { discordPlayerCompatibility: true }); - return rawPlayDlStream.stream; + const rawPlayDlStream = await pldlStream?.(url, { discordPlayerCompatibility: true }); + return rawPlayDlStream?.stream as unknown as Readable; } return new Promise((resolve, reject) => { @@ -34,23 +36,23 @@ export async function getStream(client: Rawon, url: string): Promise { ); if (!stream.stdout) { - reject(Error("Unable to retrieve audio data from the URL.")); + reject(new Error("Unable to retrieve audio data from the URL.")); } void stream.on("spawn", () => { - resolve(stream.stdout!); + resolve(stream.stdout as unknown as Readable); }); }); } export async function getInfo(url: string): Promise { if (streamStrategy === "play-dl") { - const rawPlayDlVideoInfo = await video_basic_info(url); + const rawPlayDlVideoInfo = await video_basic_info?.(url) as unknown as Unpromisify>>; return { - duration: rawPlayDlVideoInfo.video_details.durationInSec * 1000, - id: rawPlayDlVideoInfo.video_details.id!, + duration: rawPlayDlVideoInfo.video_details.durationInSec * 1_000, + id: rawPlayDlVideoInfo.video_details.id ?? "", thumbnails: rawPlayDlVideoInfo.video_details.thumbnails, - title: rawPlayDlVideoInfo.video_details.title!, + title: rawPlayDlVideoInfo.video_details.title ?? "", url: rawPlayDlVideoInfo.video_details.url }; }