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.
82 lines
2.8 KiB
Bash
Executable File
82 lines
2.8 KiB
Bash
Executable File
#!/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"
|