- JavaScript 78.7%
- HTML 18.9%
- Roff 1.7%
- Java 0.7%
| android | ||
| assets | ||
| release | ||
| www | ||
| .gitignore | ||
| capacitor.config.json | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
CALYPSO MediaPipe Face Mesh Demo
Important Finding: Android GPU Zooming Bug
During testing across different Android devices, we discovered a critical bug related to MediaPipe's WebGL execution (delegate: "GPU") on Android smartphones.
The Issue
On many Android smartphones (unlike tablets which often have desktop-class browsers or better GPU floating-point precision), initializing the MediaPipe FaceLandmarker with delegate: "GPU" does not throw an error.
However, it fails silently by causing compounding floating-point math errors across frames. This manifests as a "zooming" or "drifting" effect where the tracked face mesh grows infinitely in size and quickly disappears off-screen.
Because no exception is thrown by the WebGL context upon initialization, a standard try...catch block cannot detect or recover from this failure during runtime.
The Solution: Auto-Detection
We implemented an automatic device detection script in www/index.html using the navigator.userAgent to apply the correct hardware delegate based on the device:
// Android tablets typically omit "Mobile" in their user agent string, whereas smartphones include it.
const isSmartphone = /Mobile/i.test(navigator.userAgent);
const chosenDelegate = isSmartphone ? "CPU" : "GPU";
- Smartphones: Are forced to use
delegate: "CPU". This bypasses the WebGL precision issues entirely, keeping the tracking perfectly stable (with slightly higher battery usage). - Tablets: Are allowed to use
delegate: "GPU". High-end tablets handle the high-precision WebGL calculations smoothly, providing faster processing and lower power consumption.
This allows us to deploy a single FaceMeshDemo.apk that performs optimally and reliably across both tablets and smartphones.