Phase 0: Repo-Gerüst und vier Verifikations-Spikes
Vier Annahmen des Plans vor jedem Implementierungscode geprüft:
A (SMC): Lüftersteuerung bestätigt — F0md/F1md (klein!) als Auto/Manuell-
Umschalter, F0Tg als Ziel, Grenzen aus F0Mn/F0Mx. SMC-Integer sind
little-endian, nicht big-endian wie im verbreiteten Intel-Beispielcode.
Ladelimit: CHWA/CH0B/CH0C/bfE0/bfF0 existieren auf Mac17,9 nicht.
Key noch nicht identifiziert, deshalb smc-diff.sh für eine
Differenzmessung ohne jeden Schreibzugriff.
B (Media): mediaremote-adapter läuft unter 26.6.1, aus dem Quellcode gebaut.
Liefert vollständige Metadaten inkl. Cover aus Google Chrome — der
Fall, den AppleScript nicht erreicht.
C (Audio): Process Tap + privates Aggregate-Device liefern echte Samples
(469 Callbacks/5 s, 0 stille Puffer). Konflikt gefunden: SoundSource
6.1.1 mit ARK.driver ist bereits installiert.
D (Group): App-Group-Container ist aus einem nicht-sandboxed Prozess erreichbar.
Damit trägt die Sandbox-Entscheidung, die Bridge-App entfällt.
Spikes sind Wegwerfcode zur Verifikation, kein Produktionscode.
This commit is contained in:
81
docs/spikes/B-mediaremote.md
Normal file
81
docs/spikes/B-mediaremote.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Spike B — mediaremote-adapter unter macOS 26.6.1
|
||||
|
||||
Gemessen am 10.08.2026. Quelle aus dem Git geklont und **selbst kompiliert**, keine
|
||||
Fremd-Binary geladen: `Spikes/build-mediaremote-adapter.sh` ersetzt das CMake-Setup
|
||||
des Projekts durch einen direkten clang-Aufruf (cmake ist auf dieser Maschine nicht
|
||||
installiert).
|
||||
|
||||
Projekt: [ungive/mediaremote-adapter](https://github.com/ungive/mediaremote-adapter), BSD-3-Clause,
|
||||
~400 KB Objective-C plus ein Perl-Skript.
|
||||
|
||||
## Ergebnis: funktioniert, auch im schwierigsten Fall
|
||||
|
||||
```
|
||||
perl mediaremote-adapter.pl <framework> <testclient> test → Exitcode 0
|
||||
```
|
||||
|
||||
Exitcode 0 heißt: der Adapter ist berechtigt, MediaRemote zu benutzen. Apples Sperre aus
|
||||
macOS 15.4 ist damit auf 26.6.1 weiterhin über den Perl-Trampolinweg umgehbar.
|
||||
|
||||
### `get` — vollständige Metadaten
|
||||
|
||||
Gelesen wurde eine laufende Wiedergabe in **Google Chrome** (YouTube). Das ist der wichtige
|
||||
Befund: genau diese Quelle erreicht AppleScript nicht, sie ist der Grund für die
|
||||
Adapter-Ebene überhaupt.
|
||||
|
||||
Gelieferte Felder:
|
||||
|
||||
| Feld | Beispiel |
|
||||
|---|---|
|
||||
| `title` | „Hanjos große Entdeckung in Thailand! \| Hanjo 2012" |
|
||||
| `artist` | „FilowLIVE" |
|
||||
| `album` | `""` |
|
||||
| `duration` | 3051,04 s |
|
||||
| `elapsedTime` | 432,06 s |
|
||||
| `playbackRate` | 1 |
|
||||
| `playing` | `true` |
|
||||
| `bundleIdentifier` | `com.google.Chrome` |
|
||||
| `processIdentifier` | 4525 |
|
||||
| `artworkData` | JPEG, base64 |
|
||||
| `artworkMimeType` | `image/jpeg` |
|
||||
| `timestamp` | `2026-08-10T14:22:16Z` |
|
||||
| `contentItemIdentifier` | UUID |
|
||||
|
||||
Das Cover kam sofort mit — die Warnung aus der Projekt-README („artwork often takes a bit of
|
||||
time") traf hier nicht zu, ist aber weiterhin einzuplanen.
|
||||
|
||||
### `stream` — der Modus, den Onyx benutzt
|
||||
|
||||
Zeilenweises JSON auf stdout:
|
||||
|
||||
```json
|
||||
{"type":"data","diff":false,"payload":{}}
|
||||
{"type":"data","diff":false,"payload":{"title":"…","elapsedTime":432.06,…}}
|
||||
```
|
||||
|
||||
Erst ein leerer Payload, dann der vollständige. `diff` unterscheidet Voll- von
|
||||
Teilaktualisierung — der Parser in `MediaProvider` muss beide Fälle behandeln und darf bei
|
||||
einem leeren Payload **nicht** auf „nichts läuft" schließen.
|
||||
|
||||
`elapsedTime` wird nicht sekündlich nachgeliefert. Die Fortschrittsanzeige muss zwischen den
|
||||
Ereignissen lokal hochzählen, ausgehend von `elapsedTime` + `timestamp` + `playbackRate`,
|
||||
sonst steht der Scrubber still.
|
||||
|
||||
## Nicht getestet
|
||||
|
||||
Die Steuerbefehle (`send`, `seek`, `shuffle`, `repeat`, `speed`) wurden **absichtlich nicht**
|
||||
ausgeführt — sie hätten die laufende Wiedergabe des Nutzers angehalten oder verstellt. Die
|
||||
Prüfung erfolgt in Phase 4 an einer eigens gestarteten Wiedergabe.
|
||||
|
||||
## Auswirkungen auf den Plan
|
||||
|
||||
1. Die Kaskade aus dem Plan bleibt, aber die Gewichtung verschiebt sich: der Adapter deckt
|
||||
mehr ab als erwartet, AppleScript ist reiner Rückfall.
|
||||
2. Der Adapter wird **aus dem Quellcode mitgebaut**, nicht als Fremd-Binary eingebunden.
|
||||
`Spikes/build-mediaremote-adapter.sh` wandert dafür als Build-Phase ins Xcode-Projekt.
|
||||
Vorteil: kein blind eingebundenes Binärartefakt, und die Ad-hoc-Signatur passt zum
|
||||
restlichen Bundle.
|
||||
3. Die Perl-Datei und das Framework kommen nach `Onyx/Resources/Vendor/` und werden
|
||||
**nicht** gelinkt (sonst greift Apples Entitlement-Prüfung im eigenen Prozess).
|
||||
4. `disable-library-validation` in den Entitlements ist bestätigt nötig — das Framework ist
|
||||
ad-hoc signiert, der Host wird es mit Team-Zertifikat sein.
|
||||
Reference in New Issue
Block a user