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
This commit is contained in:
Maya 2026-03-11 18:10:18 +03:00
parent 2c66718552
commit 290c6d2f70
No known key found for this signature in database
3 changed files with 53 additions and 27 deletions

View File

@ -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."

View File

@ -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,
},

View File

@ -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"](),