Skip to content

About

Mirror your iPhone screen to Linux — real-time, no cloud, no accounts.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

iPhone Mirror icon

iPhone Mirror

"Mirror your iPhone screen to Linux — real-time, no cloud, no accounts."

version license platform stack

Screenshots · Install · Features · How it works · Development


iPhone Mirror captures your iPhone's screen over AirPlay and renders it inside a native GTK4 window on Linux, using hardware-accelerated GStreamer/VAAPI decoding. No accounts, no cloud, no telemetry — just your screen, on your machine.

Screenshots

Auto-detect device & frame
Auto-detect iPhone model

Real-time mirroring at 60fps
Live mirroring

Device frame matches your iPhone
Device frame

Features

  • 🔍 Auto-detect iPhone model — reads the device identifier from AirPlay and automatically selects the matching frame (11 Pro Max, 12 Pro Max, 13, 14 Pro Max, 15, 15 Pro Max, 16, 16 Pro, 17 Pro, 17 Pro Max).
  • 🖼️ Realistic device frames — each frame is a high-res PNG with the exact cutout dimensions from device-frames-media, so the video sits perfectly inside the screen.
  • ⚡ 60fps streaming — UxPlay -fps 60 by default; changeable with --fps.
  • 🎨 Native GTK4 — no Electron, no webview; a single Python process with GStreamer/VAAPI hardware decoding and OpenGL ES rendering.
  • 📐 Fixed frame size — the phone stays 640–900px tall regardless of window size; no oversized frames when you maximize.
  • 🔄 Live orientation — portrait and landscape automatically.
  • 🛡️ Local only — the RTP stream stays on 127.0.0.1; nothing leaves your machine.
  • 👆 USB touch control — click and drag on the mirrored screen to tap and swipe on your iPhone (requires USB connection + pymobiledevice3).

Install

.deb (recommended)

sudo apt install ./iphone-mirror_0.3.4_all.deb

User install (no sudo)

./install.sh

Installs to ~/.local/bin/iphonemirror — no root required.

From source

git clone https://github.com/MUHAMMEDHAFEEZ/iphone-mirror-linux.git
cd iphone-mirror-linux
sudo apt install python3-gi gir1.2-gtk-4.0 gstreamer1.0-tools \
  gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
  gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-vaapi
./install.sh

Requirements

Package Purpose
python3-gi + gir1.2-gtk-4.0 GTK4 Python bindings
gstreamer1.0-vaapi Hardware video decoding
gstreamer1.0-plugins-bad H.264 depayloader
UxPlay 1.74+ (-vrtp support) AirPlay server
pymobiledevice3 (optional) USB touch control

Usage

# Basic — auto-detect device, 60fps
iphonemirror

# Force a specific frame
IM_FRAME="15 Pro Max" iphonemirror

# Change max FPS
iphonemirror --fps 120

# Debug mode (shows detection logs)
IM_DEBUG=1 iphonemirror

USB Touch Control

To control your iPhone from the PC (tap, swipe), you need:

  1. USB connection — connect your iPhone via USB cable, unlock it, and tap Trust This Computer if prompted.
  2. usbmuxd — the USB multiplexor daemon:
    sudo systemctl start usbmuxd
  3. pymobiledevice3 — Python library for iOS device communication (iOS 17+ uses a RemoteXPC tunnel over USB for input injection, not the classic lockdown/HID service):
    pip3 install --user pymobiledevice3

Touch injection needs its own tunnel in addition to the AirPlay mirroring connection — the app can't create it itself since it requires sudo. Two ways to start it:

One command, one sudo prompt:

./run-with-touch.sh

Starts the tunnel, wires it up, launches iPhone Mirror, and tears the tunnel down when you quit.

Keep the tunnel up across relaunches (useful while iterating):

./start-tunnel.sh      # in its own terminal — leave it running
iphonemirror            # in another terminal, as many times as you like

How it works:

  • Click on the mirrored screen → tap at that point on your iPhone
  • Drag on the mirrored screen → swipe gesture on your iPhone
  • The coordinate mapping is automatic — click where you want to tap

Note: Touch control requires the iPhone to be connected via USB AND AirPlay at the same time. USB carries the input-injection tunnel; AirPlay carries the mirrored video. Losing either one drops just that half.

How it works

┌──────────────┐    AirPlay     ┌──────────────┐    RTP/UDP     ┌──────────────────┐
│   iPhone      │ ─────────────▶ │   UxPlay      │ ─────────────▶ │  GStreamer pipe   │
│  (any model)  │ ◀───────────── │  (1.74, -vrtp)│ ◀───────────── │  VAAPI decode     │
└──────────────┘   AirPlay2     └──────────────┘   127.0.0.1    └────────┬─────────┘
                                                                          │
                                                                          ▼
                                                              ┌──────────────────┐
                                                              │  GTK4 GLArea      │
                                                              │  device frame     │
                                                              │  60fps render     │
                                                              └──────────────────┘
  1. UxPlay advertises an AirPlay service (iPhone Mirror on _airplay._tcp) and waits for a connection.
  2. When your iPhone connects, UxPlay prints the device model (e.g. iPhone12,5) and starts an RTP/H.264 stream to 127.0.0.1:5000.
  3. GStreamer receives the RTP packets, depayloads H.264, decodes with VAAPI (hardware), and converts to RGBA.
  4. VideoArea (a GTK4 GLArea) uploads each frame as an OpenGL texture, draws it inside the matching device frame PNG with alpha blending.

Device detection

connection request from Ali's iPhone (iPhone12,5) with deviceID = A4:83:E7:12:34:56

UxPlay prints this line at the default INFO level. Our reader thread parses it, maps iPhone12,5 → iPhone 11 Pro Max, and hot-swaps the frame texture.

Frame scaling

The frame is capped to 640–900px height — it never grows beyond that, even in fullscreen. This keeps the phone looking like a real device, not a stretched poster.

Development

git clone https://github.com/MUHAMMEDHAFEEZ/iphone-mirror-linux.git
cd iphone-mirror-linux
pip install pygobject  # for development only
python3 -m iphone_mirror.main --port 5000

Project structure

iphone-mirror-linux/
├── iphone_mirror/
│   ├── __init__.py      # version
│   ├── main.py          # CLI entry point
│   ├── app.py           # Gtk.Application + MirrorWindow
│   ├── video.py         # VideoArea (GStreamer → GL texture)
│   ├── gl.py            # OpenGL ES ctypes bindings + shaders
│   ├── uxplay.py        # UxPlay process manager + device detection
│   └── device.py        # iPhone model → frame mapping
├── assets/frames/       # device frame PNGs + template.json
├── packaging/           # .desktop, icon
├── install.sh           # user install (~/.local)
├── make-release.sh      # build .deb + tar.gz
└── dist/                # release artifacts

Rebuild

./make-release.sh   # produces dist/iphone-mirror_*.deb + .tar.gz
./install.sh        # install to ~/.local

Security notes

This is a solo-maintained local tool, not an audited enterprise product. The RTP stream is unencrypted (that's the AirPlay protocol), but it stays on 127.0.0.1 — nothing leaves your machine. UxPlay advertises on the local network via mDNS, so any device on the same Wi-Fi can see the service name, but only an authorized Apple device can connect.

License

MIT

About

Mirror your iPhone screen to Linux — real-time, no cloud, no accounts.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages