feat(downloads): editor UI — trim/split/crop clips (phase 2)

VideoEditor modal on a finished Library download: HTML5 <video> scrubber, filmstrip timeline
(lazy server storyboard sprite) with draggable in/out handles, draggable/resizable crop overlay,
per-edit Precise (re-encode) vs Fast (stream-copy) cut toggle, split-into-N fan-out (N trim jobs),
optional clip name. Edited clips show a 'Clip' badge; 'editing' phase gets a % bar. New api
enqueueEdit/downloadStoryboard/storyboardImageUrl + EditSpec type; editor i18n (en/hu/de).
This commit is contained in:
npeter83 2026-07-04 01:10:42 +02:00
parent f0fc542260
commit 04c461837f
9 changed files with 585 additions and 12 deletions

View file

@ -45,7 +45,8 @@
"thumbnail": "Vorschaubild einbetten",
"sponsorblock": "Sponsoren entfernen",
"metadata": "Metadaten schreiben",
"processing": "Verarbeitung"
"processing": "Verarbeitung",
"editing": "Bearbeitung"
},
"actions": {
"pause": "Pause",
@ -55,7 +56,8 @@
"retry": "Erneut",
"download": "Auf mein Gerät speichern",
"rename": "Umbenennen",
"share": "Teilen"
"share": "Teilen",
"edit": "Bearbeiten / schneiden"
},
"empty": {
"queue": "Die Warteschlange ist leer.",
@ -142,5 +144,6 @@
"status": "Status",
"added": "Hinzugefügt",
"user": "Nutzer"
}
},
"clipBadge": "Clip"
}

View file

@ -0,0 +1,29 @@
{
"title": "Bearbeiten: „{{name}}“",
"playPause": "Wiedergabe / Pause",
"setIn": "Start hier",
"setOut": "Ende hier",
"in": "Start",
"out": "Ende",
"selected": "Auswahl",
"cropOff": "Zuschneiden",
"cropOn": "Zuschneiden aktiv",
"cropReencode": "Zuschneiden kodiert immer neu (bildgenau).",
"split": "Aufteilen in",
"accurate": {
"label": "Genauer Schnitt",
"hint": "Bildgenau. Kodiert den Clip neu."
},
"fast": {
"label": "Schneller Schnitt",
"hint": "Sofort, schneidet aber an Keyframes (±12 s)."
},
"nameLabel": "Clip-Name (optional)",
"willReencode": "Wird neu kodiert",
"willCopy": "Sofort (Stream-Kopie)",
"create": "Clip erstellen",
"createN": "{{count}} Clips erstellen",
"created_one": "{{count}} Clip zu deinen Downloads hinzugefügt",
"created_other": "{{count}} Clips zu deinen Downloads hinzugefügt",
"failed": "Clip konnte nicht erstellt werden."
}

View file

@ -45,7 +45,8 @@
"thumbnail": "Embedding thumbnail",
"sponsorblock": "Removing sponsors",
"metadata": "Writing metadata",
"processing": "Processing"
"processing": "Processing",
"editing": "Editing"
},
"actions": {
"pause": "Pause",
@ -55,7 +56,8 @@
"retry": "Retry",
"download": "Save to my device",
"rename": "Rename",
"share": "Share"
"share": "Share",
"edit": "Edit / trim"
},
"empty": {
"queue": "Nothing in the queue.",
@ -142,5 +144,6 @@
"status": "Status",
"added": "Added",
"user": "User"
}
},
"clipBadge": "Clip"
}

View file

@ -0,0 +1,29 @@
{
"title": "Edit “{{name}}”",
"playPause": "Play / pause",
"setIn": "Set start",
"setOut": "Set end",
"in": "Start",
"out": "End",
"selected": "Selection",
"cropOff": "Add crop",
"cropOn": "Cropping",
"cropReencode": "Cropping always re-encodes (frame-accurate).",
"split": "Split into",
"accurate": {
"label": "Precise cut",
"hint": "Frame-accurate. Re-encodes the clip."
},
"fast": {
"label": "Fast cut",
"hint": "Instant, but cuts snap to keyframes (±12s)."
},
"nameLabel": "Clip name (optional)",
"willReencode": "Will re-encode",
"willCopy": "Instant (stream copy)",
"create": "Create clip",
"createN": "Create {{count}} clips",
"created_one": "{{count}} clip added to your downloads",
"created_other": "{{count}} clips added to your downloads",
"failed": "Couldnt create the clip."
}

View file

@ -45,7 +45,8 @@
"thumbnail": "Bélyegkép beágyazása",
"sponsorblock": "Szponzorok eltávolítása",
"metadata": "Metaadat írása",
"processing": "Feldolgozás"
"processing": "Feldolgozás",
"editing": "Szerkesztés"
},
"actions": {
"pause": "Szünet",
@ -55,7 +56,8 @@
"retry": "Újra",
"download": "Mentés a gépemre",
"rename": "Átnevezés",
"share": "Megosztás"
"share": "Megosztás",
"edit": "Szerkesztés / vágás"
},
"empty": {
"queue": "A sor üres.",
@ -142,5 +144,6 @@
"status": "Állapot",
"added": "Hozzáadva",
"user": "Felhasználó"
}
},
"clipBadge": "Klip"
}

View file

@ -0,0 +1,29 @@
{
"title": "Szerkesztés: „{{name}}”",
"playPause": "Lejátszás / szünet",
"setIn": "Kezdet itt",
"setOut": "Vég itt",
"in": "Kezdet",
"out": "Vég",
"selected": "Kijelölés",
"cropOff": "Vágókeret",
"cropOn": "Vágókeret bekapcsolva",
"cropReencode": "A vágókeret mindig újrakódol (frame-pontos).",
"split": "Feldarabolás",
"accurate": {
"label": "Pontos vágás",
"hint": "Frame-pontos. Újrakódolja a klipet."
},
"fast": {
"label": "Gyors vágás",
"hint": "Azonnali, de kulcskockára ugrik (±12 mp)."
},
"nameLabel": "Klip neve (opcionális)",
"willReencode": "Újrakódolás lesz",
"willCopy": "Azonnali (másolás)",
"create": "Klip létrehozása",
"createN": "{{count}} klip létrehozása",
"created_one": "{{count}} klip a letöltésekhez adva",
"created_other": "{{count}} klip a letöltésekhez adva",
"failed": "A klip létrehozása nem sikerült."
}