From ffb6ef856b3d8303a033cf0c6b4f8bdd3021d20c Mon Sep 17 00:00:00 2001
From: Maya
Date: Sat, 28 Feb 2026 00:06:16 +0300
Subject: [PATCH] feat: mediabunny progress and cancel
---
messages/en.json | 2 +-
src/lib/converters/mediabunny.svelte.ts | 36 +++++++++++++++++++++----
src/routes/+page.svelte | 20 +++++++++++---
3 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/messages/en.json b/messages/en.json
index ff2d406..7e331ff 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -26,7 +26,7 @@
"audio": "Audio",
"documents": "Documents",
"video": "Video",
- "video_server_processing": "Server supported",
+ "video_server_processing": "Local & server supported",
"local_supported": "Local supported",
"status": {
"text": "Status: {status}",
diff --git a/src/lib/converters/mediabunny.svelte.ts b/src/lib/converters/mediabunny.svelte.ts
index 006e093..a6fffb0 100644
--- a/src/lib/converters/mediabunny.svelte.ts
+++ b/src/lib/converters/mediabunny.svelte.ts
@@ -18,10 +18,14 @@ import {
} from "mediabunny";
import { Converter, FormatInfo, type WorkerStatus } from "./converter.svelte";
import { ToastManager } from "$lib/util/toast.svelte";
+import { error, log } from "$lib/util/logger";
export class MediabunnyConverter extends Converter {
public name = "mediabunny";
public status: WorkerStatus = $state("ready");
+ public reportsProgress: boolean = true;
+
+ private activeConversions = new Map();
public supportedFormats: FormatInfo[] = [
new FormatInfo("mp4", true, true),
@@ -45,12 +49,9 @@ export class MediabunnyConverter extends Converter {
const input = new Input({
// TODO: add settings & special handling for certain formats & codecs
formats: [MP4, QTFF, MATROSKA, WEBM, MPEG_TS],
- source: new BlobSource(file.file)
+ source: new BlobSource(file.file),
});
- const toFormat = to.startsWith(".") ? to.slice(1) : to;
- const originalName = file.file.name.split(".").slice(0, -1).join(".");
-
const output = new Output({
format: this.format(to),
target: new BufferTarget(),
@@ -72,12 +73,20 @@ export class MediabunnyConverter extends Converter {
throw new Error(`Mediabunny conversion not valid`);
}
+ conversion.onProgress = (progress) => {
+ file.progress = progress * 100;
+ };
+
+ this.activeConversions.set(file.id, conversion);
await conversion.execute();
+ this.activeConversions.delete(file.id);
if (!output.target.buffer) {
throw new Error("Mediabunny conversion failed: no output buffer");
}
+ const toFormat = to.startsWith(".") ? to.slice(1) : to;
+ const originalName = file.file.name.split(".").slice(0, -1).join(".");
const f = new File(
[output.target.buffer],
`${originalName}.${toFormat}`,
@@ -111,5 +120,22 @@ export class MediabunnyConverter extends Converter {
}
}
- public async cancel(input: VertFile): Promise {}
+ public async cancel(input: VertFile): Promise {
+ const conversion = this.activeConversions.get(input.id);
+ if (!conversion) {
+ error(
+ ["converters", this.name],
+ `no active conversion found for file ${input.name}`,
+ );
+ return;
+ }
+
+ log(
+ ["converters", this.name],
+ `cancelling conversion for file ${input.name}`,
+ );
+
+ conversion.cancel();
+ this.activeConversions.delete(input.id);
+ }
}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index c063d64..954ad0d 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -66,10 +66,20 @@
};
if (!DISABLE_ALL_EXTERNAL_REQUESTS) {
+ const formats = Array.from(
+ new Set([
+ ...getSupportedFormats("vertd").split(", "),
+ ...getSupportedFormats("mediabunny").split(", "),
+ ]),
+ )
+ .filter((f) => f !== "none")
+ .join(", ");
+
output.Video = {
- formats: getSupportedFormats("vertd"),
+ formats,
icon: Film,
title: m["upload.cards.video"](),
+ // TODO: add "partial" state? somehow figure out diff between vertd and mediabunny
status: $vertdLoaded === true ? "ready" : "not-ready", // not using converter.status for this
};
}
@@ -231,9 +241,11 @@
{/if}
- {@html sanitize(m["upload.cards.status.text"]({
- status: getStatusText(s.status),
- }))}
+ {@html sanitize(
+ m["upload.cards.status.text"]({
+ status: getStatusText(s.status),
+ }),
+ )}