finally fix race conditions for file progress
uses sse to deliver updates
This commit is contained in:
parent
19613e1bb3
commit
6be6d3b15f
9 changed files with 492 additions and 483 deletions
56
app/services/MediaProcesser.ts
Normal file
56
app/services/MediaProcesser.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
import ffmpeg from 'fluent-ffmpeg';
|
||||
import { progressManager } from './ProgressManager';
|
||||
import { EncodingType, currentEncoding } from '../lib/ffmpeg';
|
||||
|
||||
export class MediaProcessor {
|
||||
static async processVideo(
|
||||
inputPath: string,
|
||||
filename: string,
|
||||
extension: string
|
||||
): Promise<void> {
|
||||
console.log("Starting video processing:", filename); // Debug log
|
||||
|
||||
const outputPath = `uploads/720p-${filename}${extension}`;
|
||||
const outputOptions = [
|
||||
'-vf', 'scale=-2:720',
|
||||
'-c:v', currentEncoding,
|
||||
'-c:a', 'copy',
|
||||
'-pix_fmt', 'yuv420p'
|
||||
];
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ffmpeg()
|
||||
.input(inputPath)
|
||||
.outputOptions(outputOptions)
|
||||
.output(outputPath)
|
||||
.on('progress', (progress) => {
|
||||
console.log("Progress:", progress.percent); // Debug log
|
||||
progressManager.updateProgress({
|
||||
filename: `${filename}${extension}`,
|
||||
progress: progress.percent / 100,
|
||||
status: 'processing'
|
||||
});
|
||||
})
|
||||
.on('end', () => {
|
||||
console.log("Processing complete:", filename); // Debug log
|
||||
progressManager.updateProgress({
|
||||
filename: `${filename}${extension}`,
|
||||
progress: 1,
|
||||
status: 'complete'
|
||||
});
|
||||
resolve();
|
||||
})
|
||||
.on('error', (err) => {
|
||||
console.error("Processing error:", err); // Debug log
|
||||
progressManager.updateProgress({
|
||||
filename: `${filename}${extension}`,
|
||||
progress: 0,
|
||||
status: 'error',
|
||||
message: err.message
|
||||
});
|
||||
reject(err);
|
||||
})
|
||||
.run();
|
||||
});
|
||||
}
|
||||
}
|
45
app/services/ProgressManager.ts
Normal file
45
app/services/ProgressManager.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { EventEmitter } from 'events';
|
||||
|
||||
export interface ProgressUpdate {
|
||||
filename: string;
|
||||
progress: number;
|
||||
status: 'processing' | 'complete' | 'error';
|
||||
message?: string;
|
||||
}
|
||||
|
||||
class ProgressManager {
|
||||
private static instance: ProgressManager;
|
||||
private emitter: EventEmitter;
|
||||
private activeJobs: Map<string, ProgressUpdate>;
|
||||
|
||||
private constructor() {
|
||||
this.emitter = new EventEmitter();
|
||||
this.activeJobs = new Map();
|
||||
}
|
||||
|
||||
static getInstance(): ProgressManager {
|
||||
if (!ProgressManager.instance) {
|
||||
ProgressManager.instance = new ProgressManager();
|
||||
}
|
||||
return ProgressManager.instance;
|
||||
}
|
||||
|
||||
updateProgress(update: ProgressUpdate) {
|
||||
this.activeJobs.set(update.filename, update);
|
||||
this.emitter.emit('progress', update);
|
||||
}
|
||||
|
||||
subscribeToUpdates(callback: (update: ProgressUpdate) => void) {
|
||||
this.emitter.on('progress', callback);
|
||||
}
|
||||
|
||||
unsubscribeFromUpdates(callback: (update: ProgressUpdate) => void) {
|
||||
this.emitter.off('progress', callback);
|
||||
}
|
||||
|
||||
getJobStatus(filename: string): ProgressUpdate | undefined {
|
||||
return this.activeJobs.get(filename);
|
||||
}
|
||||
}
|
||||
|
||||
export const progressManager = ProgressManager.getInstance();
|
Loading…
Add table
Add a link
Reference in a new issue