feat: add frame production monitoring and auto-stop for failed webcam streams

- Monitor FFmpeg frame output and detect stalled recordings
- Auto-stop after 30s if no frames are produced
- Add stall detection for recordings that stop producing frames
- Provide user feedback when recording fails due to no video data
- Clean up monitoring intervals on recording stop
This commit is contained in:
Mikolaj Wojciech Gorski 2025-07-26 16:39:16 +02:00
parent 1886ea7c94
commit 9470815ad1
2 changed files with 59 additions and 2 deletions

@ -1 +1 @@
Subproject commit 094176414b94e6f01c9460c060834d4bee3be4d7 Subproject commit c1d0b98a487eda0557d29135024d1eb3c72b968d

View file

@ -302,12 +302,64 @@ class WebcamRecordingService {
} }
_setupWebcamStreamHandlers(webcamStream, textChannel, voiceChannelId) { _setupWebcamStreamHandlers(webcamStream, textChannel, voiceChannelId) {
let frameCount = 0;
let lastFrameTime = Date.now();
webcamStream.on("ready", () => { webcamStream.on("ready", () => {
console.log("[Docker] FFmpeg process ready for webcam recording!"); console.log("[Docker] FFmpeg process ready for webcam recording!");
textChannel.send("🎥 Webcam recording started successfully!"); textChannel.send("🎥 Webcam recording started successfully!");
webcamStream.stream.stderr.on("data", (data) => { webcamStream.stream.stderr.on("data", (data) => {
console.log(`[Docker] Webcam FFmpeg: ${data}`); const dataStr = data.toString();
console.log(`[Docker] Webcam FFmpeg: ${dataStr}`);
// Track frame production
const frameMatch = dataStr.match(/frame=\s*(\d+)/);
if (frameMatch) {
frameCount = parseInt(frameMatch[1]);
lastFrameTime = Date.now();
}
}); });
// Monitor for frame production - stop if no frames after 30 seconds
setTimeout(() => {
if (frameCount === 0) {
console.log(
"[Docker] No frames produced after 30 seconds, stopping webcam recording"
);
textChannel.send(
"⚠️ Webcam recording stopped - no video frames were captured. User may not have camera enabled."
);
this.stopRecording(
voiceChannelId,
textChannel,
"🎥 Webcam recording stopped - no frames detected."
);
}
}, 30000);
// Check for stalled recording every 60 seconds
const stallCheckInterval = setInterval(() => {
const timeSinceLastFrame = Date.now() - lastFrameTime;
if (frameCount > 0 && timeSinceLastFrame > 60000) {
console.log(
`[Docker] Webcam recording stalled - no frames for ${timeSinceLastFrame}ms`
);
textChannel.send("⚠️ Webcam recording appears stalled - stopping.");
this.stopRecording(
voiceChannelId,
textChannel,
"🎥 Webcam recording stopped - stream stalled."
);
clearInterval(stallCheckInterval);
}
}, 60000);
// Store interval for cleanup
const recording = activeWebcamRecordings.get(voiceChannelId);
if (recording) {
recording.stallCheckInterval = stallCheckInterval;
}
}); });
webcamStream.on("error", (error) => { webcamStream.on("error", (error) => {
@ -380,6 +432,11 @@ class WebcamRecordingService {
} }
_cleanupRecording(recording) { _cleanupRecording(recording) {
// Clear any monitoring intervals
if (recording.stallCheckInterval) {
clearInterval(recording.stallCheckInterval);
}
// Remove all event listeners first // Remove all event listeners first
if (recording.connection) { if (recording.connection) {
recording.connection.removeAllListeners("startStreaming"); recording.connection.removeAllListeners("startStreaming");