From e9d92554950277b6ecff86e999d28ed0badd3d63 Mon Sep 17 00:00:00 2001 From: "Lillith Rose (Device: Lucia)" Date: Mon, 9 Jun 2025 23:33:08 -0400 Subject: [PATCH] error handling --- src/index.ts | 83 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/src/index.ts b/src/index.ts index 62af8bc..d143784 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,53 +1,70 @@ import ffmpeg from "fluent-ffmpeg"; +import fs from "fs"; +import path from "path"; import { Event, getCurrentEvent, loadEvents } from "setlist"; -const commandBase = ffmpeg() - .input("rtsp://stream.furality.online/live/club") - .seekInput("0:01") - .audioCodec("copy") - .videoCodec("copy") - .outputOption("-y"); +const STREAM_URL = "rtsp://stream.furality.online/live/club"; +const OUTPUT_DIR = "./output"; + +function getFilename(base: string) { + return path.resolve(`${OUTPUT_DIR}/${base}.ts`); +} + +function createCommand(duration: number) { + return ffmpeg() + .input(STREAM_URL) + .inputOptions("-rtsp_transport", "tcp") + .seekInput("0:01") + .videoCodec("copy") + .audioCodec("copy") + .format("mpegts") + .duration(duration); +} async function runCommand(event: Event) { const eventEnd = new Date(event.end); - const now = new Date(); - const secondsUntilEventEnd = Math.max( - 0, - Math.floor((eventEnd.getTime() - now.getTime()) / 1000) - ); - const command = commandBase.clone().duration(secondsUntilEventEnd); - const filename = event.name.replace(/ /g, "_"); + const filepath = getFilename(filename); - console.log(`Saving ${secondsUntilEventEnd}s of 1440p to ${filename}.mkv`); - console.log(process.cwd()); - command.save(`./output/${filename}.mkv`); - await new Promise((res) => { - // command.on("start", console.log); - command.on("error", (err) => { - throw err; - }); - command.on("end", (cmd) => { - console.log(cmd); - res(); - }); - }); - console.log("Command Done"); + while (true) { + const now = new Date(); + const secondsLeft = Math.max( + 0, + Math.floor((eventEnd.getTime() - now.getTime()) / 1000) + ); + if (secondsLeft <= 0) break; + + console.log(`Recording ${secondsLeft}s to ${filepath}`); + + const cmd = createCommand(secondsLeft); + const writeStream = fs.createWriteStream(filepath, { flags: "a" }); // Append mode + + try { + await new Promise((res, rej) => { + cmd.on("error", rej); + cmd.on("end", res); + cmd.pipe(writeStream); + }); + break; + } catch (err) { + console.error("FFmpeg crashed, retrying in 5s:", err); + await new Promise((r) => setTimeout(r, 5000)); + } + } + + console.log("Recording finished."); } async function main() { while (true) { await loadEvents(); - // find next const event = getCurrentEvent(); if (!event?.name) { - console.error("No more sets!"); - process.exit(0); + console.log("No current event."); + await new Promise((res) => setTimeout(res, 10000)); + continue; } await runCommand(event); - - // sleep 5s - await new Promise((res) => setTimeout(res, 5000)); } }