From 290c6d2f7098b924db8f2f6316b294329de894c1 Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 11 Mar 2026 18:10:18 +0300 Subject: [PATCH] fix: allow conversions if 1/(x) isn't ready nicer logging for mediabunny discarded tracks, fix multiple converters of same category not keeping its colour --- messages/en.json | 4 +- src/lib/converters/mediabunny.svelte.ts | 22 ++++++++-- src/routes/convert/+page.svelte | 54 +++++++++++++++---------- 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/messages/en.json b/messages/en.json index 66262eb..79fc6ae 100644 --- a/messages/en.json +++ b/messages/en.json @@ -182,7 +182,8 @@ "worker_timeout": "The {type} converter is taking longer than expected to initialize, please wait a few more moments or refresh the page.", "audio": "audio", "doc": "document", - "image": "image" + "image": "image", + "video": "video" } }, "settings": { @@ -344,6 +345,7 @@ "pandoc": "Error loading Pandoc worker, document conversion may not work as expected.", "mediabunny_init": "Error loading Mediabunny, video conversion may not work as expected.", "mediabunny_webcodecs": "Some WebCodecs APIs are not supported in this browser, video conversion may not work as expected.", + "mediabunny_discarded": "Mediabunny discarded {count} track(s) for {file}. See the browser console for details.", "no_audio": "No audio stream found.", "invalid_rate": "Invalid sample rate specified: {rate}Hz", "file_too_large": "This file exceeds the {limit}GB browser / device limit. Try Firefox or Safari to convert this large file, which typically have higher limits." diff --git a/src/lib/converters/mediabunny.svelte.ts b/src/lib/converters/mediabunny.svelte.ts index 0400104..b354ea2 100644 --- a/src/lib/converters/mediabunny.svelte.ts +++ b/src/lib/converters/mediabunny.svelte.ts @@ -225,7 +225,7 @@ export class MediabunnyConverter extends Converter { // additional mediabunny coders // currently the official ones -- maybe add our own in the future this.initializeCodecs(); - + // checks if mediabunny and webcodecs are initialized and supported this.checkStatus(); } @@ -504,10 +504,24 @@ export class MediabunnyConverter extends Converter { this.log(`videoConfig: ${JSON.stringify(videoConfig)}`); this.log(`audioConfig: ${JSON.stringify(audioConfig)}`); - for (const discarded of conversion.discardedTracks) { + // log any discarded tracks & its reasons + const discardedTracks = conversion.discardedTracks; + if (discardedTracks.length > 0) { + const discardedTrackCount = discardedTracks.length; + const discardedTrackList = discardedTracks.map( + (discarded, index) => + `${index + 1}. ${discarded.track.type} (${discarded.track.codec}) - ${discarded.reason}`, + ); + + const isValid = conversion.isValid; + const logMethod = isValid ? this.error : this.log; + logMethod(`${discardedTrackCount} discarded track(s) for ${file.name}:\n${discardedTrackList.join("\n")}`); ToastManager.add({ - type: "error", - message: `Mediabunny discarded ${discarded.track.type} track ${discarded.track.id} (${discarded.track.codec}) for reason: ${discarded.reason}`, + type: isValid ? "warning" : "error", // warning if output created, error if nothing / conversion was completely invalid + message: m["workers.errors.mediabunny_discarded"]({ + count: discardedTrackCount, + file: file.name, + }), durations: { stay: 10000, }, diff --git a/src/routes/convert/+page.svelte b/src/routes/convert/+page.svelte index 257fe04..a77555d 100644 --- a/src/routes/convert/+page.svelte +++ b/src/routes/convert/+page.svelte @@ -51,7 +51,11 @@ if (selectedConverter) return selectedConverter; } - return file.isZip() ? file.converters[0] : file.findConverters()[0]; + // prefer a usable converter over a not-ready one + const readyConverter = availableConverters.find( + (c) => c.status === "ready" || c.status === "partially-ready", + ); + return readyConverter ?? availableConverters[0]; }; $effect(() => { @@ -123,28 +127,35 @@ $effect(() => { // Set gradient color depending on the file types - let type = ""; - if (files.files.length) { - const converters = files.files.map( - (file) => getCurrentConverter(file)?.name, + const fileTypes = files.files + .map((file) => { + const converterName = getCurrentConverter(file)?.name; + if (!converterName) return null; + if (converterCategories.image.includes(converterName)) + return "blue"; + if (converterCategories.audio.includes(converterName)) + return "purple"; + if (converterCategories.video.includes(converterName)) + return "red"; + if (converterCategories.doc.includes(converterName)) + return "green"; + return null; + }) + .filter( + (type): type is "blue" | "purple" | "red" | "green" => + type !== null, ); - const uniqueTypes = new Set(converters); - if (uniqueTypes.size === 1) { - const onlyType = converters[0]; - if (converterCategories.image.includes(onlyType)) type = "blue"; - else if (converterCategories.audio.includes(onlyType)) - type = "purple"; - else if (converterCategories.video.includes(onlyType)) - type = "red"; - else if (converterCategories.doc.includes(onlyType)) - type = "green"; - } - } + const uniqueTypes = new Set(fileTypes); + const type = + files.files.length > 0 && + fileTypes.length === files.files.length && + uniqueTypes.size === 1 + ? fileTypes[0] + : ""; - if (files.files.length === 0 || !type) { - showGradient.set(false); - } else showGradient.set(true); + if (files.files.length === 0 || !type) showGradient.set(false); + else showGradient.set(true); gradientColor.set(type); }); @@ -153,7 +164,6 @@ {#snippet fileItem(file: VertFile, index: number)} {@const currentConverter = getCurrentConverter(file)} {@const name = currentConverter?.name || "unknown"} - {@const isImage = converterCategories.image.includes(name)} {@const isAudio = converterCategories.audio.includes(name)} {@const isVideo = converterCategories.video.includes(name)} {@const isDocument = converterCategories.doc.includes(name)} @@ -327,7 +337,7 @@ type: isAudio ? m["convert.errors.audio"]() : isVideo - ? "Video" + ? m["convert.errors.video"]() : isDocument ? m["convert.errors.doc"]() : m["convert.errors.image"](),