Project Structure
Scrcpy for Android is built with a two-module Gradle architecture that separates client and server responsibilities:Module Configuration
The project uses Gradle’s multi-module setup defined insettings.gradle:
The client module depends on the server module. During build, the server APK is packaged as
scrcpy-server.jar and embedded into the client app’s assets.Build System
Root Configuration
The rootbuild.gradle configures common settings for all modules:
Client Module (app/)
- Package:
org.client.scrcpy - Min SDK: 21 (Android 5.0)
- Target SDK: 31 (Android 12)
- Build dependency: Automatically builds and packages the server module
app/build.gradle:49-54:
Server Module (server/)
- Package:
org.server.scrcpy - Output: APK renamed to
scrcpy-server.jar - Copied to:
app/src/main/assets/
Client-Server Communication Protocol
Scrcpy for Android uses a local TCP socket-based protocol for bidirectional communication between the client and server.Connection Flow
Data Streams
The protocol supports two types of data streams:Downstream (Server → Client)
- Device Resolution (16 bytes): Initial handshake sends width and height
- Video Packets: H.264 encoded video frames with metadata
- Audio Packets: AAC encoded audio frames with metadata
model/MediaPacket.java:
Upstream (Client → Server)
Touch Events (20 bytes per event):Connection Code Example
FromScrcpy.java:227-290, the connection establishment:
Development Workflow
Building the Project
- Compiles the server module
- Packages server APK as JAR
- Copies JAR to client assets
- Builds the client APK with embedded server
Server Deployment
When the client app connects to a remote device (MainActivity.java:746-769):
- Extracts
scrcpy-server.jarfrom assets - Writes to local storage:
context.getExternalFilesDir("scrcpy") - Pushes to remote device via ADB
- Executes with
app_process:
Code Organization
Client Module
- UI and lifecycle management
- Video/audio decoding
- Input event handling
- ADB communication
Server Module
- Screen capture
- Video/audio encoding
- Input event injection
- System service wrappers
Key Design Patterns
Service-Based Architecture
The client uses an Android Service (Scrcpy.java) for background streaming, ensuring continuity when the activity is paused.
Asynchronous Processing
Both encoding (server) and decoding (client) use worker threads to prevent blocking the main thread:VideoDecoder.Worker- Client-side decoding threadAudioDecoder.Worker- Client-side audio playback threadScreenEncoder- Server-side video encodingAudioEncoder.EncoderCallback- Server-side audio encoding
Resource Cleanup
Server auto-deletes JAR on startup (Server.java:91-92):
Next Steps
Client Module Deep Dive
Explore MainActivity, decoders, and input handling
Server Module Deep Dive
Learn about encoders, capture, and event injection
