feat: AV-Live Concert.app one-click launcher
CI build oscope-of / build-check (push) Has been cancelled

This commit is contained in:
L'électron rare
2026-06-27 21:17:38 +02:00
parent c7f98c24af
commit a98957ce46
4 changed files with 144 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
<?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>CFBundleName</key>
<string>AV-Live Concert</string>
<key>CFBundleDisplayName</key>
<string>AV-Live Concert</string>
<key>CFBundleIdentifier</key>
<string>cc.saillant.avlive.concert</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleExecutable</key>
<string>launch</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>LSUIElement</key>
<true/>
<key>LSMinimumSystemVersion</key>
<string>11.0</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
+43
View File
@@ -0,0 +1,43 @@
# AV-Live Concert.app
One double-click boots the whole iPhone-USB concert on macm1.
## What it does
`launch_concert.sh` (the app's executable) runs the full boot sequence:
1. Launches the **iPhone ARBodyTracker** app (camera + ARKit skeleton over USB).
2. Starts the **pose pipeline** (`data_only_viz --pose --iphone-usb`: HEVC decode,
MediaPipe, horizontal mirror, OSC out).
3. Boots **SuperCollider** (`sound_algo/data_only/boot.scd` → body-play: the
concert engine, 13 body gestures, 11 morceaux).
4. Switches to the **`\concert`** scene.
Re-running restarts cleanly (it kills any prior stack first).
## Build / install
On macm1 (where the stack runs):
```sh
cd ~/Documents/Projets/AV-Live/launcher/concert
./build_concert_app.sh # -> ~/Desktop/AV-Live Concert.app
```
Then double-click **AV-Live Concert.app** on the Desktop. A notification confirms
each stage; the Metal window + sound come up after ~45 s.
## Live controls (once running)
- **Space** — next morceau (random)
- **Bras croisés** (wrists) — jump to a random morceau
- **Body gestures** — jump/stomp/squat/spin/T-pose (FX), step/lean/tilt (harmony),
arm-raise/head (melody)
- `/control/concertChain 1` — hands-free auto-chain; `/control/concertSeq 1`
sequential instead of random; `CONCERT_MIRROR=0` — disable the video mirror
## Notes
- The iPhone device UDID (`DEV`) is hardcoded in `launch_concert.sh` — update it if
the phone changes (`xcrun devicectl list devices`).
- Logs: `/tmp/concert_viz.log` (pose) and `/tmp/sc_boot.log` (SuperCollider).
+20
View File
@@ -0,0 +1,20 @@
#!/bin/zsh
# Assemble "AV-Live Concert.app" from launch_concert.sh + Info.plist.
# Usage: ./build_concert_app.sh [output-path]
# default output: ~/Desktop/AV-Live Concert.app
set -eu
cd "$(dirname "$0")"
APP="${1:-$HOME/Desktop/AV-Live Concert.app}"
rm -rf "$APP"
mkdir -p "$APP/Contents/MacOS"
cp Info.plist "$APP/Contents/Info.plist"
cp launch_concert.sh "$APP/Contents/MacOS/launch"
chmod +x "$APP/Contents/MacOS/launch"
# Ad-hoc sign so Gatekeeper lets it run locally without a quarantine prompt.
codesign --force --deep --sign - "$APP" 2>/dev/null || true
xattr -dr com.apple.quarantine "$APP" 2>/dev/null || true
echo "Built: $APP"
echo "Double-click it, or: open \"$APP\""
+55
View File
@@ -0,0 +1,55 @@
#!/bin/zsh
# AV-Live Concert launcher.
# Boots the full iPhone-USB concert stack in one shot:
# iPhone ARBodyTracker (camera + ARKit skeleton over USB)
# -> data_only_viz pose pipeline (HEVC decode + MediaPipe + mirror + OSC)
# -> SuperCollider engine (body-play boot: concert + 13 gestures + 11 morceaux)
# -> switch to the \concert scene.
# Used as the executable of "AV-Live Concert.app" (double-click to start).
# Re-running restarts cleanly (it kills any prior stack first).
set -u
REPO="$HOME/Documents/Projets/AV-Live"
DEV="AC1CDE5F-DDC4-5B2C-80D7-9953D8ABA0AC" # iPhone 16 Pro (xcrun devicectl list devices)
export PATH=/opt/homebrew/bin:$PATH
export MEDIAPIPE_DELEGATE=cpu
export POSE_FILTER=median+kalman+lookahead+ik+arkit_fuse
# CONCERT_MIRROR=0 in the environment disables the video mirror.
PY="$REPO/data_only_viz/.venv/bin/python"
SCLANG="/Applications/SuperCollider.app/Contents/MacOS/sclang"
notify() { osascript -e "display notification \"$1\" with title \"AV-Live Concert\"" 2>/dev/null; }
cd "$REPO" || { notify "repo introuvable"; exit 1; }
# 0) clean any prior run
pkill -9 -f "data_only_viz.main" 2>/dev/null
pkill -9 -f sclang 2>/dev/null
pkill -9 -f scsynth 2>/dev/null
lsof -ti UDP:57121 2>/dev/null | xargs kill -9 2>/dev/null
lsof -ti UDP:57123 2>/dev/null | xargs kill -9 2>/dev/null
sleep 2
notify "Demarrage..."
# 1) iPhone ARBodyTracker (camera + skeleton over USB)
xcrun devicectl device process launch --device "$DEV" cc.saillant.ARBodyTracker >/dev/null 2>&1
sleep 3
# 2) pose pipeline (iPhone USB HEVC -> MediaPipe -> mirror -> OSC)
nohup "$PY" -m data_only_viz.main --pose --iphone-usb > /tmp/concert_viz.log 2>&1 &
disown
sleep 11
# 3) SuperCollider engine (boots to body-play; loads concert + gestures + morceaux)
cd "$REPO/sound_algo/data_only" || exit 1
nohup "$SCLANG" boot.scd > /tmp/sc_boot.log 2>&1 &
disown
sleep 30
# 4) switch to the concert scene
"$PY" -c "from pythonosc.udp_client import SimpleUDPClient; SimpleUDPClient('127.0.0.1',57121).send_message('/control/doScene','concert')"
sleep 1
notify "Concert lance. Espace = morceau suivant. Bras croises = morceau au hasard."