Skip to content

Commit 344cc98

Browse files
committed
Replace bun spawn with node child_process and update process handling
1 parent 8444515 commit 344cc98

1 file changed

Lines changed: 44 additions & 66 deletions

File tree

src/utils/yt-dlp.ts

Lines changed: 44 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import crypto from "node:crypto";
66
import got from "got";
77
import { YTFlags } from "../@types/index.js";
88
import logger from "./logger.js";
9-
import { spawn } from "bun";
9+
import { spawn } from "node:child_process";
1010

1111
let determinedFilename: string;
1212
const platform = process.platform;
@@ -90,49 +90,42 @@ export async function downloadExecutable() {
9090
}
9191

9292
export function exec(url: string, options: Partial<YTFlags> = {}, spawnOptions: Record<string, any> = {}) {
93-
return spawn([exePath, ...args(url, options)], {
93+
return spawn(exePath, args(url, options), {
9494
windowsHide: true,
9595
...spawnOptions,
9696
stdio: ["ignore", "pipe", "pipe"]
9797
});
9898
}
9999

100100
export default async function ytdl(url: string, options: Partial<YTFlags> = {}, spawnOptions: Record<string, any> = {}) {
101-
let data = "";
102-
let errorData = "";
103-
104-
const proc = exec(url, options, spawnOptions);
101+
return new Promise((resolve, reject) => {
102+
let data = "";
103+
let errorData = "";
105104

106-
if (proc.stdout) {
107-
const reader = proc.stdout.getReader();
108-
const decoder = new TextDecoder();
109-
let result = await reader.read();
110-
while (!result.done) {
111-
data += decoder.decode(result.value, { stream: true });
112-
result = await reader.read();
113-
}
114-
data += decoder.decode();
115-
}
105+
const proc = exec(url, options, spawnOptions);
116106

117-
if (proc.stderr) {
118-
const reader = proc.stderr.getReader();
119-
const decoder = new TextDecoder();
120-
let result = await reader.read();
121-
while (!result.done) {
122-
errorData += decoder.decode(result.value, { stream: true });
123-
result = await reader.read();
124-
}
125-
errorData += decoder.decode();
126-
}
107+
proc.stdout?.on('data', (chunk) => {
108+
data += chunk.toString();
109+
});
127110

128-
const exitCode = await proc.exited;
111+
proc.stderr?.on('data', (chunk) => {
112+
errorData += chunk.toString();
113+
});
129114

130-
if (exitCode !== 0) {
131-
logger.error(`yt-dlp process exited with code ${exitCode}. Stderr: ${errorData}`);
132-
throw new Error(`yt-dlp failed with exit code ${exitCode}: ${errorData || data}`);
133-
}
115+
proc.on('close', (exitCode) => {
116+
if (exitCode !== 0) {
117+
logger.error(`yt-dlp process exited with code ${exitCode}. Stderr: ${errorData}`);
118+
reject(new Error(`yt-dlp failed with exit code ${exitCode}: ${errorData || data}`));
119+
} else {
120+
resolve(json(data));
121+
}
122+
});
134123

135-
return json(data);
124+
proc.on('error', (error) => {
125+
logger.error(`yt-dlp process error:`, error);
126+
reject(error);
127+
});
128+
});
136129
}
137130

138131
export async function downloadToTempFile(url: string, options: Partial<YTFlags> = {}): Promise<string> {
@@ -149,24 +142,20 @@ export async function downloadToTempFile(url: string, options: Partial<YTFlags>
149142
noWarnings: true,
150143
};
151144

152-
const proc = spawn([exePath, ...args(url, downloadOptions)], {
145+
const proc = spawn(exePath, args(url, downloadOptions), {
153146
windowsHide: true,
154147
stdio: ["ignore", "ignore", "pipe"]
155148
});
156149

157150
let errorData = "";
158-
if (proc.stderr) {
159-
const reader = proc.stderr.getReader();
160-
const decoder = new TextDecoder();
161-
let result = await reader.read();
162-
while (!result.done) {
163-
errorData += decoder.decode(result.value, { stream: true });
164-
result = await reader.read();
165-
}
166-
errorData += decoder.decode();
167-
}
151+
proc.stderr?.on('data', (chunk) => {
152+
errorData += chunk.toString();
153+
});
168154

169-
const exitCode = await proc.exited;
155+
const exitCode = await new Promise<number>((resolve) => {
156+
proc.on('close', (code) => resolve(code || 0));
157+
proc.on('error', () => resolve(1));
158+
});
170159

171160
if (exitCode !== 0) {
172161
if (existsSync(tempFilePath)) {
@@ -194,36 +183,25 @@ export async function downloadToTempFile(url: string, options: Partial<YTFlags>
194183
export async function checkForUpdatesAndUpdate(): Promise<void> {
195184
try {
196185
await downloadExecutable();
197-
const updateProc = spawn([exePath, "--update"], {
186+
const updateProc = spawn(exePath, ["--update"], {
198187
stdio: ["ignore", "pipe", "pipe"],
199188
});
200189

201190
let stdoutData = "";
202191
let stderrData = "";
203192

204-
if (updateProc.stdout) {
205-
const stdoutReader = updateProc.stdout.getReader();
206-
const decoder = new TextDecoder();
207-
let result = await stdoutReader.read();
208-
while (!result.done) {
209-
stdoutData += decoder.decode(result.value, { stream: true });
210-
result = await stdoutReader.read();
211-
}
212-
stdoutData += decoder.decode();
213-
}
193+
updateProc.stdout?.on('data', (chunk) => {
194+
stdoutData += chunk.toString();
195+
});
214196

215-
if (updateProc.stderr) {
216-
const stderrReader = updateProc.stderr.getReader();
217-
const decoder = new TextDecoder();
218-
let result = await stderrReader.read();
219-
while (!result.done) {
220-
stderrData += decoder.decode(result.value, { stream: true });
221-
result = await stderrReader.read();
222-
}
223-
stderrData += decoder.decode();
224-
}
197+
updateProc.stderr?.on('data', (chunk) => {
198+
stderrData += chunk.toString();
199+
});
225200

226-
const exitCode = await updateProc.exited;
201+
const exitCode = await new Promise<number>((resolve) => {
202+
updateProc.on('close', (code) => resolve(code || 0));
203+
updateProc.on('error', () => resolve(1));
204+
});
227205

228206
if (exitCode === 0) {
229207
if (stdoutData.includes("Updated yt-dlp to")) {

0 commit comments

Comments
 (0)