QtScrcpy Documentation

Android real-time display control software

31,402 stars C++ C++ 1 file · ~12,257 tokens #android#qt
RAW Doc

File: README.md

QtScrcpy

中文用户?点我查看中文介绍

QtScrcpy supports displaying and controlling Android devices via USB or over network. It does NOT require root privileges.

It supports three major platforms: GNU/Linux, Windows and macOS.

It focuses on:

  • lightness (displays only the device screen)
  • performance (30~60 fps)
  • quality (1920×1080 or above)
  • low latency (35~70ms)
  • low startup time (only about 1 second to display the first frame)
  • non-intrusiveness (nothing will be installed on the device)

The author has developed a more professional screen casting software called `QuickMirror`

QuickMirror function&features:

  • Equipment screen casting&control: batch screen casting, individual control, batch control
  • Group management
  • WiFi screen mirroring/OTG screen mirroring
  • Adb shell shortcut command
  • File transfer, apk installation
  • Multiple screen mirroring: In OTG mirroring mode, with low resolution and smoothness settings, a single computer can manage 500+phones simultaneously
  • Low latency: USB screen mirroring 1080p latency is within 30ms, which is lower than all screen mirroring software on the market in terms of latency at the same resolution and smoothness
  • Low CPU usage: pure C++development, high-performance GPU video rendering
  • High resolution: adjustable, maximum support for native resolution of Android terminals
  • Perfect Chinese input: Supports Xianyu app, supports Samsung phones
  • The free version can cast up to 10 screens, with unlimited functionality (except for automatic screen mirroring)
  • QuickMirror tutorial: https://lrbnfell4p.feishu.cn/docx/EMkvdfIvDowy3UxsXUCcpPV8nDh
  • QuickMirror Telegram communication group: https://t.me/+EnQNmb47C_liYmRl
  • Preview of QuickMirror Interface:

Mapping Keys

You can write your script to map keyboard and mouse actions to touches and clicks of the mobile phone according to your needs. Here are the script writing rules.

Script for TikTok and some other games are provided by default. Once enabled, you can play the game with your keyboard and mouse. The default key mapping for PUBG Mobile is as follows:

Instruction for adding new customized mapping files.

  • Write a customized script and put it in the keymap directory
  • Click refresh script to show it
  • Select your script
  • Connect to your phone, start service and click apply
  • Press ~ key (the SwitchKey in the key map script) to switch to custom mapping mode
  • Press the ~ key again to switch back to normal mode
  • (For games such as PUBG Mobile) If you want to move vehicles with the STEER_WHEEL keys, you need to set the move mode to single rocker mode.

If you don't know how to manually write mapping rules, you can also use the QuickAssistant developed by the author
QuickAssistant Features&Functions:

  • Play Android mobile games smoothly through keyboard and mouse
  • Interface based editing of key mapping script
  • Support pausing the computer screen and using only keyboard and mouse operations
  • Screenshot&Recording of Mobile Screen
  • Simple batch control
  • Android 11+supports playing mobile audio on computers (under development...)
  • Mobile app installation free
  • Fast and instant connection
  • Low latency: USB screen mirroring 1080p latency is within 30ms, which is lower than all screen mirroring software on the market in terms of latency at the same resolution and smoothness
  • Low CPU usage: pure C++development, high-performance GPU video rendering
  • High resolution: adjustable, maximum support for native resolution of Android terminals
  • Telegram Group:https://t.me/+Ylf_5V_rDCMyODQ1
  • QuickAssistant

Group control

You can control all your phones at the same time.

Star History

Thanks

QtScrcpy is based on Genymobile's scrcpy project. Thanks a lot!

The difference between QtScrcpy and the original scrcpy is as follows:

key points scrcpy QtScrcpy
ui sdl qt
video encode ffmpeg ffmpeg
video render sdl opengl
cross-platform self implemented provided by Qt
language C C++
style sync async
keymap no custom keymap support custom keymap
build meson+gradle qmake or CMake
  • It's very easy to customize your GUI with Qt
  • Asynchronous programming of Qt-based signal slot mechanism improves performance
  • Easy to learn
  • Add support for multi-touch

Learn

If you are interested in it and want to learn how it works but do not know how to get started, you can choose to purchase my recorded video lessons.
It details the development architecture and the development process of the entire software and helps you develop QtScrcpy from scratch.

Course introduction:https://blog.csdn.net/rankun1/article/details/87970523

You can join Telegram Group for QtScrcpy and exchange ideas with like-minded friends.:

Telegram Group:https://t.me/+EnQNmb47C_liYmRl

Requirements

Android API >= 21 (Android 5.0).

Make sure you have enabled ADB debugging on your device(s).

Download

Windows

On Windows, for simplicity, prebuilt archives with all the dependencies (including ADB) are available at Releases:

or you can build it yourself

Mac OS

On Mac OS, for simplicity, prebuilt archives with all the dependencies (including ADB) are available at Releases:

or you can build it yourself

Linux

For Arch Linux Users, you can use AUR to install: yay -Syu qtscrcpy (may be outdated; maintainer: yochananmarqos)

For users in other distros, you can use the prebuilt archives from Releases:

or you can get it at GitHub Actions, in branch dev and download the latest artifact.

or you can build it yourself (not recommended, get it in Actions if you can)

Run

Connect to your Android device on your computer, then run the program and click USB connect or WiFi connect

Wireless connection steps (ensure that the mobile phone and PC are on the same LAN):

  1. Enable USB debugging in developer options on the Android device
  2. Connect the Android device to the computer via USB
  3. Click update device, and you will see that the device number is updated
  4. Click get device IP
  5. Click start adbd
  6. Click wireless connect
  7. Click update device again, and another device with an IP address will be found. Select this device.
  8. Click start service

Note: it is not necessary to keep your Android device connected via USB after you start adbd.

Interface button introduction:

  • Start config: function parameter settings before starting the service

    You can set the bit rate, resolution, recording format, and video save path of the locally recorded video.

    • Background record: the Android device screen is not displayed after starting the service. It is recorded in the background.
    • Always on top: the video window for Android devices will be kept on the top
    • Close screen: automatically turn off the Android device screen to save power after starting the service
    • Reverse connection: service startup mode. You can uncheck it if you experience connection failure with a message more than one device
  • Refresh devices: Refresh the currently connected device

  • Start service: connect to the Android device

  • Stop service: disconnect from the Android device

  • Stop all services: disconnect all connected Android devices

  • Get device IP: Get the IP address of the Android device and update it to the "Wireless" area for the ease of wireless connection setting.

  • Start adbd: Start the adbd service of the Android device. You must start it before the wireless connection.

  • Wireless connect: Connect to Android devices wirelessly

  • Wireless disconnect: Disconnect wirelessly connected Android devices

  • adb command: execute customized ADB commands (blocking commands are not supported now, such as a shell)

The main function

  • Display Android device screens in real-time

  • Real-time mouse and keyboard control of Android devices

  • Screen recording

  • Screenshot to png

  • Wireless connection

  • Supports multiple device connections

  • Full-screen display

  • Display on the top

  • Install apk: drag and drop apk to the video window to install

  • Transfer files: Drag files to the video window to send files to Android devices

  • Background recording: record only, no display interface

  • Copy-paste

    It is possible to synchronize clipboards between the computer and the device, in
    both directions:

    • Ctrl + c copies the device clipboard to the computer clipboard;
    • Ctrl + Shift + v copies the computer clipboard to the device clipboard;
    • Ctrl + v pastes the computer clipboard as a sequence of text events (non-ASCII characters does not yet work).
  • Group control

  • Sync device speaker sound to the computer (based on sndcpy, Android 10+ only)

Shortcuts

Action Shortcut (Windows) Shortcut (macOS)
Switch fullscreen mode Ctrl+f Cmd+f
Resize window to 1:1 (pixel-perfect) Ctrl+g Cmd+g
Resize window to remove black borders Ctrl+w | Double-click¹ Cmd+w | Double-click¹
Click on HOME Ctrl+h | Middle-click Ctrl+h | Middle-click
Click on BACK Ctrl+b | Right-click² Cmd+b | Right-click²
Click on APP_SWITCH Ctrl+s Cmd+s
Click on MENU Ctrl+m Ctrl+m
Click on VOLUME_UP Ctrl+↑ (up) Cmd+↑ (up)
Click on VOLUME_DOWN Ctrl+↓ (down) Cmd+↓ (down)
Click on POWER Ctrl+p Cmd+p
Power on Right-click² Right-click²
Turn device screen off (keep mirroring) Ctrl+o Cmd+o
Expand notification panel Ctrl+n Cmd+n
Collapse notification panel Ctrl+Shift+n Cmd+Shift+n
Copy to clipboard³ Ctrl+c Cmd+c
Cut to clipboard³ Ctrl+x Cmd+x
Synchronize clipboards and paste³ Ctrl+v Cmd+v
Inject computer clipboard text Ctrl+Shift+v Cmd+Shift+v

¹Double-click on black borders to remove them.

²Right-click turns the screen on if it was off, presses BACK otherwise.

³Only on Android >= 7.

TODO

TODO

FAQ

FAQ

DEVELOP

DEVELOP

Everyone is welcome to maintain this project and contribute your own code, but please follow these requirements:

  1. Please open PRs to the dev branch instead of the master branch
  2. Please rebase the original project before opening PRs
  3. Please submit PRs on the principle of "small amounts, many times" (one PR for a change is recommended)
  4. Please keep the code style consistent with the existing style.

Why develop QtScrcpy?

There are several reasons listed below according to importance (high to low).

  1. In the process of learning Qt, I need a real project to try.
  2. I have some background skills in audio and video and I am interested in them.
  3. I have some Android development skills. But I have used it for a long time. I want to consolidate it.
  4. I found scrcpy and decided to re-make it with the new technology stack (C++ + Qt + Opengl + FFmpeg).

Build

All the dependencies are provided and it is easy to compile.

QtScrcpy

Non-Arch Linux Users

  1. Set up the Qt development environment with the official Qt installer or third-party tools such as aqt on the target platform.
    Qt version bigger than 5.12 is required. (use MSVC 2019 on Windows)
  2. Clone the project with git clone --recurse-submodules [email protected]:barry-ran/QtScrcpy.git
  3. For Windows, open CMakeLists.txt with QtCreator and compile Release
  4. For Linux, directly run ./ci/linux/build_for_linux.sh "Release"
    Note: compiled artifacts are located at output/x64/Release

Arch Linux Users

  1. Install packages: base-devel cmake qt5-base qt5-multimedia qt5-x11extras (qtcreator is recommended)
  2. Clone the project with git clone --recurse-submodules [email protected]:barry-ran/QtScrcpy.git
  3. Run ./ci/linux/build_for_linux.sh "Release"

Scrcpy-Server

  1. Set up Android development environment on the target platform
  2. Open server project in project root with Android Studio
  3. The first time you open it, if you do not have the corresponding version of Gradle, you will be prompted to find Gradle, whether to upgrade Gradle or create it. Select Cancel. After cancelling, you will be prompted to select the location of existing Gradle. Cancel it too and it will download automatically.
  4. After compiling the apk, rename it to scrcpy-server and replace QtScrcpy/QtScrcpyCore/src/third_party/scrcpy-server.

Licence

Since it is based on scrcpy, it uses the same license as scrcpy

text
Copyright (C) 2025 Rankun

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

About the author

Barry CSDN

An ordinary programmer, working mainly in C++ for desktop client development, graduated from Shandong for more than a year of steel simulation education software, and later moved to Shanghai to work in security, online education-related fields, familiar with audio and video. I have an understanding of audio and video fields such as voice calls, live education, video conferencing and other related solutions. I also have experience in Android, Linux servers and other kinds of development.

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]











File: docs/DEVELOP.md

scrcpy for developers

Overview

This application is composed of two parts:

  • the server (scrcpy-server), to be executed on the device,
  • the client (the scrcpy binary), executed on the host computer.

The client is responsible to push the server to the device and start its
execution.

Once the client and the server are connected to each other, the server initially
sends device information (name and initial screen dimensions), then starts to
send a raw H.264 video stream of the device screen. The client decodes the video
frames, and display them as soon as possible, without buffering, to minimize
latency. The client is not aware of the device rotation (which is handled by the
server), it just knows the dimensions of the video frames.

The client captures relevant keyboard and mouse events, that it transmits to the
server, which injects them to the device.

Server

Privileges

Capturing the screen requires some privileges, which are granted to shell.

The server is a Java application (with a public static void main(String... args) method), compiled against the Android framework, and executed as
shell on the Android device.

To run such a Java application, the classes must be dexed (typically,
to classes.dex). If my.package.MainClass is the main class, compiled to
classes.dex, pushed to the device in /data/local/tmp, then it can be run
with:

text
adb shell CLASSPATH=/data/local/tmp/classes.dex \
    app_process / my.package.MainClass

The path /data/local/tmp is a good candidate to push the server, since it's
readable and writable by shell, but not world-writable, so a malicious
application may not replace the server just before the client executes it.

Instead of a raw dex file, app_process accepts a jar containing
classes.dex (e.g. an APK). For simplicity, and to benefit from the gradle
build system, the server is built to an (unsigned) APK (renamed to
scrcpy-server).

Hidden methods

Although compiled against the Android framework, hidden methods and classes are
not directly accessible (and they may differ from one Android version to
another).

They can be called using reflection though. The communication with hidden
components is provided by wrappers classes and aidl.

Threading

The server uses 3 threads:

  • the main thread, encoding and streaming the video to the client;
  • the controller thread, listening for control messages (typically,
    keyboard and mouse events) from the client;
  • the receiver thread (managed by the controller), sending device messges
    to the clients (currently, it is only used to send the device clipboard
    content).

Since the video encoding is typically hardware, there would be no benefit in
encoding and streaming in two different threads.

Screen video encoding

The encoding is managed by ScreenEncoder.

The video is encoded using the MediaCodec API. The codec takes its input
from a surface associated to the display, and writes the resulting H.264
stream to the provided output stream (the socket connected to the client).

On device rotation, the codec, surface and display are reinitialized, and a
new video stream is produced.

New frames are produced only when changes occur on the surface. This is good
because it avoids to send unnecessary frames, but there are drawbacks:

  • it does not send any frame on start if the device screen does not change,
  • after fast motion changes, the last frame may have poor quality.

Both problems are solved by the flag
KEY_REPEAT_PREVIOUS_FRAME_AFTER.

Input events injection

Control messages are received from the client by the Controller (run in a
separate thread). There are several types of input events:

  • keycode (cf KeyEvent),
  • text (special characters may not be handled by keycodes directly),
  • mouse motion/click,
  • mouse scroll,
  • other commands (e.g. to switch the screen on or to copy the clipboard).

Some of them need to inject input events to the system. To do so, they use the
hidden method InputManager.injectInputEvent (exposed by our
InputManager wrapper).

Client

The client relies on SDL, which provides cross-platform API for UI, input
events, threading, etc.

The video stream is decoded by libav (FFmpeg).

Initialization

On startup, in addition to libav and SDL initialization, the client must
push and start the server on the device, and open two sockets (one for the video
stream, one for control) so that they may communicate.

Note that the client-server roles are expressed at the application level:

  • the server serves video stream and handle requests from the client,
  • the client controls the device through the server.

However, the roles are reversed at the network level:

  • the client opens a server socket and listen on a port before starting the
    server,
  • the server connects to the client.

This role inversion guarantees that the connection will not fail due to race
conditions, and avoids polling.

(Note that over TCP/IP, the roles are not reversed, due to a bug in adb reverse. See commit 1038bad and issue #5.)

Once the server is connected, it sends the device information (name and initial
screen dimensions). Thus, the client may init the window and renderer, before
the first frame is available.

To minimize startup time, SDL initialization is performed while listening for
the connection from the server (see commit 90a46b4).

Threading

The client uses 4 threads:

  • the main thread, executing the SDL event loop,
  • the stream thread, receiving the video and used for decoding and
    recording,
  • the controller thread, sending control messages to the server,
  • the receiver thread (managed by the controller), receiving device
    messages
    from the server.

In addition, another thread can be started if necessary to handle APK
installation or file push requests (via drag&drop on the main window) or to
print the framerate regularly in the console.

Stream

The video stream is received from the socket (connected to the server on the
device) in a separate thread.

If a decoder is present (i.e. --no-display is not set), then it uses libav
to decode the H.264 stream from the socket, and notifies the main thread when a
new frame is available.

There are two frames simultaneously in memory:

  • the decoding frame, written by the decoder from the decoder thread,
  • the rendering frame, rendered in a texture from the main thread.

When a new decoded frame is available, the decoder swaps the decoding and
rendering frame (with proper synchronization). Thus, it immediatly starts
to decode a new frame while the main thread renders the last one.

If a recorder is present (i.e. --record is enabled), then it muxes the raw
H.264 packet to the output video file.

text
+----------+      +----------+
                              ---> | decoder  | ---> |  screen  |
             +---------+     /     +----------+      +----------+
 socket ---> | stream  | ----
             +---------+     \     +----------+
                              ---> | recorder |
                                   +----------+

Controller

The controller is responsible to send control messages to the device. It
runs in a separate thread, to avoid I/O on the main thread.

On SDL event, received on the main thread, the input manager
creates appropriate control messages. It is responsible to
convert SDL events to Android events (using convert). It pushes the control
messages
to a queue hold by the controller. On its own thread, the controller
takes messages from the queue, that it serializes and sends to the client.

UI and event loop

Initialization, input events and rendering are all managed in the main
thread.

Events are handled in the event loop, which either updates the screen or
delegates to the input manager.

Hack

For more details, go read the code!

If you find a bug, or have an awesome idea to implement, please discuss and
contribute ;-)

Debug the server

The server is pushed to the device by the client on startup.

To debug it, enable the server debugger during configuration:

bash
meson x -Dserver_debugger=true
# or, if x is already configured
meson configure x -Dserver_debugger=true

If your device runs Android 8 or below, set the server_debugger_method to
old in addition:

bash
meson x -Dserver_debugger=true -Dserver_debugger_method=old
# or, if x is already configured
meson configure x -Dserver_debugger=true -Dserver_debugger_method=old

Then recompile.

When you start scrcpy, it will start a debugger on port 5005 on the device.
Redirect that port to the computer:

bash
adb forward tcp:5005 tcp:5005

In Android Studio, Run > Debug > Edit configurations... On the left, click on
+, Remote, and fill the form:

  • Host: localhost
  • Port: 5005

Then click on Debug.


File: docs/FAQ.md

Frequently Asked Questions

一些经常问的问题

如果在此文档没有解决你的问题,描述你的问题,截图软件控制台中打印的日志,一起发到QQ群里提问。

adb问题

ADB版本之间的冲突

text
adb server version (41) doesn't match this client (39); killing...

当你的电脑中运行不同版本的adb时,会发生此错误。你必须保证所有程序使用相同版本的adb。
现在你有两个办法解决这个问题:

  1. 任务管理器找到adb进程并杀死
  2. 配置QtScrcpy的config.ini中的AdbPath路径指向当前使用的adb

手机通过数据线连接电脑,刷新设备列表以后,没有任何设备出现

随便下载一个手机助手,尝试连接成功以后,再用QtScrcpy刷新设备列表连接

控制问题

可以看到画面,但无法控制

有些手机(小米等手机)需要额外打开控制权限,检查是否USB调试里打开了允许模拟点击

.jpg)

其它

支持声音(软件不做支持)

关于转发安卓声音到PC的讨论

画面不清晰

在Windows上,您可能需要配置缩放行为。

QtScrcpy.exe>属性>兼容性>更改高DPI设置>覆盖高DPI缩放行为>由以下人员执行缩放:应用程序。

如果视频窗口大小远远小于设备屏幕的大小,则画面会不清晰。这在文字上尤其明显

玩和平精英上下车操作会失效

这是由于游戏中上车会创建新的界面,导致鼠标触摸点失效,目前技术上没有好的解决办法

可以通过连续按两次~键(数字键1左边)来恢复,这是目前最好的办法。

无法输入中文

手机端安装搜狗输入法/QQ输入法就可以支持输入中文了

可以控制,但无法看到画面

控制台错误信息可能会包含 QOpenGLShaderProgram::attributeLocation(vertexIn): shader program is not linked

一般是由于显卡不支持当前的视频渲染方式,config.ini里修改下解码方式,改成1或者2试试

错误信息:AdbProcess::error:adb server version (40) doesnt match this client (41)

任务管理找到adb进程并杀死,重新操作即可

错误信息:Could not open video stream

导致这个错误的原因有很多,最简单的解决方法是在分辨率设置中,选择一个较低的分辨率


File: docs/KeyMapDes.md

Custom key mapping instructions

The key map file is in json format, and the new key map file needs to be placed in the keymap directory to be recognized by QtScrcpy.

The specific writing format of the button mapping file will be introduced below, and you can also refer to the button mapping file that comes with it.

Key mapping script format description

General Instructions

-The coordinate positions in the key map are all expressed by relative positions, and the width and height of the screen are expressed by 1, for example, the pixels of the screen are 1920x1080, then the coordinates (0.5,0.5) indicate
Taking the upper left corner of the screen as the origin, the position of the pixel coordinates (1920,1080)*(0.5,0.5)=(960,540).

text
Or when the left mouse button clicks, the console will output the pos at this time, just use this pos directly

-The key codes in the key map are represented by Qt enumerations, detailed description can be refer to Qt documentation (search for The key names used by Qt. can be quickly located).
-Open the following two settings in the developer options, you can easily observe the coordinates of the touch point:

Mapping type description

-switchKey: Switch the key of the custom key mapping. The default is the normal mapping. You need to use this key to switch between the normal mapping and the custom mapping.

-mouseMoveMap: mouse movement mapping, the movement of the mouse will be mapped to startPos as the starting point, and the direction of the mouse movement as the direction of the finger drag operation (after the mouse movement map is turned on, the mouse will be hidden, limiting the range of mouse movement).
Generally used to adjust the character field of vision in FPS mobile games.
-startPos finger drag starting point
-speedRatio mouse sensitivity of the finger dragging. The value must be at least 0.00225. The greater the value, the lower the sensitivity. The Y-axis translates with a ratio of 2.25. If this does not fit your phone screen, please use the following two settings to set individual sensitivity values.
-speedRatioX sensitivity of the mouse X-axis. This value must be at least 0.001.
-speedRatioY sensitivity of the mouse Y-axis. This value must be at least 0.001.
-smallEyes The button that triggers the small eyes. After pressing this button, the mouse movement will be mapped to the finger drag operation with the smallEyes.pos as the starting point and the mouse movement direction as the movement direction

-keyMapNodes general key map, json array, all general key maps are placed in this array, map the keys of the keyboard to ordinary finger clicks.

There are several types of key mapping as follows:

-type The type of key mapping, each element in keyMapNodes needs to be specified, and can be of the following types:
-KMT_CLICK Ordinary click, key press simulates finger press, key lift simulates finger lift
-KMT_CLICK_TWICE Double click, key press simulates finger press and then lift, key lift simulates finger press and then lift
- KMT_CLICK_MULTI Click multiple times. According to the delay and pos in the clickNodes array, press one key to simulate touching multiple positions
-KMT_DRAG drag and drop, the key press is simulated as a finger press and drag a distance, the key lift is simulated as a finger lift
-KMT_STEER_WHEEL steering wheel mapping, which is dedicated to the mapping of the steering wheel for moving characters in FPS games, requires 4 buttons to cooperate.

Description of the unique attributes of different key mapping types:

-KMT_CLICK
-key The key code to be mapped
-pos simulates the location of the touch
-Whether the switchMap releases the mouse. After clicking this button, besides the default simulated touch map, whether the mouse operation is released. (You can refer to the effect of M map mapping in Peace Elite Map)

-KMT_CLICK_TWICE
-key The key code to be mapped
-pos Simulates the location of the touch

-KMT_CLICK_MULTI
-delay Delay delay ms before simulating touch
-pos Simulates the location of the touch

-KMT_DRAG
-key The key code to be mapped
-startPos Simulate the start position of touch drag
-endPos Simulate the end position of touch drag
-dragSpeed Speed of the drag movement (range 0-1, default 1.0). Higher values result in faster movements
-startDelay Optional delay in milliseconds to wait after the initial touch before starting the drag movement

-KMT_STEER_WHEEL
-centerPos steering wheel center point
-leftKey key control in the left direction
-rightKey Right key control
-UpKey key control
-downKey key control in down direction
-leftOffset After dragging the left arrow key, drag to the leftOffset horizontally to the centerPos
-rightOffset After pressing the right direction key, drag it to the right offset of the center to the right of the centerPos position
-upOffset After pressing the up arrow key, drag it to the upper offset position horizontally relative to the centerPos position
-downOffset Press the down arrow key and drag it to the downOffset position horizontally relative to the centerPos position

Visual Key Mapping Tool

  1. Just use QuickAssistant

  2. A web-based GUI tool is available to help you create and manage key mappings visually: ScrcpyKeyMapper

You can use this tool to:

  • Create key mappings visually
  • Test your mappings in real-time
  • Export mappings as JSON files
  • Import existing mappings for editing

Try it online: ScrcpyKeyMapper Web App


File: docs/KeyMapDes_zh.md

自定义按键映射说明

按键映射文件为json格式,新增自己的按键映射文件需要放在keymap目录中才可以被QtScrcpy识别。

按键映射文件的具体编写格式下面会介绍,也可以参考自带的按键映射文件。

按键映射脚本格式说明

通用说明

  • 按键映射中的坐标位置都是用相对位置表示的,屏幕的宽高都用1表示,例如屏幕的像素为1920x1080,那么坐标(0.5,0.5)则表示的是
    以屏幕左上角为原点,像素坐标(1920,1080)*(0.5,0.5)=(960,540)的位置。

    或者鼠标左键单击时控制台会输出此时的pos,直接使用这个pos即可

  • 按键映射中的按键码是用Qt的枚举表示的,详细说明可以参考Qt文档(搜索 The key names used by Qt. 可以快速定位)。

  • 开发人员选项中打开如下两个设置,可以方便的观察触摸点的坐标:

映射类型说明

  • switchKey:切换自定义按键映射的开关键,默认为普通映射,需要使用这个按键在普通映射和自定义映射之间切换。

  • mouseMoveMap:鼠标移动映射,鼠标的移动将被映射为以startPos为起点,以鼠标移动方向为移动方向的手指拖动操作(开启鼠标移动映射以后会隐藏鼠标,限制鼠标移动范围)。
    一般在FPS手游中用来调整人物视野。

    • startPos 手指拖动起始点
    • speedRatio 鼠标移动映射为手指拖动的比例,可以控制鼠标灵敏度,数值要大于0.00225,数值越大,灵敏度越低,Y轴以2.25的比率平移。如果这不适合您的手机屏幕,请使用以下两种设置来设置单个灵敏度值。
    • speedRatioX 鼠标X轴的速度比灵敏度。此值必须至少为0.001。
    • speedRatioY 鼠标Y轴的速度比灵敏度。此值必须至少为0.001。
    • smallEyes 触发小眼睛的按键,按下此按键以后,鼠标的移动将被映射为以smallEyes.pos为起点,以鼠标移动方向为移动方向的手指拖动操作
  • keyMapNodes 一般按键的映射,json数组,所有一般按键映射都放在这个数组中,将键盘的按键映射为普通的手指点击。

一般按键映射有如下几种类型:

  • type 按键映射的类型,每个keyMapNodes中的元素都需要指明,可以是如下类型:
    • KMT_CLICK 普通点击,按键按下模拟为手指按下,按键抬起模拟为手指抬起
    • KMT_CLICK_TWICE 两次点击,按键按下模拟为手指按下再抬起,按键抬起模拟为手指按下再抬起
    • KMT_CLICK_MULTI 多次点击,根据clickNodes数组中的delay和pos实现一个按键多次点击
    • KMT_DRAG 拖拽,按键按下模拟为手指按下并拖动一段距离,按键抬起模拟为手指抬起
    • KMT_STEER_WHEEL 方向盘映射,专用于FPS游戏中移动人物脚步的方向盘的映射,需要4个按键来配合。

不同按键映射类型的专有属性说明:

  • KMT_CLICK

    • key 要映射的按键码
    • pos 模拟触摸的位置
    • switchMap 是否释放出鼠标,点击此按键后,除了默认的模拟触摸映射,是否释放出鼠标操作。(可以参考和平精英映射中M地图映射的效果)
  • KMT_CLICK_TWICE

    • key 要映射的按键码
    • pos 模拟触摸的位置
  • KMT_CLICK_MULTI

    • delay 延迟delay毫秒以后再模拟触摸
    • pos 模拟触摸的位置
  • KMT_DRAG

    • key 要映射的按键码
    • startPos 模拟触摸拖动的开始位置
    • endPos 模拟触摸拖动的结束位置
    • dragSpeed 拖动移动的速度(范围0-1,默认1.0)。数值越大,移动越快
    • startDelay 可选的延迟时间(毫秒),在开始拖动移动之前等待指定的时间
  • KMT_STEER_WHEEL

    • centerPos 方向盘中心点
    • leftKey 左方向的按键控制
    • rightKey 右方向的按键控制
    • upKey 上方向的按键控制
    • downKey 下方向的按键控制
    • leftOffset 按下左方向键后模拟拖动到相对centerPos位置水平偏左leftOffset处
    • rightOffset 按下右方向键后模拟拖动到相对centerPos位置水平偏右rightOffset处
    • upOffset 按下上方向键后模拟拖动到相对centerPos位置水平偏上upOffset处
    • downOffset 按下下方向键后模拟拖动到相对centerPos位置水平偏下downOffset处

可视化按键映射工具

  1. 直接使用QuickAssistant

  2. 还有一个基于Web的GUI工具可以帮助你直观地创建和管理按键映射:ScrcpyKeyMapper

你可以使用这个工具来:

  • 直观地创建按键映射
  • 实时测试你的映射
  • 导出映射为JSON文件
  • 导入现有映射进行编辑

在线试用:ScrcpyKeyMapper网页应用


File: docs/TODO.md

TODO

低优先级

中优先级

高优先级

mark

ffmpeg

ffmpeg编译参数详解

fontawesome

fontawesome 在线搜索

adb

以下是 ADB 和 Fastboot 的谷歌官方下载链接:

ADB和Fastboot for Windows

https://dl.google.com/android/repository/platform-tools-latest-windows.zip

ADB和Fastboot for Mac

https://dl.google.com/android/repository/platform-tools-latest-darwin.zip

ADB和Fastboot for Linux

https://dl.google.com/android/repository/platform-tools-latest-linux.zip

由于这些是直接的 Google 链接,用户可以确保下载不仅是官方的,而且将始终能够获得最新版本的 ADB 和 Fastboot


File: README_zh.md

QtScrcpy

Speaks English? Click me for English introduction.

QtScrcpy 可以通过 USB / 网络连接Android设备,并进行显示和控制。无需root权限。

同时支持 GNU/Linux ,Windows 和 MacOS 三大主流桌面平台。

它专注于:

  • 精致 (仅显示设备屏幕)
  • 性能 (30~60fps)
  • 质量 (1920×1080以上)
  • 低延迟 (35~70ms)
  • 快速启动 (1s 内就可以看到第一帧图像)
  • 非侵入性 (不在设备上安装任何软件)

作者开发了更加专业的投屏软件`极限投屏`

极限投屏功能&特点:

  • 设备投屏&控制:批量投屏、单个控制、批量控制
  • 分组管理
  • wifi投屏/OTG投屏
  • adb shell快捷指令
  • 文件传输、apk安装
  • 投屏数量多:在OTG投屏模式,设置分辨率和流畅度为低的情况下,单台电脑可以同时管理500+台手机
  • 低延迟:usb投屏1080p延迟在30ms以内,在相同分辨率流畅度情况下,比市面上所有投屏软件延迟都低
  • cpu占用率低:纯C++开发,高性能GPU视频渲染
  • 高分辨率:可调节,最大支持安卓终端的原生分辨率
  • 完美中文输入:支持闲鱼app,支持三星手机
  • 免费版最多投屏10台,功能无限制(除了自动重新投屏)
  • 极限投屏使用教程:https://lrbnfell4p.feishu.cn/docx/QRMhd9nImorAGgxVLlmczxSdnYf
  • 极限投屏qq交流群:822464342
  • 极限投屏界面预览:

自定义按键映射

可以根据需要,自己编写脚本将键盘按键映射为手机的触摸点击,编写规则在这里。

默认自带了针对和平精英手游和抖音进行键鼠映射的映射脚本,开启平精英手游后可以用键鼠像玩端游一样玩和平精英手游,开启抖音映射以后可以使用上下左右方向键模拟上下左右滑动,你也可以按照编写规则编写其他游戏的映射文件,默认按键映射如下:

自定义按键映射操作方法如下:

  • 编写自定义脚本放入 keymap 目录
  • 点击刷新脚本,确保脚本可以被检测到
  • 选择需要的脚本
  • 连接手机并启动服务之后,点击应用脚本
  • 按~(即脚本中定义的 SwitchKey)键切换为自定义映射模式即可启用
  • 再次按~键切换为正常控制模式
  • (对于和平精英等游戏)若想使用方向盘控制载具,记得在载具设置中设置为单摇杆模式

如果不会自己手写映射规则,也可以去使用作者开发的极限手游助手
极限手游助手功能&特点:

  • 通过键盘鼠标畅玩安卓手机游戏
  • 按键映射脚本界面化编辑
  • 支持暂停电脑端画面,只使用键鼠操作
  • 截图&录制手机画面
  • 简单批量控制
  • 安卓11+支持电脑播放手机音频(开发中...)
  • 手机端免安装App
  • 极速秒连接
  • 低延迟:usb投屏1080p延迟在30ms以内,在相同分辨率流畅度情况下,比市面上所有投屏软件延迟都低
  • cpu占用率低:纯C++开发,高性能GPU视频渲染
  • 高分辨率:可调节,最大支持安卓终端的原生分辨率
  • QQ交流群:901736468
  • 极限手游助手说明文档

批量操作

你可以同时控制所有的手机

Star历史

感谢

基于Genymobile的scrcpy项目进行复刻,重构,非常感谢。

比较

QtScrcpy 和 Scrcpy 区别如下:

关键点 scrcpy QtScrcpy
界面 sdl qt
视频解码 ffmpeg ffmpeg
视频渲染 sdl opengl
跨平台基础设施 自己封装 Qt
编程语言 C C++
编程方式 同步 异步
按键映射 不支持自定义 支持自定义按键映射
编译方式 Meson+Gradle CMake
  • 使用Qt可以非常容易的定制自己的界面
  • 基于Qt的信号槽机制的异步编程提高性能
  • 方便新手学习
  • 增加多点触控支持

学习它

如果你对它感兴趣,想学习它的实现原理而又感觉无从下手,可以选择购买我录制的视频课程,
里面详细介绍了整个软件的开发架构以及开发流程,带你从无到有的开发 QtScrcpy:

课程介绍:https://blog.csdn.net/rankun1/article/details/87970523

或者你也可以加入我的 QtScrcpy QQ 群,和志同道合的朋友一块互相交流技术:

QQ群号:901736468

要求

Android 部分至少需要 API 21(Android 5.0)。

您要确保在 Android 设备上启用adb调试。

下载

Windows

Windows 平台,你可以直接使用我编译好的可执行程序:

你也可以自己编译

Mac OS

Mac OS 平台,你可以直接使用我编译好的可执行程序:

你也可以自己编译

Linux

对于 Arch Linux 用户,可以使用 AUR 安装:yay -Syu qtscrcpy(可能版本并非最新;维护者:yochananmarqos)

其他发行版的用户可以直接使用我编译好的可执行程序:

你也可以从 GitHub Actions 获取最新的自动编译好的软件

当然,你也可以自己编译(不推荐,需要准备环境)

目前只在 Ubuntu 和 Arch Linux 上测试过编译过程

运行

在你的电脑上接入Android设备,然后运行程序,点击 一键USB连接 或者 一键WIFI连接

无线连接步骤

  1. 将手机和电脑连接到同一局域网
  2. 安卓手机端在开发者选项中打开 USB 调试
  3. 通过 USB 连接安卓手机到电脑
  4. 点击刷新设备,会看到有设备号更新出来
  5. 点击获取设备 IP
  6. 点击启动 adbd
  7. 无线连接
  8. 再次点击刷新设备,发现多出了一个 IP 地址开头的设备,选择这个设备
  9. 启动服务

备注:启动 adbd 以后无需继续连接 USB 线,以后连接断开都不再需要,除非 adbd 停止运行

界面解释

  • 启动配置:启动服务前的功能参数设置

    分别可以设置本地录制视频的比特率、分辨率、录制格式、录像保存路径等。

    • 仅后台录制:启动服务不显示界面,只录制 Android 设备屏幕
    • 窗口置顶:Android 设备显示窗口置顶
    • 自动息屏:启动服务以后,自动关闭 Android 设备屏幕以节省电量
    • 使用 Reverse:服务启动模式,出现服务启动失败报错 "more than one device" 可以去掉这个勾选尝试连接
  • 刷新设备列表:刷新当前连接的设备

  • 启动服务:连接到 Android 设备

  • 停止服务:断开与 Android 设备的连接

  • 停止所有服务:断开所有已连接的 Android 设备

  • 获取设备ip:获取到 Android 设备的 IP 地址,更新到无线区域中,方便进行无线连接

  • 启动adbd:启动 Android 设备的 adbd 服务,无线连接之前,必须要启动

  • 无线连接:使用无线方式连接 Android 设备

  • 无线断开:断开无线方式连接的 Android 设备

  • 命令行:执行自定义 adb 命令(目前不支持阻塞命令,例如shell)

功能

  • 实时显示 Android 设备屏幕
  • 实时键鼠控制Android设备
  • 屏幕录制
  • 截图
  • 无线连接
  • 多设备连接与批量操作
  • 全屏显示
  • 窗口置顶
  • 安装 apk:拖拽apk到显示窗口即可安装
  • 传输文件:拖拽文件到显示窗口即可发送文件到 Android 设备
  • 后台录制:只录制屏幕,不显示界面
  • 剪贴板同步:
    在计算机和设备之间同步剪贴板:
    • Ctrl + c将设备剪贴板复制到计算机剪贴板;
    • Ctrl + Shift + v将计算机剪贴板复制到设备剪贴板;
    • Ctrl + v 将计算机剪贴板作为一系列文本事件发送到设备(不支持非ASCII字符)
  • 同步设备扬声器声音到电脑(基于sndcpy,仅支持安卓10级以上,目前不推荐使用,可使用蓝牙连接替代)

快捷键

功能 快捷键(Windows) 快捷键 (macOS)
切换全屏 Ctrl+f Cmd+f
调整窗口大小为 1:1 Ctrl+g Cmd+g
调整窗口大小去除黑边 Ctrl+w | 左键双击 Cmd+w | 左键双击
点击 主页 Ctrl+h | 点击鼠标中键 Ctrl+h | 点击鼠标中键
点击 BACK Ctrl+b | 右键双击 Cmd+b | 右键双击
点击 APP_SWITCH Ctrl+s Cmd+s
点击 MENU Ctrl+m Ctrl+m
点击 VOLUME_UP Ctrl+↑ (上) Cmd+↑ (上)
点击 VOLUME_DOWN Ctrl+↓ (下) Cmd+↓ (下)
点击 POWER Ctrl+p Cmd+p
打开电源 右键双击 右键双击
关闭屏幕 (保持投屏) Ctrl+o Cmd+o
打开下拉菜单 Ctrl+n Cmd+n
关闭下拉菜单 Ctrl+Shift+n Cmd+Shift+n
复制到剪切板 Ctrl+c Cmd+c
剪切到剪切板 Ctrl+x Cmd+x
同步剪切板并粘贴 Ctrl+v Cmd+v
注入电脑剪切板文本 Ctrl+Shift+v Cmd+Shift+v

鼠标左键双击黑色区域可以去除黑色区域

如果电源关闭,鼠标右键双击打开电源;如果电源开启,鼠标右键双击相当于返回

TODO

后期计划

FAQ

常见问题说明

开发者

开发相关

欢迎大家一起维护这个项目,贡献自己的代码,不过请遵循以下几点要求:

  1. PR 请推向 dev 分支,不要推向 master 分支
  2. 提交 PR 之前请先变基原项目
  3. PR 请以少量多次的原则提交(即一个功能点提交一个 PR)
  4. 代码风格请保持和原有风格一致

为什么开发 QtScrcpy?

综合起来有以下几个原因,比重从大到小排列:

  1. 学习Qt的过程中需要一个项目实战一下
  2. 本身具有音视频相关技能,对音视频很感兴趣
  3. 本身具有 Android 开发技能,好久没用有点生疏,需要巩固一下
  4. 发现了 Scrcpy,决定用新的技术栈(C++ + Qt + Opengl + FFmpeg)进行复刻

编译

尽量提供了所有依赖资源,方便傻瓜式编译。

QtScrcpy

非 Arch Linux

  1. 使用官方 Qt Installer 或非官方工具(如 aqt)在目标平台上搭建Qt开发环境。
    需要 5.12 以上版本 Qt(在 Windows 上使用 MSVC 2019)
  2. 克隆该项目:git clone --recurse-submodules [email protected]:barry-ran/QtScrcpy.git
  3. Windows 使用 QtCreator 打开项目下 CMakeLists.txt 并编译 Release
  4. Linux 用终端执行 ./ci/linux/build_for_linux.sh "Release"
    注:编译结果位于 output/x64/Release 中

Arch Linux

  1. 安装以下包:qt5-base qt5-multimedia qt5-x11extras(推荐安装 qtcreator)
  2. 克隆该项目:git clone --recurse-submodules [email protected]:barry-ran/QtScrcpy.git
  3. 用终端执行 ./ci/linux/build_for_linux.sh "Release"
    注:编译结果位于 output/x64/Release 中

Scrcpy-Server

  1. 目标平台上搭建 Android 开发环境
  2. 使用 Android Studio 打开项目根目录中的 server
  3. 第一次打开时,如果你没有对应版本的 Gradle,Studio 会提示找不到 Gradle,是否升级 Gradle 并创建,选择取消,取消后会提示选择 Gradle 的位置,同样取消即可。Studio 会随后自动下载。
  4. 按需编辑代码
  5. 编译出 apk 以后改名为 scrcpy-server 并替换 third_party/scrcpy-server 即可

Licence

由于是复刻的 Scrcpy,尊重它的 Licence

text
Copyright (C) 2025 Rankun

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

关于作者

Barry 的 CSDN

一枚普通的程序员,工作中主要使用 C++ 进行桌面客户端开发,一毕业在山东做过一年多钢铁仿真教育软件,后来转战上海先后从事安防,在线教育相关领域工作,对音视频比较熟悉,对音视频领域如语音通话,直播教育,视频会议等相关解决方案有所了解。同时具有Android,Linux服务器等开发经验。