import { Config } from "./config.ts"; const ws = new WebSocket(Deno.args[0]) // deno-lint-ignore no-unused-vars let config: Config = {} as unknown as Config const supported = [ "youtube-channel-info" ] function key_to_url(key: string): string { const [kind, id] = key.split(":", 2) if (kind == "youtube-channel-info") return `https://youtube.com/channel/${id}` throw new Error(`unknown kind ${kind}`); } async function dfile(path: string, url: string) { console.log(`thumbnail download ${path} from ${url}`); const r = await fetch(url) if (!r.body) return console.error("thumbnail download failed"); await Deno.writeFile(path, new Uint8Array(await r.arrayBuffer())) } async function save_infojson(url: string, key: string, data: { [key: string]: unknown }) { if (!data.output) throw new Error("output dir missing"); const output = data.output const infojson = `${output}/channel.info.json`; const o = await new Deno.Command("yt-dlp", { args: [ "--skip-download", "--write-info-json", "-o", `${output}/channel`, "--playlist-items", "0", url ], stdout: "piped", stderr: "inherit", }).output() if (!o.success) throw new Error("info json download failed"); ws.send(JSON.stringify({ t: "metadata", key, data: { progress: 0.5 } })) const oj = JSON.parse(await Deno.readTextFile(infojson)) const avatar = oj.thumbnails?.find((t: { id: string }) => t.id == "avatar_uncropped") ?? oj?.thumbnails?.[oj.thumbnails?.length - 1] const banner = oj.thumbnails?.find((t: { id: string }) => t.id == "banner_uncropped") if (avatar) await dfile(`${output}/poster.jpeg`, avatar.url) ws.send(JSON.stringify({ t: "metadata", key, data: { progress: 0.75 } })) if (banner) await dfile(`${output}/backdrop.jpeg`, banner.url) ws.send(JSON.stringify({ t: "metadata", key, data: { progress: 1 } })) } ws.onerror = () => console.error("ws error") ws.onclose = () => { console.error("ws closed") Deno.exit(1) } ws.onopen = () => { console.log("ws open"); ws.send(JSON.stringify({ t: "register", name: "yt-dlp channel info generator", task_kinds: supported })) ws.send(JSON.stringify({ t: "accept" })) } ws.onmessage = async ev => { if (typeof ev.data != "string") return const p = JSON.parse(ev.data) if (p.t == "config") config = p.config if (p.t == "error") console.error(`error: ${p.message}`); if (p.t == "work") { const url = key_to_url(p.key) if (!p.data.output) throw new Error("no output"); console.log(`got work ${p.key}`); await save_infojson(url, p.key, p.data) ws.send(JSON.stringify({ t: "complete", key: p.key })) ws.send(JSON.stringify({ t: "save" })) ws.send(JSON.stringify({ t: "accept" })) } }