adb_scr_py
使用 ADB 协议在电脑上控制 Android 手机,并能高效获取屏幕显示的内容。
特性
- 🚀 高性能:多媒体处理调用C扩展且利用硬件加速。可以轻松批量连接多台手机(至少5台以上)
- 📱 多种连接方式:支持 USB 和 TCP(网络)连接
- 🎯 完整的控制功能:点击、双击、长按、返回键、粘贴文本等
- 📸 屏幕截图:实时获取屏幕内容,支持自定义 JPG 质量
- 🎬 应用管理:启动和停止应用
- 🧵 无 GIL 锁:充分利用多核 CPU 性能
安装
系统要求
- Python >= 3.11
- macOS arm64(目前仅支持此平台,后续等待H264解码的问题解决之后再考虑别的平台)
- 已安装 ADB 工具
安装方式
pip install adb_scr_py
或使用 uv:
uv add adb_scr_py
快速开始
基本使用
import asyncio
from adb_scr import init_lib, deinit_lib, list_devices, AndroidDevice
async def main():
# 初始化库(启动 ADB 守护进程等)
adb_version, scrcpy_version = await init_lib()
print(f"ADB 版本: {adb_version}, scrcpy 版本: {scrcpy_version}")
# 列出已连接的设备
devices = await list_devices()
print(f"已连接设备: {devices}")
# 连接设备
device = AndroidDevice("192.168.1.100:5555", "tcp")
if await device.connect():
print("设备连接成功")
# 获取屏幕尺寸
await asyncio.sleep(0.5) # 等待屏幕数据
size = device.get_screen_size()
if size:
print(f"屏幕尺寸: {size[0]}x{size[1]}")
# 获取屏幕截图
jpg_data = await device.get_screenshot_jpg(quality=90)
if jpg_data:
with open("screenshot.jpg", "wb") as f:
f.write(jpg_data)
print("截图已保存")
# 点击屏幕
await device.click(500, 500)
# 断开连接
await device.disconnect()
# 反初始化库
await deinit_lib()
asyncio.run(main())
USB 设备连接
from adb_scr import AndroidDevice
# USB 设备使用设备的序列号
device = AndroidDevice("emulator-5554", "usb")
await device.connect()
网络设备连接
from adb_scr import AndroidDevice
# 网络设备使用 IP:端口 格式
device = AndroidDevice("192.168.1.100:5555", "tcp")
await device.connect()
API 文档
模块函数
init_lib(adb_path: str | None = None) -> tuple[str, str]
初始化库。会启动 ADB 守护进程等一系列准备工作。
参数:
adb_path: ADB 可执行文件路径,如果为 None 则自动在系统PATH中找ADB
返回:
(adb_version, scrcpy_version): ADB 版本号和 scrcpy 版本号
异常:
AdbScrPyInitException: 初始化失败
deinit_lib() -> None
反初始化库。会停止 ADB 守护进程并清理临时文件。
!作死警告!
- 千万不要在已经连接设备(调用了
AndroidDevice.connect()方法)后调用这个函数,可能导致非常严重的后果! - 因为一些奇怪的通信协议和操作系统的机制,这么干轻则导致python进程挂死,必须强行结束。
- 重则把手机内核搞崩掉导致需要强制重启。
list_devices() -> list[str]
获取当前连接的 ADB 设备列表。
返回:
- 设备列表,每个元素为设备地址或序列号,可以用于后续连接设备
set_screen_record_fps(fps: int) -> None
设置录屏帧率(10-60)。仅推荐无硬件解码器的平台进行设置,硬件解码的性能绰绰有余无需关注。
AndroidDevice 类
构造函数
AndroidDevice(serial: str, connection_type: Literal["tcp", "usb"])
参数:
serial: 设备序列号或 IP:端口connection_type: 连接类型,"tcp" 或 "usb"
方法
| 方法 | 说明 |
|---|---|
connect() -> bool |
连接设备 |
disconnect() -> None |
断开设备连接 |
get_screen_size() -> tuple[int, int] | None |
获取屏幕尺寸 |
get_screenshot_jpg(quality: int = 75) -> bytes | None |
获取屏幕截图。由于技术问题,这个接口不能高频调用(建议不超过 5fps) |
click(x: int, y: int) -> None |
单击屏幕 |
double_click(x: int, y: int) -> None |
双击屏幕 |
long_press(x: int, y: int, duration_ms: int) -> None |
长按屏幕 |
swipe(x1: int, y1: int, x2: int, y2: int) -> None |
滑动屏幕,从 (x1, y1) 滑动到 (x2, y2) |
action_series(actions: list[GestureActionNode], check: bool = True) -> None |
执行一系列手势操作(下方详见说明) |
press_back() -> None |
按返回键 |
paste(text: str) -> None |
粘贴文本 |
launch_app(package_name: str, activity_name: str) -> bool |
启动应用 |
stop_app(package_name: str) -> bool |
停止应用 |
*get_screenshot_jpg方法需要访问解码器,但python无内建的高效率DispatchQueue,导致不得不用asyncio.Lock保护操作。如果高频调用会导致整个解码流程阻塞!
高级用法
自定义 ADB 路径
await init_lib(adb_path="/path/to/adb")
设置录屏帧率
from adb_scr import set_screen_record_fps
set_screen_record_fps(30)
应用管理
# 启动应用
await device.launch_app("com.example.app", ".MainActivity")
# 停止应用
await device.stop_app("com.example.app")
滑动操作
# 从 (100, 500) 滑动到 (100, 200),实现向上滑动
await device.swipe(100, 500, 100, 200)
自定义手势序列
使用 action_series 方法可以执行复杂的手势操作,用于模拟复杂的手指操作,比如玩游戏或者拖拽等。
from adb_scr.device.types import GestureActionNode, GestureAction
# 自定义手势序列
actions = [
GestureActionNode(100, 500, GestureAction.DOWN, 10), # 按下
GestureActionNode(100, 400, GestureAction.MOVE, 20), # 移动
GestureActionNode(100, 300, GestureAction.MOVE, 20), # 继续移动
GestureActionNode(100, 200, GestureAction.UP, 0), # 抬起
]
await device.action_series(actions)
参数说明:
-
手势序列规则:正常情况下,列表开头的操作必须是
DOWN,结尾的操作必须是UP。方法默认会检查这个条件,不符合条件的会拒绝执行。 -
duration_ms 参数:每个节点的
duration_ms表示执行该操作后等待的时间(毫秒)。- 每个节点(除了最后一个)的
duration_ms不建议设为 0,否则操作间隔过短,手机可能无法响应 - 最后一个节点的
duration_ms建议填 0,除非你确定需要等待一段时间 duration_ms必须在 0-10000 范围内(0-10秒)
- 每个节点(除了最后一个)的
-
跳过检查:这是个非常危险的操作,如果你确定自己在做什么非得要越过常规的操作,可以将
check参数设为False跳过检查:await device.action_series(actions, check=False)
⚠️ 警告:假如
DOWN之后没有UP,会导致手机认为一直有手指按在屏幕上,后续的所有操作都可能会错乱 -
坐标检查:默认会检查坐标是否在屏幕范围内,超出范围的坐标会被拒绝执行。
注意事项
- 并发安全:
AndroidDevice的方法内部有锁保护,不会并行执行多个操作 - 屏幕尺寸获取:刚连接时屏幕数据可能还未送达,建议等待几百毫秒后再获取
- 网络设备:TCP 连接的设备需要确保手机和电脑在同一网络,且已开启 ADB 网络调试
- 资源清理:设备使用完毕后必须调用
disconnect()清理资源,否则会导致内存泄漏。建议(不强制但建议)在软件退出前调用deinit_lib()反初始化库,释放所有资源。
技术实现
- 使用 scrcpy 服务端进行屏幕镜像
- C extension 使用 libjpeg-turbo 实现高效的图像编码
- 完全异步实现,基于 Python asyncio
许可证
MIT License
致谢
- scrcpy - 屏幕镜像核心
- libjpeg-turbo - 高性能 JPEG 编码
Release files for adb-scr-py 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| adb_scr_py-0.1.1.tar.gz | 414.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| adb_scr_py-0.1.1-cp314-cp314-macosx_26_0_arm64.whl | CPython 3.14 | CPython 3.14 | macOS 26.0+ ARM64 | Details |
Total release size: 738.6 kB
Release files / adb_scr_py-0.1.1.tar.gz
| Download URL | adb_scr_py-0.1.1.tar.gz |
|---|---|
| Size | 414.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5df3d4ab5eaace956d3ebb862df6b17579b736840bdfd0fbf3376a6a75e3d3a5
|
|
BLAKE2b-256 checksum How to use checksums |
12c5c25b88535cfa716e62efa3233314240fe1d03eb1113a2c9732dd939f76b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.3 {"installer":{"name":"uv","version":"0.10.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / adb_scr_py-0.1.1-cp314-cp314-macosx_26_0_arm64.whl
| Download URL | adb_scr_py-0.1.1-cp314-cp314-macosx_26_0_arm64.whl |
|---|---|
| Size | 324.4 kB |
| Tags | CPython 3.14 macOS 26.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
591a28d0fd9d30acde30425409f8b01dab6e3320d491572185eb22544a8573de
|
|
BLAKE2b-256 checksum How to use checksums |
b724f7e33516f1829165d9459b25cfa2ca4d98b9ea99c872e00af574e6d3e6ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.3 {"installer":{"name":"uv","version":"0.10.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|