Mirror is an all-in-one application that forwards your screen content to external displays and expands Android's built-in screen mirroring capabilities. It creates virtual displays and supports screen sharing to:
- AirPlay receivers (Apple tvOS and macOS built-in receivers, or third-party receivers using AirPlay Server for Android or UxPlay)
- DisplayLink adapters connected to the device via USB host mode
- Moonlight (Nvidia GameStream) clients with remote control support via the built-in Sunshine server
It can be used in conjunction with Extend to turn any connected display or sink device into a secondary display where you can cast and control any application. You can also use this with AirPlay Server for Android or Moonlight for Android to create a dummy display that stays in Picture-in-Picture.
demo.mp4
Mirror supports creating virtual displays and streaming to them without Shizuku. Remote input requires Shizuku: enable it in any supported mode (wireless debugging, USB debugging, or root) and grant access to this application. See Shizuku documentation for details.
Mirror gets pixels onto a display. What application runs on it, where it renders, and how input is routed are handled by Extend. The two applications connect through Android's display system via DisplayManager API.
- Any device on Android 8.0+ (no privileged access required)
- (Optional) Receiver on the same subnet for AirPlay and Moonlight sinks
- (Optional) USB 2 or higher for DisplayLink sinks
- (Optional) Extend for managing the secondary display
- (Optional) Shizuku for hidden API access
- Outbound AirPlay 2 (modern) and AirPlay 1 (legacy) screen mirroring to Apple devices or third-party AirPlay receivers
- Outbound Moonlight streaming and remote control, with Sunshine server built in
- DisplayLink USB output via USB host mode (including USB 2)
- Each display sink is registered as a virtual display via
DisplayManagerAPI allowing other applications to launch activities on it - Touchscreen relay for remote pointer and keyboard input directed at the mirrored display
| Feature | Shizuku | Minimum API |
|---|---|---|
| AirPlay mirroring | N | 26 (MediaProjection.createVirtualDisplay) 34 ( MediaProjectionConfig.createConfigForDefaultDisplay) |
| DisplayLink USB output | N | 26 (android.hardware.usb.host) |
| Moonlight video streaming | N | 26 (MediaCodec H.264) 28 (BT.709/BT.2020 color metadata) 30 ( KEY_LOW_LATENCY) |
| Moonlight H.265/HEVC encoding | N | 29 (MediaCodecInfo.isHardwareAccelerated) |
| Audio capture (playback submix) | N | 29 (AudioPlaybackCaptureConfiguration) |
| Audio capture (remote submix) | O | 31 (REMOTE_SUBMIX) |
| Cursor overlay | O | 26 (TYPE_APPLICATION_OVERLAY) |
| Remote device input | R | 26 (IInputManager.injectInputEvent) |
| Touchscreen relay with live preview | R | 31 (setFocusedRootTask) 34 ( focusTopTask) |
| Auto-match aspect ratio | R | 26 (IWindowManager.setForcedDisplaySize) |
| Trusted virtual display | R | 33 (VIRTUAL_DISPLAY_FLAG_TRUSTED, OWN_DISPLAY_GROUP, ALWAYS_UNLOCKED, TOUCH_FEEDBACK_DISABLED) 34 ( DEVICE_DISPLAY_GROUP) |
| Untrusted virtual display | F | 26 (MediaProjection.createVirtualDisplay) |
| Application mirroring | N | 26 (ActivityOptions.setLaunchDisplayId) 29 ( ActivityManager.isActivityStartAllowedOnDisplay) |
| Prevent auto-lock | R | 26 (WRITE_SECURE_SETTINGS) |
| Disable USB audio output | R | 26 (IAudioService.setWiredDeviceConnectionState) 33 ( IAudioService.getDevicesForAttributes) |
| Display hotplug monitor | I | 26 (DisplayManager.DisplayListener) |
| Legend | Description |
|---|---|
| R | Required |
| O | Optional |
| F | Fallback |
| I | Inherited |
| N | Unused |
Native streaming servers are bridged to Android via JNI. The Moonlight path compiles Sunshine for Android and exposes a MediaProjection backed video source. Sunshine handles RTP packetization itself; moonlight-common-c supplies the Limelight protocol headers, RTSP parser, and ENet UDP control transport. The AirPlay path is built on doubletake, ported to Android via Go mobile and patched for Apple devices and legacy AirPlay receivers. The DisplayLink path uses Android USB host mode with a user-imported vendor driver.
flowchart LR
Android["Mirror"]
Sunshine["Sunshine (C/JNI)<br/><small>Moonlight (RTSP + RTP)</small>"]
Doubletake["doubletake (Go/JNI)<br/><small>RAOP + FairPlay + H.264</small>"]
DL["DisplayLink (USB)<br/><small>USB host mode</small>"]
Moonlight["Moonlight clients"]
AppleSink["Apple devices or third-party AirPlay receivers"]
DLSink["USB Display"]
Android -- "VirtualDisplay" --> Sunshine --> Moonlight
Android -- "VirtualDisplay" --> Doubletake --> AppleSink
Android -- "VirtualDisplay" --> DL --> DLSink
CMake drives the native C/C++ build under ./app/src/main/cpp. Submodules must be initialized before building. AirPlay is powered by doubletake with custom bindings under ./doubletake. This library needs to be built with ./build.sh first. Make sure go is available in $PATH before building.
git submodule update --init --recursive
./build.sh && ./gradlew assembleDebugCheck out the CI for reproducible build instructions.
- LizardByte for Sunshine server
- Moonlight Game Streaming Project for Moonlight headers
- Omar Roth for open-source AirPlay sender
doubletake - Tao Wen for the open-source Android bindings of DisplayLink vendor driver
- Xiph.Org Foundation for the Opus codec
Disclaimer: This project is not affiliated with Apple Inc or Synaptics Inc.