1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 07:20:00 +03:00
Files
android_cast/README.md
2026-05-23 17:05:31 +02:00

101 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Android Cast (POC)
**Roadmap & alpha scope:** [docs/ROADMAP.md](docs/ROADMAP.md) · **LAN demo QA:** [docs/ALPHA_SOAK.md](docs/ALPHA_SOAK.md) · USB-C/HDMI: [docs/USB_HDMI_CAST.md](docs/USB_HDMI_CAST.md) · Commercial (dev-gated): [docs/COMMERCIAL.md](docs/COMMERCIAL.md)
Minimal LAN screen-casting proof of concept in **Java**. Captures screen + playback audio, encodes **H.264 + AAC**, streams over **UDP or TCP** to a receiver that decodes and plays back.
## Features
- UDP broadcast discovery on the local network
- TCP or UDP stream transport (selectable; must match on both devices)
- PIN auth (SHA-256 hash, default `1234`)
- Screen capture → H.264 (AVC) with quality presets and scaled capture resolution
- Playback audio capture (API 29+) → AAC-LC
- Runtime notification permission (Android 13+)
## Quick start (alpha demo)
1. Install the same APK on two devices on the **same WiFi**.
2. **Receiver:** **Receive** → transport **UDP** → stream protection **None****Start listening**.
3. **Sender:** **Send****UDP** → pick **one** receiver → PIN → approve screen capture.
4. Sender resolution: **Original**, **720p**, **480p**, or **Auto** (settings drawer).
5. Watch **notifications** on both devices for status (not only toasts).
6. Stop from the sender notification **Stop** action.
Full soak script: [docs/ALPHA_SOAK.md](docs/ALPHA_SOAK.md).
### If video never appears
- Transport must match on both sides (e.g. both TCP).
- Receiver must show *Listening* or *Ready* in the notification before you cast.
- Sender notification should reach *Casting via TCP · WxH* — if it shows *Screen capture data missing*, reinstall and try again (Android 13+ intent fix).
- Keep the receiver UI open once so the video `Surface` attaches (or return to it after rotation).
## Build
Use **JDK 17 or 21** (Gradle does not run on JDK 25 yet):
```bash
export JAVA_HOME=/usr/lib/jvm/openjdk-bin-21
cd "/home/foxx/repos/My Projects/android cast"
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
## Stream options
| Option | Effect |
|--------|--------|
| **Transport UDP** | Default; lower latency |
| **Transport TCP** | Reliable fallback |
| **Sender resolution** | **Original** (native), **720p** / **480p** (long-edge cap), **Auto** (adaptive from peer stats) |
| **Bitrate** | Estimated / quality / speed modes in settings |
| **Stream protection** | FEC/NACK optional on UDP — use **None** for alpha demo |
| **Audio** | `AudioPlaybackCapture` + AAC (Android 10+) |
| **Camera capture** | Rear/front Camera2 (Android 10+); requires camera permission |
## Protocol
| Step | Description |
|------|-------------|
| Discovery | UDP `41234`, JSON with `magic`, `name`, `port`, `transport` |
| Connect | TCP or UDP port `41235` |
| Auth | `HELLO``AUTH``AUTH_OK``CAST_SETTINGS` |
| Stream | `STREAM_CONFIG`, `VIDEO_FRAME`, `AUDIO_CONFIG`, `AUDIO_FRAME` |
UDP frames use `ACUD` header and fragmentation for payloads > ~1.2 KB.
## Bluetooth / BLE
**Not viable for this video stream.** Practical throughput:
- **BLE**: ~100300 kb/s — fine for control/metadata only
- **Bluetooth Classic (SPP)**: often ~13 Mb/s theoretical — still far below 720p H.264 (~28 Mb/s), with high latency
A phone cannot “passthrough” a live encoded screen stream over BLE to another device for playback without a custom high-bandwidth profile (which consumer Android does not expose for arbitrary apps). Use **WiFi** for media; BT could be added later only for discovery/pairing if needed.
## Persistent services (AIDL)
Casting runs in **foreground services** with tray notifications:
| Service | Role |
|---------|------|
| `ScreenCastService` | Sender — capture, encode, stream |
| `ReceiverCastService` | Receiver — listen, decode, play |
Activities bind via AIDL (`ICastSenderService` / `ICastReceiverService`) for status updates and (on the receiver) attaching the video `Surface`. Rotating the screen or leaving the app does **not** stop the receiver listener; the sender keeps casting until you tap **Stop** in the notification.
## Limitations
- No TLS encryption (LAN cleartext POC)
- UDP mode may glitch under load
- Audio captures **playback** routed through the system (not microphone); some apps may be silent by policy
- Single sender → single receiver
## Development (git flow)
We use a **green `master`** plus integration branch **`next`**: features merge to `next` first; releases merge `next``master` and are tagged there; production hotfixes branch from `master` and sync back into `next`.
- Narrative: [docs/GIT_FLOW.md](docs/GIT_FLOW.md)
- PDF: [docs/GIT_FLOW.pdf](docs/GIT_FLOW.pdf) — `pip install -r docs/_pdf_build/requirements-pdf.txt`, then `python3 docs/_pdf_build/build_git_flow_pdf.py`