debug: yt-dlp/ffmpeg capture stderr'ını GET /debug/capture/:sessionId ile görünür kıl
İlk gerçek capture denemesi 2 saniyede sessionı bitirdi (0 segment) — Coolify /logs endpoint'i api-daemon'un stdout'unu güvenilir şekilde izole edemediği için sebebi göremedik. Artık her session'ın son yt-dlp/ffmpeg stderr satırları bellekte tutulup HTTP'den okunabiliyor. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,20 @@ import { ytdlpAntiBotArgs } from "../ytdlpCookies";
|
|||||||
|
|
||||||
const SEGMENT_LIST_POLL_MS = 5_000;
|
const SEGMENT_LIST_POLL_MS = 5_000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Coolify's /logs endpoint can't reliably isolate one docker-compose
|
||||||
|
* service's stdout, so the last capture attempt's yt-dlp/ffmpeg stderr tail
|
||||||
|
* is kept here and surfaced via GET /status for debugging.
|
||||||
|
*/
|
||||||
|
export const lastCaptureDebug = new Map<string, string[]>();
|
||||||
|
|
||||||
|
function appendCaptureDebug(sessionId: string, line: string) {
|
||||||
|
const lines = lastCaptureDebug.get(sessionId) ?? [];
|
||||||
|
lines.push(line);
|
||||||
|
if (lines.length > 40) lines.shift();
|
||||||
|
lastCaptureDebug.set(sessionId, lines);
|
||||||
|
}
|
||||||
|
|
||||||
interface SegmentListEntry {
|
interface SegmentListEntry {
|
||||||
fileName: string;
|
fileName: string;
|
||||||
startSec: number;
|
startSec: number;
|
||||||
@@ -97,9 +111,16 @@ async function runCapture(job: Job<StreamIngestJob>): Promise<void> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
ytdlp.stdout.pipe(ffmpeg.stdin);
|
ytdlp.stdout.pipe(ffmpeg.stdin);
|
||||||
ytdlp.stderr.on("data", (chunk) => console.error(`[yt-dlp:${sessionId}]`, chunk.toString().trim()));
|
ytdlp.on("error", (err) => appendCaptureDebug(sessionId, `[yt-dlp spawn error] ${err.message}`));
|
||||||
ffmpeg.stderr.on("data", () => {
|
ytdlp.stderr.on("data", (chunk) => {
|
||||||
/* ffmpeg logs are extremely verbose; only surface on error below */
|
const text = chunk.toString().trim();
|
||||||
|
console.error(`[yt-dlp:${sessionId}]`, text);
|
||||||
|
appendCaptureDebug(sessionId, `[yt-dlp] ${text}`);
|
||||||
|
});
|
||||||
|
ffmpeg.on("error", (err) => appendCaptureDebug(sessionId, `[ffmpeg spawn error] ${err.message}`));
|
||||||
|
ffmpeg.stderr.on("data", (chunk) => {
|
||||||
|
/* ffmpeg logs are extremely verbose; keep only the tail for debugging */
|
||||||
|
appendCaptureDebug(sessionId, `[ffmpeg] ${chunk.toString().trim().split("\n").pop()}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
let lastProcessedIndex = 0;
|
let lastProcessedIndex = 0;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import express from "express";
|
|||||||
import { prisma } from "@streamclipper/db";
|
import { prisma } from "@streamclipper/db";
|
||||||
import { env } from "./env";
|
import { env } from "./env";
|
||||||
import { lastPollErrors } from "./youtubePolling";
|
import { lastPollErrors } from "./youtubePolling";
|
||||||
|
import { lastCaptureDebug } from "./capture/streamIngest";
|
||||||
|
|
||||||
export function startServer() {
|
export function startServer() {
|
||||||
const app = express();
|
const app = express();
|
||||||
@@ -32,6 +33,10 @@ export function startServer() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get("/debug/capture/:sessionId", (req, res) => {
|
||||||
|
res.json({ lines: lastCaptureDebug.get(req.params.sessionId) ?? [] });
|
||||||
|
});
|
||||||
|
|
||||||
app.listen(env.port, () => {
|
app.listen(env.port, () => {
|
||||||
console.log(`[server] api-daemon listening on :${env.port}`);
|
console.log(`[server] api-daemon listening on :${env.port}`);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user