docs(spec): native video confirmed working on device
The spike's central question — can a SurfaceView be composited behind a transparent Tauri WebView on Android — is answered yes, verified on a physical device. No upstream issue blocked it and none demonstrated it; this appears to be the first working instance. Marks DR-148 done behind the flag and records what is confirmed versus what is still open: playback and positioning are verified, but the individual native controls (seek, audio-track, subtitle), the mini-player transition, and the MediaCodec hardware-decode claim are not yet each measured. The mini-player transition is called out as the known gap, since it is the one case where the fullscreen assumption behind "no rect plumbing needed" does not hold. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
# Spec: Android native video — transparent-webview spike
|
||||
|
||||
**Status:** In progress — implemented behind `experimentalNativeVideo`, pending
|
||||
on-device confirmation. Branch `feat/android-native-video`.
|
||||
**Status:** Spike succeeded — native video confirmed working on a physical
|
||||
device (2026-08-11) with `experimentalNativeVideo` on. Shipped behind that flag,
|
||||
default off. Branch `feat/android-native-video`.
|
||||
|
||||
**The spike's central question is answered: yes.** A `SurfaceView` *can* be
|
||||
composited behind a transparent Tauri WebView on Android. Nothing upstream
|
||||
blocked it and nothing upstream demonstrated it — this is, as far as the issue
|
||||
trackers show, the first working instance. The remaining flag is about test
|
||||
coverage and the unverified cases below, not about viability.
|
||||
**Requirements:** IR-004, UR-003, UR-004 → DR-001, DR-023, DR-024
|
||||
**UX spec:** n/a — no intended visual change; the video surface must land exactly where the `<video>` element is today
|
||||
**Supersedes / revises:** acts on finding 2 of [playback-backend-unification.md](playback-backend-unification.md)
|
||||
@@ -175,9 +182,12 @@ is handled by an `OnLayoutChangeListener` that re-fits on any bounds change. The
|
||||
frontend's native branch is a bare `flex-1` box, so there is no rect to report
|
||||
and nothing to keep in sync.
|
||||
|
||||
This does mean **the mini-player transition is untested** for the native path —
|
||||
it is the one case the fullscreen assumption does not cover, and it remains an
|
||||
on-device check.
|
||||
Fullscreen playback is confirmed working on device. But this reasoning rests
|
||||
entirely on the fullscreen assumption, so **the mini-player transition is the
|
||||
known gap** — it is the one case where the surface is *not* fullscreen, and
|
||||
therefore the one case where the "no rect plumbing needed" conclusion could
|
||||
still turn out to be wrong. If artefacts appear there, the fix is the rect
|
||||
reporting this section originally proposed, scoped to that transition alone.
|
||||
|
||||
### A trap for the next implementer
|
||||
|
||||
@@ -212,9 +222,10 @@ The spike is **complete** when one of these is true:
|
||||
- [x] Transparent WebView confirmed working on a physical device (reported by the maintainer; the config that enables it is now committed in `tauri.android.conf.json`).
|
||||
- [x] `experimentalNativeVideo` off → behaviour byte-identical to today. Guarded by `adapterSelection.test.ts`, which asserts the flag-off case forces HTML5 even when Rust reports native.
|
||||
- [x] `webviewAudio.ts` no longer inspects `navigator.userAgent`; the platform's audio backend is read from Rust (`player_get_capabilities` → `usesWebviewAudio`).
|
||||
- [ ] `experimentalNativeVideo` on → video plays via ExoPlayer/MediaCodec, correctly positioned, with working seek, audio-track switch, and subtitle selection through the existing `PlayerAdapter` contract.
|
||||
- [ ] No artefacts on rotation, background/foreground, or mini-player transition.
|
||||
- [ ] `adb shell dumpsys media.metrics` (or logcat) confirms a hardware decoder is in use.
|
||||
- [x] `experimentalNativeVideo` on → video plays via ExoPlayer, correctly positioned, on a physical device (2026-08-11). The surface reaches the hierarchy and is visible through the transparent WebView — the whole point of the spike.
|
||||
- [ ] Seek, audio-track switch and subtitle selection exercised through `NativePlayerAdapter`. Playback is confirmed; these individual controls are not yet each verified on the native path.
|
||||
- [ ] No artefacts on rotation, background/foreground, or **mini-player transition** — the last is the one case the fullscreen assumption does not cover, so it is the likeliest place to find a problem.
|
||||
- [ ] `adb shell dumpsys media.metrics` (or logcat) confirms a hardware decoder is in use. Plausible but unmeasured — do not claim the MediaCodec win until this is read.
|
||||
- [ ] Measured battery/thermal or CPU improvement over the HTML5 path on the same clip.
|
||||
|
||||
**Failure path**
|
||||
|
||||
Reference in New Issue
Block a user