Index Keywords

↶ Return

Connecting to an Android Phone with a Local scrcpy Build

Description

This article explains how to build and run scrcpy from a local source checkout on Linux, connect to an Android phone over USB, and fall back to Android’s wireless debugging connection when USB is unreliable. Scrcpy mirrors the phone’s video and audio and accepts keyboard and mouse input without requiring root access or an app installed on the phone.[1]

The commands were tested with scrcpy 4.0, a Pixel 7 Pro running Android 16, and an Ubuntu-based Linux host. Replace the example device serial, IP address, and ports with values reported by your own phone and adb.

Prerequisites

Linux host

The host needs:

  • A data-capable USB cable for the initial USB connection
  • Git and curl
  • Android Debug Bridge (adb)
  • Meson and Ninja
  • SDL 3, FFmpeg, libusb, and their development packages
  • A graphical Linux session in which scrcpy can open a window
  • The same local network as the phone when using wireless debugging

On Debian or Ubuntu, install the runtime and client build dependencies documented by scrcpy:[2]

1
2
3
4
5
sudo apt update
sudo apt install curl ffmpeg libsdl3-0 adb libusb-1.0-0 \
gcc git pkg-config meson ninja-build libsdl3-dev \
libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev \
libswresample-dev libusb-1.0-0-dev libv4l-dev

This guide uses scrcpy’s prebuilt Android server, so Java and a full Android SDK are not required. They are required if the server is built from source.

Android phone

Scrcpy supports Android 5.0/API 21 or newer. Enable developer options and USB debugging before connecting:[1:1][3]

  1. Open Settings → About phone.
  2. Tap Build number seven times.
  3. Open Settings → System → Developer options.
  4. Enable USB debugging.
  5. Connect the phone with a data-capable USB cable.
  6. Unlock the phone and accept the RSA debugging authorization prompt. Select Always allow from this computer only if the host is trusted.

For a wireless connection on Android 11 or newer, also enable Wireless debugging under developer options. The phone and host must be able to reach each other over the local network.[4][5]

Build scrcpy from the Local Checkout

Clone and select a release

Use the official repository and select an exact release so that the client and Android server versions are predictable:

1
2
3
4
5
6
mkdir -p "$HOME/Workspace"
cd "$HOME/Workspace"
git clone https://github.com/Genymobile/scrcpy.git
cd scrcpy
git switch --detach v4.0
git describe --tags --exact-match

For an existing checkout:

1
2
3
cd "$HOME/Workspace/scrcpy"
git fetch --tags origin
git switch --detach v4.0

The remaining examples are pinned to v4.0. When upgrading, replace the tag, download URL, and checksum with the values in the new release’s doc/build.md.

Download and verify the matching server

The host client uploads a small server program to the phone at startup. The server version must exactly match the client version.[2:1]

1
2
3
4
5
6
7
curl -fL \
-o scrcpy-server \
https://github.com/Genymobile/scrcpy/releases/download/v4.0/scrcpy-server-v4.0

printf '%s %s\n' \
'84924bd564a1eb6089c872c7521f968058977f91f5ff02514a8c74aff3210f3a' \
'scrcpy-server' | sha256sum --check

The verification command must print:

1
scrcpy-server: OK

Do not continue if the checksum does not match.

Configure and compile

Create a release build that copies the verified server into the build directory:

1
2
3
4
5
6
7
meson setup build-auto \
--buildtype=release \
--strip \
-Db_lto=true \
-Dprebuilt_server="$PWD/scrcpy-server"

ninja -C build-auto

If build-auto already exists, reconfigure it before rebuilding:

1
2
3
meson setup --reconfigure build-auto \
-Dprebuilt_server="$PWD/scrcpy-server"
ninja -C build-auto

Confirm that the copied server still has the expected checksum:

1
sha256sum build-auto/server/scrcpy-server

The local launcher syntax is important: ./run takes the build directory as its first argument, followed by normal scrcpy options.

Connect over USB

Start or refresh ADB and list its devices:

1
2
3
adb kill-server
adb start-server
adb devices -l

A healthy authorized connection resembles:

1
2
List of devices attached
DEVICE_SERIAL device usb:4-2 product:cheetah model:Pixel_7_Pro

The state must be device:

  • unauthorized means the phone needs to be unlocked and the RSA prompt accepted.
  • An empty list means ADB cannot currently communicate with the phone. Reconnect the cable, try a direct host USB port, and restart ADB.
  • offline usually requires reconnecting the phone or restarting ADB.

Launch the build and explicitly select the USB serial shown by adb devices -l:

1
2
cd "$HOME/Workspace/scrcpy"
./run build-auto --serial DEVICE_SERIAL

If only one ADB device is present, this shorter selector also works:

1
./run build-auto --select-usb

Keep the terminal process running while using the scrcpy window. Closing the window stops scrcpy.

Connect with Android Wireless Debugging

Wireless debugging is useful when the USB controller, cable, or composite MTP/ADB connection resets during transfer. It is also convenient after the host has been paired once.

Pair the host once

On the phone, open Settings → System → Developer options → Wireless debugging, then select Pair device with pairing code. The pairing screen shows a pairing IP address and port plus a six-digit code.

On the host, run:

1
adb pair PHONE_IP:PAIRING_PORT

Enter the six-digit code when prompted. The pairing port is temporary and is not normally the same port used by adb connect.[5:1]

Connect to the debugging endpoint

Return to the main Wireless debugging screen. Use the IP address & port value shown there:

1
2
adb connect PHONE_IP:DEBUG_PORT
adb devices -l

For example:

1
2
3
List of devices attached
DEVICE_SERIAL device usb:4-2 product:cheetah model:Pixel_7_Pro
192.168.1.50:37853 device product:cheetah model:Pixel_7_Pro

When both USB and TCP/IP transports are listed, select the TCP/IP serial explicitly:[4:1]

1
2
cd "$HOME/Workspace/scrcpy"
./run build-auto --serial PHONE_IP:DEBUG_PORT

The successful startup log should identify the phone and then report the renderer and video texture, for example:

1
2
3
[server] INFO: Device: [Google] google Pixel 7 Pro (Android 16)
INFO: Renderer: opengl
INFO: Texture: 1440x3120

The wireless debugging port may change after wireless debugging, Wi-Fi, or the phone is restarted. Read the current endpoint from the phone instead of assuming that an old port is still valid.

Disconnect when finished:

1
adb disconnect PHONE_IP:DEBUG_PORT

Disable wireless debugging on the phone when it is not needed, especially on an untrusted network.

Troubleshooting

Symptom Likely cause Corrective action
adb devices -l is empty USB transport did not enumerate or ADB retained stale state Unlock and reconnect the phone, try another data cable or a direct USB port, then run adb kill-server && adb start-server.
Device is unauthorized Host key has not been approved Accept the RSA prompt on the unlocked phone. Revoke USB debugging authorizations in developer options and reconnect if the prompt never appears.
adb push reports failed to read copy response and the device disappears The USB device reset during the server upload Replug the phone, change the cable/port, avoid an unstable hub, and use wireless debugging if USB continues resetting.
USB repeatedly resets with the standard ADB backend Host ADB/libusb interaction As a diagnostic, restart ADB with adb kill-server, ADB_LIBUSB=1 adb start-server, wait two seconds, and run adb devices -l again. This does not repair a bad cable or controller.
The server version (...) does not match the client (...) A stale or wrong prebuilt server was copied into the build Download the server for the exact checked-out scrcpy release, verify its checksum, reconfigure Meson, and rebuild.
Meson says the build data was generated by an incompatible version Meson was upgraded after the build directory was created Run meson setup --reconfigure build-auto and then ninja -C build-auto. If reconfiguration cannot recover the directory, create a new build directory name.
adb connect cannot reach the phone Wrong endpoint, different network, client isolation, firewall, or VPN routing Re-read IP address & port, confirm both devices are on the same reachable LAN, and temporarily disable a VPN such as WireGuard if it captures or blocks local routes. Pair again if authorization was removed.
scrcpy reports more than one device USB and Wi-Fi transports are both active Pass --serial DEVICE_SERIAL for USB or --serial PHONE_IP:DEBUG_PORT for Wi-Fi.
Wayland reports that it cannot set the window icon The compositor lacks the optional icon protocol Ignore the warning if the scrcpy window and video stream open normally.

To confirm that Linux itself still sees a phone that ADB does not list, use:

1
lsusb | grep -Ei 'Google|Pixel|18d1'

If lsusb sees the phone but ADB does not, restart ADB after reconnecting the phone. If the kernel repeatedly disconnects and re-enumerates the device during transfers, prefer a direct USB port, another cable, or wireless debugging.

Repeat-Use Checklist

After the one-time build and pairing steps, a normal wireless session only requires:

1
2
3
4
cd "$HOME/Workspace/scrcpy"
adb connect PHONE_IP:DEBUG_PORT
adb devices -l
./run build-auto --serial PHONE_IP:DEBUG_PORT

For a normal USB session:

1
2
3
cd "$HOME/Workspace/scrcpy"
adb devices -l
./run build-auto --serial DEVICE_SERIAL

Rebuild whenever the checked-out scrcpy version changes, and always keep the host client and Android server on the same release.

Sources


  1. Title: scrcpy README and prerequisites
    Publication: Genymobile/scrcpy
    Version: 4.0 ↩︎ ↩︎

  2. Title: Build scrcpy
    Publication: Genymobile/scrcpy
    Version: 4.0 ↩︎ ↩︎

  3. Title: Configure on-device developer options
    Publication: Android Developers ↩︎

  4. Title: scrcpy connection documentation
    Publication: Genymobile/scrcpy
    Version: 4.0 ↩︎ ↩︎

  5. Title: Android Debug Bridge: Connect to a device over Wi-Fi
    Publication: Android Developers ↩︎ ↩︎