Watch YouTube on your Rokid AR glasses — ad-free, ring-navigable, in two modes.
GlassTube is a paired system of two coordinated Android apps that talk over a direct Bluetooth (SPP / RFCOMM) link — no Rokid SDK on the phone:
android-phone— installs on your Android phone. Owns the Piped account, the feed, search, stream resolution, the foreground transport service, and the audio player (audio-only mode).android-glasses— installs on the Rokid glasses (YodaOS). Renders the amber-on-black HUD, is 100% navigable by the R08 smart-ring (single input axis), and runs its own ExoPlayer for the audio+video mode.
Playback is ad-free via Piped / NewPipeExtractor — no Google login required. An optional Piped account unlocks your subscription feed.
⚠️ Legal / Terms of Service. Ad-free extraction of YouTube streams is a gray area with respect to YouTube's Terms of Service. GlassTube deliberately uses Piped (no Google account) to avoid tying a Google identity to extraction. Use it for personal, educational purposes and at your own risk. This project is not affiliated with, endorsed by, or sponsored by Google, YouTube, or Rokid.
| Mode | Where it plays | The glasses' role |
|---|---|---|
| Audio-only | ExoPlayer on the phone (foreground service). The glasses are already the BT headset, so sound comes out of them. | Browse the list and send commands (play/pause/next). |
| Audio + video | ExoPlayer on the glasses, pulling the resolved stream URL over Wi-Fi. | Browse and render video; the phone only resolves the URL and sends it. |
In both modes the phone owns the account, feed and stream resolution — the glasses never fetch metadata (the "state on the phone, view on the glasses" rule). The only network the glasses do is pulling the media bytes of a resolved stream in audio+video mode (too heavy for Bluetooth).
Navigation on the glasses is identical in both modes: a linear, ordered list of focusable actions plus a Back affordance, driven entirely by the R08 Access Bridge (forward/back = move focus, tap = activate, double-tap = Back).
glasstube/
├── shared-contracts/ # Pure-JVM Kotlin. Single source of truth for the wire protocol. No Android deps.
├── android-phone/ # Phone-host app (Gradle project).
├── android-glasses/ # Glasses-client app (Gradle project).
└── docs/ # ARCHITECTURE.md, PROTOCOL.md
shared-contracts is consumed by both apps via includeBuild("../shared-contracts").
Any change to the wire format must bump TransportConstants.PROTOCOL_VERSION
and ship both APKs together.
| # | Milestone | Status |
|---|---|---|
| 1 | Versioned handshake + heartbeat + monorepo scaffold | ✅ Built |
| 2 | Audio-only mode via Piped (feed / search / resolve + phone ExoPlayer) | ✅ Built |
| 3 | Audio+video mode (glasses ExoPlayer, HLS, ring-navigable controls) | ✅ Built |
| 4 | Piped account + subscription feed (encrypted token, login UI) | ✅ Built |
| 5 | Working transport: direct Bluetooth SPP (phone server + glasses client) | ✅ Built |
The two apps talk over Bluetooth Classic RFCOMM: the phone advertises an
insecure SPP service and the glasses connect to it as a client. The phone and
glasses must already be OS-level Bluetooth paired (bonded) — pairing the
glasses through Hi Rokid establishes that bond. On first launch, grant the
BLUETOOTH_CONNECT permission on both. Tap "Connect to glasses" on the phone to
start the foreground SPP server; the glasses connect and complete the versioned
handshake automatically.
The
CXRServiceBridgepath (Rokid CXR) connects to the Rokid companion runtime, not to a plain phone app, so GlassTube uses the direct SPP link the rokid-volund-os reference proves works. A BLE-GATT fallback and CXR bridging can be layered on later.
- BLE-GATT fallback transport (SPP is the implemented path today).
- Playlist NEXT/PREV forwarding to the glasses player in audio+video mode.
- On-glasses search input (voice over the reserved
micchannel, or a ring-navigable keyboard). TheSearchwire message exists; the input UI does not. - Optional: SponsorBlock, quality/instance selection UI.
Requires JDK 17+ (21 recommended) and Android SDK 34. Validated toolchain: AGP 8.7.3, Kotlin 2.1.0, Gradle 8.11.1. Both debug APKs build cleanly and use only the platform Bluetooth APIs for transport (no Rokid SDK dependency).
# Phone
cd android-phone && ./gradlew :app:assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
# Glasses — sideload via Hi Rokid
cd android-glasses && ./gradlew :app:assembleDebug
adb push app/build/outputs/apk/debug/app-debug.apk /sdcard/Download/
# then open it from Hi Rokid on the paired phoneThe glasses UI ships a JVM/Robolectric test that asserts the R08 Access Bridge
node contract (every actionable control is a focusable + clickable leaf with a
contentDescription; no full-screen click catchers):
cd android-glasses && ./gradlew :app:testDebugUnitTestThe shared protocol has its own round-trip test under
shared-contracts/src/test/.
- Piped instance —
Config.DEFAULT_PIPED_APIon the phone. Public instances come and go; point it at a reliable or self-hosted one. It is also persisted per-user inSessionStore. - Piped account (optional) — log in from the phone app to get your
subscription feed. The token is stored with
EncryptedSharedPreferences; it is a Piped token, not a Google token.
- Rokid R08 Access Bridge: https://github.com/Anezium/R08-Access-Bridge
- RokidPipe (100% ring-navigable reference app): https://github.com/Anezium/RokidPipe
- Piped: https://github.com/TeamPiped/Piped · NewPipeExtractor: https://github.com/TeamNewPipe/NewPipeExtractor
- LibreTube (Piped-account model): https://github.com/libre-tube/LibreTube
Released under the MIT License. GlassTube contains only original code and talks to Piped over HTTP; it does not bundle NewPipe/LibreTube sources. If you later vendor GPL/AGPL code into the tree, relicense accordingly.