Beta-Hinweise und noindex entfernt, Kostenlos-Hinweis, Funktionen
(Ausschnitt, Marken, Feed/Ads-Format), FAQ, Impressum-&-Datenschutz-Link.
Falsche Angaben korrigiert (Ausgabe ist MP4/H.264/AAC, nicht codec-
erhaltend). Schriften selbst gehostet statt Google Fonts, OG-Bild.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ShKCZzkdZhym6mHuPqXQAT
- Systemfenster mit Toolbar (Dateien, Zielordner, Start), Tabelle mit
Standbild samt Ausschnitt, Ausschnitt-Knopf, Status als Text; das ganze
Fenster nimmt Dateien an. Folgt hell/dunkel des Systems, Gold nur als Akzent.
- Ausschnitt-Ansicht: Rahmen ziehen, Mittig setzen (Z/Doppelklick), Marken
setzen (M), per Hover-×, Rechtsklick oder ⌫ löschen, eigene Zeitleiste.
- Zielordner immer sichtbar; Start fragt ihn ab, statt still ausgegraut zu sein.
- Fehlendes Format im Namen wird beim Reinziehen gezeigt, mit "4x5 anhängen"
pro Datei oder für alle.
- Sparkle-Updater wird jetzt tatsächlich gestartet (vorher nur eingebunden),
plus "Nach Updates suchen …" im App-Menü.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ShKCZzkdZhym6mHuPqXQAT
- CropPlan: Ausschnitt-Offset pro Datei, mit Marken ab Zeitpunkt X (harte
Schnitte). CropEngine schneidet pro Frame nach Plan; cropRect ist die
gemeinsame Geometrie für Vorschau und Render.
- CropEngine wendet die Track-Transformation an: iPhone-Clips (quer
gespeichert, per 90°-Drehung hochkant) wurden bisher seitlich und mit
schwarzem Balken gerendert.
- FileNameParser erkennt 9x16/9X16/9×16, getrennt mit -, _ oder Leerzeichen,
Trenner bleiben erhalten; Rest hinter dem Format optional.
appendingTargetFormat hängt bei fehlendem Format "4x5" an.
- ConversionPipeline/JobQueue: appendFormatWhenMissing und CropPlan pro Job.
- Tests: Render-Richtung, Marken mitten im Clip, gedrehte Quelle, Parser-
Schreibweisen, Anhängen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ShKCZzkdZhym6mHuPqXQAT
Release-Konfiguration in project.yml auf Manual + Developer-ID-
Application-Zertifikat + Team-ID (XY4C2RG3L5) umgestellt. Debug bleibt
ad-hoc signiert für schnelle lokale Builds. Sparkle 2.10.0 als Package
eingebunden, SUFeedURL/SUPublicEDKey/SUEnableAutomaticChecks gesetzt.
Der private Sparkle-Schlüssel liegt ausschließlich im Schlüsselbund
(generate_keys), nirgendwo im Repo.
scripts/publish-release.sh: Bugfix im Notarisierungs-Check — spctl
gibt bei Erfolg ohne -v-Flag gar keinen Text aus, wodurch
"grep -q accepted" nie anschlug und jede gültige DMG fälschlich als
nicht notarisiert gemeldet worden wäre.
Erste Beta-DMG gebaut und end-to-end verifiziert: archiviert, mit
Developer-ID signiert (inkl. aller eingebetteten Sparkle-XPC-Dienste),
per create-dmg verpackt, bei Apple eingereicht und akzeptiert,
gestapelt, per spctl gegengeprüft und direkt vom gemounteten DMG
gestartet — läuft ohne Gatekeeper-Warnung.
bin/ (heruntergeladene Sparkle-CLI-Tools) und dist/ (Build-Artefakte)
sind bewusst nicht eingecheckt.
AVKits VideoPlayer (SwiftUI) crasht auf diesem macOS-Stand beim
Anzeigen mit einem Swift-Runtime-Fehler: "failed to demangle
superclass of VideoPlayerView from mangled name 'So12AVPlayerViewC'".
Das ist ein Metadata-Bug in Apples eigener _AVKit_SwiftUI-Bridge, kein
Fehler in unserem Code — bestätigt über den Crash-Report (SIGABRT,
swift::fatalError beim Instanziieren der generischen Metadata für
VideoPlayerView).
Fix: PlayerView bindet AppKits AVPlayerView direkt per
NSViewRepresentable ein statt über AVKits SwiftUI-Wrapper zu gehen —
umgeht den kaputten Codepfad komplett.
Schritt 5 der Umsetzungsreihenfolge.
ReviewSheet zeigt die Quelldatei per AVKit VideoPlayer (Scrubbing,
Play/Pause etc. kommen dadurch kostenlos mit) und blendet oben/unten
abgedunkelte Balken plus einen hellen Rahmen für die bleibende 4:5-
Fläche ein. Die Geometrie kommt direkt aus
CropEngine.targetSize(forSourceSize:) — die Vorschau zeigt also exakt
das, was beim tatsächlichen Crop rauskommt, keine zweite Berechnung.
Erreichbar über einen Vorschau-Button pro Zeile in der Dateiliste.
Bewusst noch nicht enthalten (README, "Danach"-Liste): verstellbarer
vertikaler Crop-Offset — die Ansicht ist reine Framing-Kontrolle.
Schließt eine MVP-Lücke: README verlangt "überschreiben nur nach
Rückfrage", bisher landete CropEngineError.destinationAlreadyExists
nur als Fehler in der Liste.
ConversionPipeline.previewDestination berechnet den Zielpfad einer
Datei, ohne irgendetwas anzufassen — damit kann die Oberfläche vor dem
Start prüfen, ob Konflikte bestehen, statt es mitten im Batch zu
entdecken. Bei Konflikten zeigt ConversionCoordinator einen Sammel-
Alert (Ersetzen/Überspringen/Abbrechen) für den ganzen Batch; eine
Datei-für-Datei-Auswahl wäre für das MVP unverhältnismäßig viel UI für
einen Randfall.
Neuer DropItem.Status-Fall .skippedByUser unterscheidet eine bewusste
Nutzerentscheidung von einem echten Fehler/Reject.
- GENERATE_INFOPLIST_FILE für DropTwoCore/DropTwoCoreTests, sonst
scheitert das Code-Signing der eingebetteten Frameworks (beide
Targets hatten kein Info.plist).
- .xcodeproj war ungetrackt, aber ohne aktive .gitignore-Regel — laut
README soll er nicht eingecheckt werden.
- MVP-Checkliste in der README auf den tatsächlichen Stand gebracht.
Schritt 4 der Umsetzungsreihenfolge.
- AppSettings: Quell-/Zielordner über Security-Scoped Bookmarks,
überlebt einen Neustart.
- DropZoneView: Drag & Drop plus Dateiauswahl-Dialog, öffnet im
konfigurierten Quellordner.
- ConversionCoordinator treibt JobQueue an, sortiert neue Dateien nach
zuletzt geändert, hält Fortschritt/Status pro Datei nach.
- FileListView zeigt Fortschritt und hebt Problemfälle (übersprungen/
abgelehnt/fehlgeschlagen) sichtbar hervor — keine stillen Abbrüche.
- CoreErrors+LocalizedError: deutsche Klartexte für die Core-Fehler-
Enums leben bewusst im App-Target, nicht im UI-freien Core.
- AppIcon aus assets/icon.svg gebaut (alle 10 macOS-Icongrößen via
rsvg-convert, ImageMagicks eingebauter SVG-Renderer hat den
Rahmen-Stroke verschluckt).
Bewusst ausgeklammert (spätere Schritte): Review-Ansicht, Menu-Bar-
Betrieb, Signierung/Notarisierung/Sparkle, Overwrite-Rückfrage-Dialog.
Schritt 3 der Umsetzungsreihenfolge.
ConversionPipeline bündelt den kompletten Weg einer Datei — Namen
parsen, Projekt-Unterordner anlegen, Original kopieren, croppen — als
einzelnen, UI-freien Core-Baustein. droptwo-cli und später die App
nutzen denselben Aufruf, damit beide garantiert dasselbe tun.
JobQueue verarbeitet mehrere Dateien mit begrenzter Parallelität
(Standard 2 gleichzeitige Exporte) und liefert Ergebnisse fortlaufend
über einen AsyncStream.
droptwo-cli ruft nur noch ConversionPipeline pro Datei auf. An echtem
9:16-Testmaterial verifiziert: korrekte Zielauflösung (1080×1920 ->
1080×1350), Dauer/Framerate erhalten, plausible Bitrate, sauberer
zentrierter Crop (visuell per Frame-Vergleich geprüft).
Schritt 2 der Umsetzungsreihenfolge.
VideoInspector liest Dimension (orientierungskorrigiert), Codec,
Framerate, Dauer und Audiospur-Vorhandensein über die moderne
async AVFoundation-API.
CropEngine läuft über AVAssetReader/AVAssetWriter statt
AVAssetExportSession, weil das die volle Kontrolle über Zielbitrate
und Profil gibt. Zielformat ist fest MP4/H.264/AAC, unabhängig vom
Quellcodec — das Deliverable landet ausschließlich bei Meta Ads.
Bitrate wird aus Auflösung × Framerate abgeleitet (Faustregel,
überschreibbar über Options), Audio läuft nicht mehr per Passthrough,
sondern wird nach AAC-LC transkodiert. Crop bleibt volle Breite,
vertikal zentriert, Höhe auf gerade Zahl gerundet.
Tests synthetisieren ihre Clips zur Laufzeit per AVAssetWriter
(TestVideoFactory) statt Binärdateien einzuchecken.
Schritt 1 der Umsetzungsreihenfolge. Anker ist das Format-Segment
(9x16/4x5), nicht die Position — dadurch bleiben Projektnamen und
Sprachkürzel mit eigenem Bindestrich intakt (z.B. "Somos-Pendant" oder
"EN-US"). Sucht das rechteste Vorkommen, verlangt mindestens ein
Segment davor und danach, erkennt Finder-Duplikate und meldet
Ablehnungen/Skips unterscheidbar statt still zu scheitern.
14 Tests inklusive der Bindestrich- und Groß-/Kleinschreibungs-Kantenfälle.