QtScrcpyCore 是一个基于 Qt 框架的 Android 屏幕镜像和控制核心库,它是开源项目 QtScrcpy 的核心组件。QtScrcpyCore 主要功能:
-
通过 USB 或 WiFi 连接 Android 设备
-
实时显示 Android 设备屏幕
-
支持从电脑向设备发送触摸和按键事件
-
支持音频传输(部分版本)
-
支持剪贴板同步
核心架构
主要模块组成:
QtScrcpyCore
├── AdbProcess # ADB 命令执行模块
├── Device # 设备管理模块
├── VideoSocket # 视频数据传输
├── ControlSocket # 控制指令传输
├── Decoder # H264 解码器
├── FrameProducer # 帧生成器
└── Stream # 数据流处理
设备管理架构总览
核心组件关系

-
IDeviceManage:单例工厂,管理设备生命周期。 -
Device:实际设备实例,整合视频流、输入控制、文件传输等功能。 -
观察者模式:通过
DeviceObserver实现事件广播。
设备连接流程
// DeviceManage::connectDevice()
1. 检查参数有效性(序列号、设备数限制)
2. 创建Device对象
3. 连接信号:
- deviceConnected → 通知UI更新
- deviceDisconnected → 触发资源清理
4. 启动Server(异步):
- 成功:初始化Decoder/Recorder
- 失败:删除Device
设备控制框架的核心头文件
QtScrcpyCore.h
#pragma once
#include <QPointer>
#include <QMouseEvent>
#include "QtScrcpyCoreDef.h"
namespace qsc {
class DeviceObserver {
protected:
DeviceObserver() {
}
virtual ~DeviceObserver() {
}
public:
virtual void onFrame(int width, int height, uint8_t* dataY, uint8_t* dataU, uint8_t* dataV, int linesizeY, int linesizeU, int linesizeV) {
Q_UNUSED(width);
Q_UNUSED(height);
Q_UNUSED(dataY);
Q_UNUSED(dataU);
Q_UNUSED(dataV);
Q_UNUSED(linesizeY);
Q_UNUSED(linesizeU);
Q_UNUSED(linesizeV);
}
virtual void updateFPS(quint32 fps) { Q_UNUSED(fps); }
virtual void grabCursor(bool grab) {Q_UNUSED(grab);}
virtual void mouseEvent(const QMouseEvent *from, const QSize &frameSize, const QSize &showSize) {
Q_UNUSED(from);
Q_UNUSED(frameSize);
Q_UNUSED(showSize);
}
virtual void wheelEvent(const QWheelEvent *from, const QSize &frameSize, const QSize &showSize) {
Q_UNUSED(from);
Q_UNUSED(frameSize);
Q_UNUSED(showSize);
}
virtual void keyEvent(const QKeyEvent *from, const QSize &frameSize, const QSize &showSize) {
Q_UNUSED(from);
Q_UNUSED(frameSize);
Q_UNUSED(showSize);
}
virtual void postGoBack() {}
virtual void postGoHome() {}
virtual void postGoMenu() {}
virtual void postAppSwitch() {}
virtual void postPower() {}
virtual void postVolumeUp() {}
virtual void postVolumeDown() {}
virtual void postCopy() {}
virtual void postCut() {}
virtual void setScreenPowerMode(bool open) { Q_UNUSED(open); }
virtual void expandNotificationPanel() {}
virtual void collapsePanel() {}
virtual void postBackOrScreenOn(bool down) { Q_UNUSED(down); }
virtual void postTextInput(QString &text) { Q_UNUSED(text); }
virtual void requestDeviceClipboard() {}
virtual void setDeviceClipboard(bool pause = true) { Q_UNUSED(pause); }
virtual void clipboardPaste() {}
virtual void pushFileRequest(const QString &file, const QString &devicePath) {
Q_UNUSED(file);
Q_UNUSED(devicePath);
}
virtual void installApkRequest(const QString &apkFile) { Q_UNUSED(apkFile); }
virtual void screenshot() {}
virtual void showTouch(bool show) { Q_UNUSED(show); }
};
class IDevice : public QObject {
Q_OBJECT
public:
IDevice(QObject *parent = nullptr) : QObject(parent) {}
virtual ~IDevice(){}
signals:
void deviceConnected(bool success, const QString& serial, const QString& deviceName, const QSize& size);
void deviceDisconnected(QString serial);
public:
virtual void setUserData(void* data) = 0;
virtual void* getUserData() = 0;
virtual void registerDeviceObserver(DeviceObserver* observer) = 0;
virtual void deRegisterDeviceObserver(DeviceObserver* observer) = 0;
virtual bool connectDevice() = 0;
virtual void disconnectDevice() = 0;
virtual void mouseEvent(const QMouseEvent *from, const QSize &frameSize, const QSize &showSize) = 0;
virtual void wheelEvent(const QWheelEvent *from, const QSize &frameSize, const QSize &showSize) = 0;
virtual void keyEvent(const QKeyEvent *from, const QSize &frameSize, const QSize &showSize) = 0;
virtual void postGoBack() = 0;
virtual void postGoHome() = 0;
virtual void postGoMenu() = 0;
virtual void postAppSwitch() = 0;
virtual void postPower() = 0;
virtual void postVolumeUp() = 0;
virtual void postVolumeDown() = 0;
virtual void postCopy() = 0;
virtual void postCut() = 0;
virtual void setScreenPowerMode(bool open) = 0;
virtual void expandNotificationPanel() = 0;
virtual void collapsePanel() = 0;
virtual void postBackOrScreenOn(bool down) = 0;
virtual void postTextInput(QString &text) = 0;
virtual void requestDeviceClipboard() = 0;
virtual void setDeviceClipboard(bool pause = true) = 0;
virtual void clipboardPaste() = 0;
virtual void pushFileRequest(const QString &file, const QString &devicePath = "") = 0;
virtual void installApkRequest(const QString &apkFile) = 0;
virtual void screenshot() = 0;
virtual void showTouch(bool show) = 0;
virtual bool isReversePort(quint16 port) = 0;
virtual const QString &getSerial() = 0;
virtual void updateScript(QString script) = 0;
virtual bool isCurrentCustomKeymap() = 0;
};
class IDeviceManage : public QObject {
Q_OBJECT
public:
static IDeviceManage& getInstance();
virtual bool connectDevice(DeviceParams params) = 0;
virtual bool disconnectDevice(const QString &serial) = 0;
virtual void disconnectAllDevice() = 0;
virtual QPointer<IDevice> getDevice(const QString& serial) = 0;
signals:
void deviceConnected(bool success, const QString& serial, const QString& deviceName, const QSize& size);
void deviceDisconnected(QString serial);
};
}
此文件定义了一个设备管理和控制的框架,主要用于Android设备屏幕镜像和控制(类似于scrcpy项目的Qt实现)。其是设备控制框架的核心头文件,定义了:
-
设备参数结构体(
DeviceParams) -
设备观察者接口(
DeviceObserver) -
设备操作接口(
IDevice) -
设备管理接口(
IDeviceManage)
1. 核心结构解析
(1) DeviceParams - 设备连接参数
struct DeviceParams {
QString serial; // 设备序列号
quint16 localPort = 27183; // 本地端口(默认scrcpy端口)
QString serverLocalPath; // 本地服务端路径
QString serverRemotePath; // 设备端路径
int maxSize = 0; // 最大分辨率(0为原生尺寸)
int bitRate = 8000000; // 码率(默认8Mbps)
bool display = true; // 是否显示视频
bool recordFile = false; // 是否录制
QString recordPath; // 录制存储路径
// ... 其他参数(如帧率、编解码选项等)
};
设计要点:
-
支持无线/有线连接(通过
serial字段区分,如192.168.1.100:5555) -
灵活的媒体控制(分辨率、码率可动态调整)
(2) DeviceObserver - 观察者接口
class DeviceObserver {
public:
virtual void onFrame(int w, int h, uint8_t* dataY, uint8_t* dataU, uint8_t* dataV, ...);
virtual void updateFPS(quint32 fps);
virtual void mouseEvent(const QMouseEvent* event, const QSize& frameSize, const QSize& showSize);
// ... 其他输入事件和控制回调
};
这是一个抽象基类,定义了设备事件回调接口:
-
视频帧处理:
onFrame()接收YUV格式的视频帧数据 -
输入事件:
-
mouseEvent()鼠标事件 -
wheelEvent()滚轮事件 -
keyEvent()键盘事件
-
-
设备控制:
-
各种系统按键事件(返回、主页、菜单等)
-
音量控制
-
电源管理
-
剪贴板操作
-
-
文件操作:文件推送和APK安装
-
其他功能:截图、显示触摸等
(3) IDevice - 设备操作接口
class IDevice : public QObject {
Q_OBJECT
public:
virtual bool connectDevice() = 0;
virtual void mouseEvent(const QMouseEvent* event, ...) = 0;
virtual void postGoBack() = 0;
// ... 其他控制命令(电源、音量、剪贴板等)
signals:
void deviceConnected(bool success, QString serial, QString deviceName, QSize size);
};
继承自QObject,定义了设备操作接口:
-
设备连接管理:
connectDevice(),disconnectDevice() -
输入事件转发:鼠标、滚轮、键盘事件,转发Qt输入事件到Android设备
-
设备控制命令:系统按键、电源管理、剪贴板等
-
文件操作:推送文件、安装APK
-
其他功能:截图、显示触摸点等
-
观察者模式:
registerDeviceObserver(),deRegisterDeviceObserver() -
系统命令:模拟物理按键(如HOME键)
(4) IDeviceManage - 设备管理器
class IDeviceManage : public QObject {
Q_OBJECT
public:
static IDeviceManage& getInstance(); // 单例访问
virtual bool connectDevice(DeviceParams params) = 0;
virtual QPointer<IDevice> getDevice(const QString& serial) = 0;
};
单例模式的管理器,主要功能:
-
连接/断开设备
-
获取设备实例
-
断开所有设备
-
提供设备连接状态信号
2. 关键设计亮点
(1) 多设备支持
-
通过
QMap<QString, IDevice*>管理多个设备,键为设备序列号 -
每个设备独立视频流和控制通道
(2) 跨平台兼容性
-
接口纯虚化,可在不同平台(Windows/macOS/Linux)实现具体逻辑
-
依赖Qt信号槽机制,确保线程安全
(3) 可扩展性
-
协议扩展:新增控制命令只需在
IDevice中添加接口 -
功能插件化:通过
DeviceObserver可插入日志、录屏等模块
3. 设计模式
-
观察者模式:
-
DeviceObserver作为观察者接口 -
IDevice作为被观察者,可以注册/注销观察者
-
-
工厂模式:
-
IDeviceManage作为创建和管理设备的工厂
-
-
单例模式:
-
IDeviceManage使用单例模式确保全局唯一实例
-
4. 功能特点
-
支持Android设备屏幕镜像(YUV格式帧数据)
-
支持输入事件转发(鼠标、键盘、触摸)
-
支持系统按键模拟(返回、主页、电源等)
-
支持文件传输和APK安装
-
支持剪贴板同步
-
支持脚本控制

被折叠的 条评论
为什么被折叠?



