Spaces:
Sleeping
Sleeping
| import { NextApiRequest, NextApiResponse } from "next" | |
| import { isUrl, shellSanitizeUrl } from "../../lib/utils" | |
| import { exec, ExecException } from "child_process" | |
| import * as util from "util" | |
| const asyncExec = util.promisify(exec) | |
| const memoizeExtractFromUrl = () => { | |
| let cache: Record<string, any> = {} | |
| return async (url: string) => { | |
| if (url in cache) { | |
| const cached = cache[url] | |
| if (cached.pending) { | |
| return true | |
| } | |
| return cache[url] | |
| } | |
| if (!isUrl(url)) { | |
| console.error("Invalid url provided to source video from:", url) | |
| cache[url] = { | |
| error: true, | |
| stdout: "", | |
| stderr: "Invalid url", | |
| } | |
| return cache[url] | |
| } | |
| try { | |
| cache[url] = await asyncExec("yt-dlp -g " + url) | |
| } catch (error) { | |
| const e = error as ExecException | |
| console.error("Extraction failed", e) | |
| cache[url] = { | |
| error: true, | |
| stdout: "", | |
| stderr: e.message, | |
| } | |
| } | |
| return cache[url] | |
| } | |
| } | |
| const extractFromUrl = memoizeExtractFromUrl() | |
| const handleResult = async (url: string, res: NextApiResponse) => { | |
| const result = await extractFromUrl(url) | |
| // already pending? | |
| if (result === true) { | |
| setTimeout(async () => { | |
| await handleResult(url, res) | |
| }, 100) | |
| return | |
| } | |
| if (result.error) { | |
| console.error(`exec error: ${result.error}`) | |
| return res.status(500).send(result.stderr.replace("\n", "")) | |
| } | |
| res.json({ | |
| stdout: result.stdout, | |
| stderr: result.stderr.replace("\n", ""), | |
| }) | |
| } | |
| export default async function source( | |
| req: NextApiRequest, | |
| res: NextApiResponse | |
| ) { | |
| const url = shellSanitizeUrl(req.body) | |
| if (!isUrl(url)) { | |
| return res.status(400).send("Invalid url") | |
| } | |
| console.log("Requested video source of", req.body, "sanitized", url) | |
| await handleResult(url, res) | |
| } | |