使用ADB协议在电脑上控制手机,并能高效获取屏幕显示的内容
Project description
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 守护进程并清理临时文件。
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 编码
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file adb_scr_py-0.0.3.tar.gz.
File metadata
- Download URL: adb_scr_py-0.0.3.tar.gz
- Upload date:
- Size: 413.5 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14f35bfca7bd5988052958acf2334cf5631c5923f318db686391536724d32f82
|
|
| MD5 |
1fd01663fb0945ded3b1826c3649bd38
|
|
| BLAKE2b-256 |
09537fe979d93355a60245c19750cbf83c78a222f8343e88199ffe5849bacfd1
|
File details
Details for the file adb_scr_py-0.0.3-cp314-cp314-macosx_26_0_arm64.whl.
File metadata
- Download URL: adb_scr_py-0.0.3-cp314-cp314-macosx_26_0_arm64.whl
- Upload date:
- Size: 323.9 kB
- Tags: CPython 3.14, macOS 26.0+ ARM64
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
00ef6539d5e9bb9a03153d491b7801cf650535dc386660ac6323eba6be8b3dbd
|
|
| MD5 |
72782dadf075568c6604690c3b414382
|
|
| BLAKE2b-256 |
c0cfeadaa01e6c2b90a2ee6a1022f189f0642added2d1e721b2f474c49c0d4ee
|