Skip to content

Commit 5390004

Browse files
AI slop
1 parent 11f924e commit 5390004

File tree

1 file changed

+175
-10
lines changed

1 file changed

+175
-10
lines changed

packages/utils/src/media-processor.ts

Lines changed: 175 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export interface MediaProcessor {
6969
getMetadata(): Promise<MediaMetadata>;
7070
convert(options: ConversionOptions): Promise<Uint8Array>;
7171
dispose(): void;
72+
isReady(): boolean;
7273
}
7374

7475
// Formats that Mediabunny typically supports well
@@ -202,16 +203,66 @@ async function loadFFmpegWasm() {
202203
class MediabunnyProcessor implements MediaProcessor {
203204
private input: MediabunnyInput | null = null;
204205
private file: File | null = null;
206+
private mediabunny: any = null;
207+
208+
isReady(): boolean {
209+
return (
210+
this.input !== null && this.file !== null && this.mediabunny !== null
211+
);
212+
}
205213

206214
async loadFile(file: File): Promise<void> {
207-
const mediabunny = await loadMediabunny();
208-
const { Input, BlobSource, ALL_FORMATS } = mediabunny;
215+
console.debug("MediabunnyProcessor: Starting loadFile", {
216+
fileName: file.name,
217+
fileSize: file.size,
218+
fileType: file.type,
219+
});
209220

210-
this.file = file;
211-
this.input = new Input({
212-
source: new BlobSource(file),
213-
formats: ALL_FORMATS,
221+
this.mediabunny = await loadMediabunny();
222+
const { Input, BlobSource, ALL_FORMATS } = this.mediabunny;
223+
224+
console.debug("MediabunnyProcessor: Mediabunny loaded successfully", {
225+
hasInput: !!Input,
226+
hasBlobSource: !!BlobSource,
227+
hasFormats: !!ALL_FORMATS,
214228
});
229+
230+
this.file = file;
231+
232+
try {
233+
const blobSource = new BlobSource(file);
234+
console.debug("MediabunnyProcessor: BlobSource created");
235+
236+
this.input = new Input({
237+
source: blobSource,
238+
formats: ALL_FORMATS,
239+
});
240+
241+
console.debug("MediabunnyProcessor: Input created", {
242+
inputType: typeof this.input,
243+
inputConstructor: this.input?.constructor?.name,
244+
hasInput: !!this.input,
245+
});
246+
247+
// Validate that the input was created properly
248+
if (!this.input || typeof this.input !== "object") {
249+
throw new Error("Failed to create valid Input object");
250+
}
251+
252+
// Additional validation - check if input has expected methods
253+
if (
254+
typeof this.input.getVideoTracks !== "function" ||
255+
typeof this.input.getAudioTracks !== "function"
256+
) {
257+
throw new Error("Input object missing expected methods");
258+
}
259+
} catch (error) {
260+
console.error("MediabunnyProcessor: Failed to create input", error);
261+
this.input = null;
262+
throw new Error(
263+
`Failed to create media input: ${error instanceof Error ? error.message : String(error)}`,
264+
);
265+
}
215266
}
216267

217268
async getMetadata(): Promise<MediaMetadata> {
@@ -248,15 +299,40 @@ class MediabunnyProcessor implements MediaProcessor {
248299
}
249300

250301
async convert(options: ConversionOptions): Promise<Uint8Array> {
302+
console.debug("MediabunnyProcessor: Starting convert", {
303+
outputFormat: options.outputFormat,
304+
hasInput: !!this.input,
305+
inputType: typeof this.input,
306+
inputConstructor: this.input?.constructor?.name,
307+
});
308+
251309
if (!this.input) {
252310
throw new Error("No file loaded");
253311
}
254312

255-
const mediabunny = await loadMediabunny();
256-
const { Output, Conversion, BufferTarget } = mediabunny;
313+
if (!this.mediabunny) {
314+
throw new Error("Mediabunny not initialized");
315+
}
316+
317+
// Additional validation to ensure input is proper
318+
if (typeof this.input !== "object" || this.input === null) {
319+
throw new Error(
320+
"Invalid input object - media file may not be properly loaded",
321+
);
322+
}
323+
const { Output, Conversion, BufferTarget } = this.mediabunny;
324+
325+
console.debug("MediabunnyProcessor: Mediabunny classes available", {
326+
hasOutput: !!Output,
327+
hasConversion: !!Conversion,
328+
hasBufferTarget: !!BufferTarget,
329+
});
257330

258331
// Get appropriate output format
259-
const outputFormat = this.getOutputFormat(options.outputFormat, mediabunny);
332+
const outputFormat = this.getOutputFormat(
333+
options.outputFormat,
334+
this.mediabunny,
335+
);
260336

261337
const target = new BufferTarget();
262338
const output = new Output({
@@ -271,7 +347,36 @@ class MediabunnyProcessor implements MediaProcessor {
271347
output.setVideoSize(options.width, options.height);
272348
if (options.frameRate) output.setVideoFrameRate(options.frameRate);
273349

274-
const conversion = new Conversion(this.input, output);
350+
// Final validation before creating Conversion
351+
if (!this.input || this.input === null || this.input === undefined) {
352+
throw new Error("Input is null or undefined");
353+
}
354+
355+
// Check if input has the expected structure for mediabunny
356+
if (typeof this.input !== "object") {
357+
throw new Error(`Input is not an object, got: ${typeof this.input}`);
358+
}
359+
360+
// Create conversion with proper error handling
361+
let conversion: any;
362+
try {
363+
console.debug("MediabunnyProcessor: Creating Conversion with", {
364+
inputConstructor: this.input.constructor?.name,
365+
outputConstructor: output.constructor?.name,
366+
});
367+
conversion = new Conversion(this.input, output);
368+
} catch (conversionError) {
369+
console.error("MediabunnyProcessor: Conversion creation failed", {
370+
error: conversionError,
371+
inputType: typeof this.input,
372+
inputConstructor: this.input?.constructor?.name,
373+
outputType: typeof output,
374+
outputConstructor: output?.constructor?.name,
375+
});
376+
throw new Error(
377+
`Failed to create conversion: ${conversionError instanceof Error ? conversionError.message : String(conversionError)}. Input type: ${typeof this.input}, Input constructor: ${this.input?.constructor?.name}`,
378+
);
379+
}
275380

276381
// Handle progress updates
277382
if (options.onProgress) {
@@ -336,6 +441,7 @@ class MediabunnyProcessor implements MediaProcessor {
336441
dispose(): void {
337442
this.input = null;
338443
this.file = null;
444+
this.mediabunny = null;
339445
}
340446
}
341447

@@ -345,6 +451,10 @@ class FFmpegProcessor implements MediaProcessor {
345451
private file: File | null = null;
346452
private metadata: MediaMetadata | null = null;
347453

454+
isReady(): boolean {
455+
return this.ffmpeg !== null && this.file !== null;
456+
}
457+
348458
async loadFile(file: File): Promise<void> {
349459
const { FFmpeg, fetchFile, toBlobURL } = await loadFFmpegWasm();
350460

@@ -588,6 +698,12 @@ export async function createMediaProcessor(
588698
try {
589699
const processor = new MediabunnyProcessor();
590700
await processor.loadFile(file);
701+
702+
// Validate processor is properly initialized
703+
if (!processor.isReady()) {
704+
throw new Error("MediabunnyProcessor not properly initialized");
705+
}
706+
591707
return processor;
592708
} catch (error) {
593709
console.warn("Mediabunny failed, falling back to FFmpeg:", error);
@@ -624,6 +740,55 @@ export async function convertMedia(
624740
}
625741
}
626742

743+
// Debug helper function for troubleshooting media processing issues
744+
export async function debugMediaFile(file: File): Promise<{
745+
fileInfo: {
746+
name: string;
747+
size: number;
748+
type: string;
749+
};
750+
mediabunnyAvailable: boolean;
751+
mediabunnyError?: string;
752+
processorCreated: boolean;
753+
processorError?: string;
754+
}> {
755+
const result = {
756+
fileInfo: {
757+
name: file.name,
758+
size: file.size,
759+
type: file.type,
760+
},
761+
mediabunnyAvailable: false,
762+
processorCreated: false,
763+
} as any;
764+
765+
// Test mediabunny availability
766+
try {
767+
const mediabunny = await loadMediabunny();
768+
result.mediabunnyAvailable = true;
769+
console.log("Mediabunny loaded successfully:", {
770+
hasInput: !!mediabunny.Input,
771+
hasBlobSource: !!mediabunny.BlobSource,
772+
hasFormats: !!mediabunny.ALL_FORMATS,
773+
});
774+
} catch (error) {
775+
result.mediabunnyError =
776+
error instanceof Error ? error.message : String(error);
777+
}
778+
779+
// Test processor creation
780+
try {
781+
const processor = await createMediaProcessor(file);
782+
result.processorCreated = processor.isReady();
783+
processor.dispose();
784+
} catch (error) {
785+
result.processorError =
786+
error instanceof Error ? error.message : String(error);
787+
}
788+
789+
return result;
790+
}
791+
627792
// Check if a format combination is supported
628793
export function isFormatSupported(
629794
inputFormat: string,

0 commit comments

Comments
 (0)