| | 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) |
| | |
| | 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) |
| | } |
| |
|