Skip to content
This repository has been archived by the owner on Nov 11, 2024. It is now read-only.

Commit

Permalink
feat: patch for play-dl strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
Mednoob committed Jul 21, 2024
1 parent 01dbd3e commit 8769a10
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,4 @@ dist
# Rawon cache directories and files
data.json
scripts/
play-dl-fix/
36 changes: 18 additions & 18 deletions index.js
Original file line number Diff line number Diff line change
@@ -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);

Expand Down Expand Up @@ -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, {
Expand All @@ -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")) {
Expand All @@ -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);
Expand All @@ -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 {
Expand All @@ -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`);
Expand All @@ -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...");

Expand Down
14 changes: 14 additions & 0 deletions play-dl-importer/index.d.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}> => {}
};
16 changes: 16 additions & 0 deletions play-dl-importer/index.js
Original file line number Diff line number Diff line change
@@ -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;
30 changes: 16 additions & 14 deletions src/utils/handlers/YTDLUtil.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
/* 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> = T extends Promise<infer U> ? 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<Readable> {
if (streamStrategy === "play-dl") {
const isSoundcloudUrl = checkQuery(url);
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) => {
Expand All @@ -34,23 +36,23 @@ export async function getStream(client: Rawon, url: string): Promise<Readable> {
);

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<BasicYoutubeVideoInfo> {
if (streamStrategy === "play-dl") {
const rawPlayDlVideoInfo = await video_basic_info(url);
const rawPlayDlVideoInfo = await video_basic_info?.(url) as unknown as Unpromisify<ReturnType<NonNullable<typeof video_basic_info>>>;
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
};
}
Expand Down

0 comments on commit 8769a10

Please sign in to comment.