← Zurück zum Journal
MeetreToolsmacOSSwiftUI

Meetre ist erwachsen geworden und jetzt eine echte Mac-App

Mein Meeting-Transkriptor war mal ein Python-Skript mit einem Funkeln in der Menüleiste. Jetzt ist er eine native SwiftUI-App mit Bibliothek, Live-Untertiteln und Teams-Erkennung, und die Python-Engine macht darunter einfach weiter die schwere Arbeit.

Meetre ist erwachsen geworden und jetzt eine echte Mac-App

Im Juni war Meetre ein ✦ in der Menüleiste, dahinter ein Python-Prozess und ein Ordner voller Markdown-Dateien. Ich hab hier darüber geschrieben und war ziemlich zufrieden. Dann hab ich es weiter benutzt. Die Risse kamen dort, wo sie immer kommen: nicht bei den Modellen, sondern bei allem drumherum.

Also ist Meetre diese Woche eine richtige App geworden. Meetre.app, in SwiftUI geschrieben, liegt in ~/Applications und taucht in Spotlight und Launchpad auf wie jedes andere Programm auch.

Das Python bleibt, es redet nur nicht mehr mit dir

Die Engine hab ich nicht neu geschrieben. Transkription, Sprechererkennung und Zusammenfassungen laufen weiter in Python auf MLX und PyTorch, und der Code funktioniert. Den aus Prinzip nach Swift zu portieren, hätte mich einen Monat gekostet und nichts gebracht.

Geändert hat sich, wer das Sagen hat. Die Swift-App startet die Engine als Kindprozess und spricht mit ihr über JSON-RPC, ein JSON-Objekt pro Zeile, über stdin und stdout. Die App schickt record.start, die Engine antwortet mit einem Zeitstempel und meldet dann alle halbe Sekunde ihren Zustand, solange sie aufnimmt oder rechnet. Eine eigene Oberfläche hat die Engine gar nicht mehr. Alles, was du siehst, ist Swift.

Ein Nebeneffekt davon war mir vorher gar nicht klar. macOS vergibt Mikrofon- und Bildschirmaufnahme-Rechte pro App. Als noch ein Python-Interpreter danach gefragt hat, stand im Dialog irgendein Binary tief aus einem virtuellen Environment, und das sah ungefähr so vertrauenswürdig aus, wie es klingt. Jetzt läuft die Engine unter Meetre.app, im Dialog steht "Meetre", und die Erlaubnis hängt an dem, was du tatsächlich installiert hast. App und Aufnahme-Helfer sind außerdem mit einer festen lokalen Identität signiert. Nach einem Update vergisst macOS also nicht mehr alles, was du schon erlaubt hattest.

Das Meetre-Popover in der Menüleiste im Ruhezustand, mit großem Aufnahmeknopf und den letzten drei Meetings
Das Popover kann zuerst genau eine Sache: aufnehmen. Alles andere kommt danach.

Eine klare Aktion pro Fläche

Bevor ich das meiste gebaut hab, hab ich ein kleines Regelbuch fürs Design geschrieben, hauptsächlich damit ich aufhöre, mit mir selbst zu diskutieren. Die Regel, auf die ich immer wieder zurückkomme: Jede Fläche hat eine offensichtliche Aktion. Das Popover ist zum Aufnehmen da. Die Meeting-Ansicht zum Lesen der Zusammenfassung. Die Einstellungen, um eine Sache zu ändern. Alles Zweitrangige wandert in ein Menü.

Das Popover hält sich daran. Ein großer gläserner Aufnahmeknopf, eine Statuszeile darunter, deine letzten drei Meetings, fertig. Bei den Farben bin ich streng: Das Rot gehört der Aufnahme, und sonst darf es nirgends in der App vorkommen. Löschen-Buttons bekommen das System-Rot für destruktive Aktionen. Klingt nach Haarspalterei, bis du merkst, wie viel ruhiger sich eine Oberfläche anfühlt, wenn Rot genau eine Sache bedeutet.

Endlich eine Bibliothek

Die größte neue Fläche ist das Bibliotheksfenster. Links die Meetings, sortiert nach Heute, Gestern, Diese Woche und Früher. Jedes Meeting hat drei Tabs: Zusammenfassung, Transkript und Chat. Die Zusammenfassung teilt sich in Entscheidungen, Aufgaben zum Abhaken und offene Fragen. Im Transkript sind die Redebeiträge nach Person gruppiert, mit einem farbigen Streifen am Rand. So siehst du auf einen Blick, wer zwanzig Minuten am Stück geredet hat, ohne ein Wort zu lesen.

Das Meetre-Bibliotheksfenster mit einem Transkript, nach Sprecher gruppiert, jeder Beitrag mit farbigem Rand und Zeitstempel

Der Chat ist der jüngste der drei Tabs und kriegt einen eigenen Artikel, weil daraus mehr geworden ist als geplant.

Die Engine hab ich nicht neu geschrieben. Ich hab ihr nur verboten, direkt mit dir zu reden.

Untertitel, die du ignorieren kannst

Während der Aufnahme schweben Live-Untertitel in einem kleinen dunklen Panel oben rechts. Klicks gehen durch, es klaut deinem Call also nie einen Mausklick, außer bei den zwei kleinen Knöpfen oben im Panel. Standardmäßig ist es zu einem schmalen Streifen eingeklappt, ein Klick klappt es auf. Es ist immer dunkel, damit es auf jedem Hintergrund lesbar bleibt. Und es blendet ein und aus, statt reinzurutschen. Ein Panel, das neben einem Videocall herumfährt, ist wie jemand, der im Hintergrund winkt.

Das Live-Transkript-Overlay, ein dunkles Panel mit Untertiteln und Sprecher-Labels

Dass diese Untertitel auch der richtigen Person zugeordnet werden, war das schwierigste Problem des ganzen Releases. Auch dazu gibt's einen eigenen Artikel.

Es merkt, wenn ein Call anfängt

Die meisten meiner Calls laufen über Teams, und die meisten vergessenen Aufnahmen waren die, die anfingen, während ich noch eine Mail fertig geschrieben hab. Jetzt achtet Meetre darauf, ob ein Teams-Prozess das Mikrofon greift, und fragt, ob es aufnehmen soll. Wenn der Call endet, fragt es, ob es stoppen soll. Ignorierst du die zweite Frage, nimmt es einfach weiter auf. Für ein Tool, dessen ganzer Job ist, nichts zu verlieren, ist das die sichere Wahl.

Eine Nachfrage aus der Menüleiste: Teams-Call erkannt, diesen Call aufnehmen und transkribieren?

Keiner muss irgendwas neu installieren

Wer noch die alte Python-Version hat, soll dafür keine Anleitung von mir brauchen. Also aktualisiert sich die alte Version wie gewohnt selbst, baut im Hintergrund die neue Meetre.app, tauscht den Anmeldeobjekt-Eintrag aus, räumt Launchpad auf, damit es genau einen Eintrag gibt, und öffnet die neue App. Und der Installer weigert sich, Meetre zu beenden, solange es aufnimmt oder rechnet. Ein Update, das ein Meeting frisst, wäre der ironischste Bug, den ich ausliefern könnte.

Wie es weitergeht

Auf der Roadmap stehen zwei größere Schritte. Erstens werden Meetings zu ganz normalen Ordnern an einem Ort deiner Wahl, standardmäßig iCloud Drive: eine meeting.json, das Transkript, die Zusammenfassung und auf Wunsch das Audio. Absichtlich simple Dateien, damit du sie im Finder oder in Obsidian öffnen kannst und sie mit allem anderen im Backup landen. Zweitens eine Begleit-App für iPhone und iPad, die denselben Ordner liest: Meetings durchsuchen, Zusammenfassungen lesen, Aufgaben abhaken. Aufgenommen wird vorerst weiter am Mac.

Das Ganze bleibt Open Source unter MIT und läuft komplett auf deinem Rechner. Es liegt auf GitHub. Installiert wird immer noch mit einer Zeile, und wenn du es schon hast, musst du gar nichts tun. Das ist mir die liebste Sorte Release Note.