Phase 4: Medien-Widget mit dreistufiger Kaskade
Adapter für alles inklusive Browser, AppleScript für Spotify und Musik, Medientasten als letzte Reserve. Die Reihenfolge ist keine Vorliebe, sondern Absicherung: Apple hat die Now-Playing-Schnittstelle in macOS 15.4 schon einmal zugemacht. Fällt der Adapter aus, verliert das Widget seine Anzeige — aber nicht seine Funktion. Deshalb bleiben die Transporttasten auch dann bedienbar, wenn gar keine Metadaten da sind. Der Fortschritt zählt zwischen den Ereignissen selbst hoch. Spike B hatte gezeigt, dass elapsedTime nicht laufend nachgeliefert wird: ein Scrubber, der stur den letzten Wert anzeigt, steht still, während der Titel läuft. Gerechnet wird aus asOf und playbackRate, begrenzt auf die Titellänge — sonst zeigt die Anzeige nach dem Ende weiter steigende Zahlen. Teilmeldungen (diff = true) ergänzen den Stand, statt ihn zu ersetzen. Eine Meldung mit nur der Position würde sonst Titel, Interpret und Cover löschen. In AnyDecodable wird Bool vor Double geprüft. Andernfalls wird "playing": true zu 1 und die Wiedergabe gilt für immer als angehalten. Play/Pause schaltet sofort um, statt auf das nächste Ereignis zu warten. Ein Knopf, der eine halbe Sekunde später reagiert, fühlt sich kaputt an; das echte Ereignis korrigiert den Stand ohnehin. Der Adapter liegt als Quellcode unter Vendor/ (BSD-3, Stand in ONYX-VERSION.txt) und wird beim Bauen kompiliert, statt als fertige Binary eingecheckt zu werden. Er wird bewusst nicht gelinkt: geladen wird er von /usr/bin/perl, im eigenen Prozess greift Apples Entitlement-Prüfung. 124 Tests grün.
This commit is contained in:
81
Scripts/build-mediaremote-adapter.sh
Executable file
81
Scripts/build-mediaremote-adapter.sh
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
# Baut den mediaremote-adapter aus dem mitgelieferten Quellcode.
|
||||
#
|
||||
# Wird als Build-Schritt des App-Targets aufgerufen. Repliziert das
|
||||
# CMakeLists.txt des Projekts mit clang — cmake ist keine Voraussetzung, die
|
||||
# man einem Mitentwickler zumuten will.
|
||||
#
|
||||
# Der Umweg über /usr/bin/perl ist kein Trick um seiner selbst willen: seit
|
||||
# macOS 15.4 prüft mediaremoted Entitlements, und Fremdprogramme bekommen keine
|
||||
# Now-Playing-Daten mehr. Perl ist ein berechtigtes Systemprogramm und lädt das
|
||||
# hier gebaute Framework.
|
||||
#
|
||||
# Quelle: https://github.com/ungive/mediaremote-adapter (BSD-3-Clause),
|
||||
# eingebettet unter Vendor/ — siehe ONYX-VERSION.txt für den Stand.
|
||||
|
||||
set -euo pipefail
|
||||
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
|
||||
|
||||
SRC="${SRC:-$(cd "$(dirname "$0")/.." && pwd)/Vendor/mediaremote-adapter}"
|
||||
OUT="${OUT:?Zielverzeichnis fehlt}"
|
||||
NAME=MediaRemoteAdapter
|
||||
FW="$OUT/$NAME.framework"
|
||||
|
||||
[[ -d "$SRC" ]] || { echo "Quellen fehlen unter $SRC" >&2; exit 1; }
|
||||
|
||||
rm -rf "$OUT"
|
||||
mkdir -p "$FW/Versions/A/Headers" "$FW/Versions/A/Resources"
|
||||
|
||||
SOURCES=(
|
||||
"$SRC"/src/adapter/{env,get,globals,keys,now_playing,repeat,seek,send,shuffle,speed,stream,test}.m
|
||||
"$SRC"/src/private/MediaRemote.m
|
||||
"$SRC"/src/utility/{Debounce,helpers}.m
|
||||
)
|
||||
|
||||
echo "→ Framework-Binary"
|
||||
xcrun clang -dynamiclib -fobjc-arc -fvisibility=default -O2 \
|
||||
-arch arm64 -mmacosx-version-min=26.0 \
|
||||
-I"$SRC/include" -I"$SRC/src" \
|
||||
-framework Foundation -framework AppKit -framework UniformTypeIdentifiers \
|
||||
-install_name "@rpath/$NAME.framework/Versions/A/$NAME" \
|
||||
-o "$FW/Versions/A/$NAME" \
|
||||
"${SOURCES[@]}"
|
||||
|
||||
cp "$SRC/include/$NAME.h" "$FW/Versions/A/Headers/"
|
||||
|
||||
cat > "$FW/Versions/A/Resources/Info.plist" <<PLIST
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key><string>$NAME</string>
|
||||
<key>CFBundleIdentifier</key><string>com.vandenbe.$NAME</string>
|
||||
<key>CFBundleName</key><string>$NAME</string>
|
||||
<key>CFBundlePackageType</key><string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key><string>0.1</string>
|
||||
<key>CFBundleVersion</key><string>0.1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST
|
||||
|
||||
ln -sf A "$FW/Versions/Current"
|
||||
ln -sf "Versions/Current/$NAME" "$FW/$NAME"
|
||||
ln -sf Versions/Current/Headers "$FW/Headers"
|
||||
ln -sf Versions/Current/Resources "$FW/Resources"
|
||||
|
||||
echo "→ Test-Client"
|
||||
xcrun clang -fobjc-arc -O2 -arch arm64 \
|
||||
-I"$SRC/src/test" \
|
||||
-framework Foundation -framework MediaPlayer \
|
||||
-o "$OUT/${NAME}TestClient" \
|
||||
"$SRC"/src/test/{main,NowPlayingTest}.m
|
||||
|
||||
echo "→ ad-hoc signieren"
|
||||
codesign --force --deep --sign - "$FW"
|
||||
codesign --force --sign - "$OUT/${NAME}TestClient"
|
||||
|
||||
cp "$SRC/bin/mediaremote-adapter.pl" "$OUT/"
|
||||
|
||||
echo
|
||||
echo "Fertig: $OUT"
|
||||
ls -la "$OUT"
|
||||
Reference in New Issue
Block a user