Files
meditation-timer/README.md
Marcus Rehbock 0d694dc98b
All checks were successful
Build & Release APK / build (push) Successful in 12m15s
Videos tab: stream/download the server video library, in-app ExoPlayer
- New Videos tab lists videos served by health-api (GET /v1/videos), with
  thumbnails, duration/size, "Download for offline" into app-private storage
  (progress bar, remove), and tap-to-play.
- Full-screen Media3/ExoPlayer: plays the local copy if downloaded, otherwise
  streams /v1/videos/<file> with the existing sync bearer token (range requests).
- Activity handles rotation itself (configChanges) so playback survives it.
- Server side: health-api /v1/videos + video-add.sh (yt-dlp) — see README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pvxTrcfAiFZJcS7Jve2Au
2026-09-01 20:02:09 +10:00

1.7 KiB

Meditation Timer

Jhana meditation timer for GrapheneOS. Start/end gong, scroll-wheel duration picker (presets 20/45/60/90), session history with depth rating + notes, and sync to the meditation dashboard at health.rehbock.xyz/meditation.html.

Pipeline

Push to main on git.rehbock.xyz → Gitea Actions builds a signed release APK → published as a Gitea release → Obtainium on the phone picks up the new version.

Sync

Sessions POST to https://meditation.rehbock.xyz/v1/sessions (health-api). The bearer token is not in this repo or the APK — set it once in-app (History → Token) or seed it via:

adb shell am start -n com.marcus.meditationtimer/.MainActivity --es sync_token "<token>"

Sessions shorter than 30 seconds are not recorded (gong tests).

Videos

The Videos tab lists a library served by health-api (GET /v1/videos, files at /v1/videos/<name> with range support, same bearer token as sync). Add videos on the VPS:

~/personal/health-api/video-add.sh "https://www.youtube.com/watch?v=..."

(yt-dlp → 720p mp4 + thumbnail + info.json in health-api/data/videos/; delete the files to remove a video.) In-app: tap to stream, or "Download for offline" to keep a copy in app-private storage. Playback is Media3/ExoPlayer.

Local build

./gradlew assembleDebug   # needs ANDROID_HOME or local.properties

Release signing (CI): secrets KEYSTORE_B64 + KEYSTORE_PASSWORD; key alias meditation. Keystore master copy: ~/.android-keys/ on the desktop.

Gong

app/src/main/res/raw/gong.wav is synthesized (singing-bowl partials, detuned fundamental pair for beating). Regenerate with the script in the repo history / scratchpad if the tone needs tweaking.