File size: 1,854 Bytes
d092f57 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
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)
}
|