nextav/src/lib/transcode/throttler.ts

52 lines
1.4 KiB
TypeScript

import { ChildProcessWithoutNullStreams } from 'child_process';
export class TranscodeThrottler {
private timer?: NodeJS.Timeout;
private encoderPosition = 0;
private playheadPosition = 0;
private userPaused = false;
private ffmpegPaused = false;
constructor(private readonly process: ChildProcessWithoutNullStreams) {}
start(): void {
this.timer = setInterval(() => this.tick(), 1000);
this.timer.unref();
}
stop(): void {
if (this.timer) {
clearInterval(this.timer);
this.timer = undefined;
}
}
updateProgress(stderrLine: string): void {
const match = stderrLine.match(/time=(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?)/);
if (!match) return;
const hours = Number(match[1]);
const minutes = Number(match[2]);
const seconds = Number(match[3]);
this.encoderPosition = hours * 3600 + minutes * 60 + seconds;
}
updateClient(position: number, isPaused: boolean): void {
this.playheadPosition = Math.max(0, position);
this.userPaused = isPaused;
}
private tick(): void {
const gap = this.encoderPosition - this.playheadPosition;
if (!this.ffmpegPaused && !this.userPaused && gap > 60) {
this.process.stdin.write('p\n');
this.ffmpegPaused = true;
return;
}
if (this.ffmpegPaused && (!this.userPaused || gap < 30)) {
this.process.stdin.write('u\n');
this.ffmpegPaused = false;
}
}
}