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.
82 lines
3.3 KiB
Markdown
82 lines
3.3 KiB
Markdown
# 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.
|