error handling
Some checks failed
Build Docker Image / docker (push) Has been cancelled
Test / test (push) Has been cancelled

This commit is contained in:
Lillith Rose (Device: Lucia) 2025-06-09 23:33:08 -04:00
parent a1a7f664e9
commit e9d9255495

View file

@ -1,53 +1,70 @@
import ffmpeg from "fluent-ffmpeg"; import ffmpeg from "fluent-ffmpeg";
import fs from "fs";
import path from "path";
import { Event, getCurrentEvent, loadEvents } from "setlist"; import { Event, getCurrentEvent, loadEvents } from "setlist";
const commandBase = ffmpeg() const STREAM_URL = "rtsp://stream.furality.online/live/club";
.input("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") .seekInput("0:01")
.audioCodec("copy")
.videoCodec("copy") .videoCodec("copy")
.outputOption("-y"); .audioCodec("copy")
.format("mpegts")
.duration(duration);
}
async function runCommand(event: Event) { async function runCommand(event: Event) {
const eventEnd = new Date(event.end); const eventEnd = new Date(event.end);
const filename = event.name.replace(/ /g, "_");
const filepath = getFilename(filename);
while (true) {
const now = new Date(); const now = new Date();
const secondsUntilEventEnd = Math.max( const secondsLeft = Math.max(
0, 0,
Math.floor((eventEnd.getTime() - now.getTime()) / 1000) Math.floor((eventEnd.getTime() - now.getTime()) / 1000)
); );
const command = commandBase.clone().duration(secondsUntilEventEnd); if (secondsLeft <= 0) break;
const filename = event.name.replace(/ /g, "_"); console.log(`Recording ${secondsLeft}s to ${filepath}`);
console.log(`Saving ${secondsUntilEventEnd}s of 1440p to ${filename}.mkv`); const cmd = createCommand(secondsLeft);
console.log(process.cwd()); const writeStream = fs.createWriteStream(filepath, { flags: "a" }); // Append mode
command.save(`./output/${filename}.mkv`);
await new Promise<void>((res) => { try {
// command.on("start", console.log); await new Promise((res, rej) => {
command.on("error", (err) => { cmd.on("error", rej);
throw err; cmd.on("end", res);
cmd.pipe(writeStream);
}); });
command.on("end", (cmd) => { break;
console.log(cmd); } catch (err) {
res(); console.error("FFmpeg crashed, retrying in 5s:", err);
}); await new Promise((r) => setTimeout(r, 5000));
}); }
console.log("Command Done"); }
console.log("Recording finished.");
} }
async function main() { async function main() {
while (true) { while (true) {
await loadEvents(); await loadEvents();
// find next
const event = getCurrentEvent(); const event = getCurrentEvent();
if (!event?.name) { if (!event?.name) {
console.error("No more sets!"); console.log("No current event.");
process.exit(0); await new Promise((res) => setTimeout(res, 10000));
continue;
} }
await runCommand(event); await runCommand(event);
// sleep 5s
await new Promise((res) => setTimeout(res, 5000));
} }
} }