ios和android录屏
parent
fd88ef376a
commit
509a7278fc
|
@ -689,9 +689,9 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
|
|||
@Override
|
||||
public void startRecord() {
|
||||
if ("0".equals(deviceInfo.getPlatform())) {
|
||||
AndroidUtil.startRecord(this.remoteAddress, deviceInfo.getDeviceId(), deviceInfo.getOtherInfo().get("taskId"));
|
||||
AndroidUtil.startRecord(this.remoteAddress, deviceInfo.getDeviceId(), deviceInfo.getOtherInfo().get("taskId"),deviceInfo.getOtherInfo().get("tenantId"));
|
||||
} else {
|
||||
IosUtil.startRecord(this.remoteAddress, deviceInfo.getDeviceId(), deviceInfo.getOtherInfo().get("taskId"), deviceInfo.getResolution());
|
||||
IosUtil.startRecord(this.remoteAddress, deviceInfo.getDeviceId(), deviceInfo.getOtherInfo().get("taskId"), deviceInfo.getOtherInfo().get("tenantId"),deviceInfo.getResolution());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -589,6 +589,7 @@ public class DefaultExecThread implements AtuExecThread{
|
|||
otherInfo = new HashMap<>();
|
||||
}
|
||||
otherInfo.put("taskId",task.getTaskId());
|
||||
otherInfo.put("tenantId", task.getTenantId());
|
||||
deviceConnection.getDeviceInfo().setOtherInfo(otherInfo);
|
||||
//开启录屏
|
||||
deviceConnection.startRecord();
|
||||
|
|
|
@ -55,10 +55,11 @@ public class AndroidUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static String startRecord(String remoteAddress,String deviceId,String taskId){
|
||||
public static String startRecord(String remoteAddress,String deviceId,String taskId,String tenantId){
|
||||
DebuggerDeviceInfo info = new DebuggerDeviceInfo();
|
||||
info.setDeviceId(deviceId);
|
||||
info.setPlatform("0");
|
||||
info.setTenantId(tenantId);
|
||||
logger.info("移动任务开启录屏,任务id:"+taskId);
|
||||
info.setTaskId(taskId);
|
||||
logger.info("录屏参数:{}", JSON.toJSONString(info));
|
||||
|
|
|
@ -122,10 +122,11 @@ public class IosUtil {
|
|||
}
|
||||
|
||||
|
||||
public static String startRecord(String remoteAddress, String deviceId, String taskId, String resolution) {
|
||||
public static String startRecord(String remoteAddress, String deviceId, String taskId, String tenantId,String resolution) {
|
||||
DebuggerDeviceInfo info = new DebuggerDeviceInfo();
|
||||
info.setDeviceId(deviceId);
|
||||
info.setPlatform("1");
|
||||
info.setTenantId(tenantId);
|
||||
logger.info("移动任务开启录屏,任务id:" + taskId);
|
||||
info.setTaskId(taskId);
|
||||
info.setResolution(resolution);
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URI;
|
||||
|
@ -46,6 +47,7 @@ public abstract class AbstractDeviceManager extends Thread implements DeviceMana
|
|||
SpringUtils.getBean(DeviceConnectionService.class).deviceAgentDead(serial);
|
||||
}
|
||||
|
||||
|
||||
protected void publishDeviceOnlineToWebConnection(String deviceId) {
|
||||
MessageHandler handleMessageThread = SpringUtils.getBean(DeviceConnectionService.class).getHandleMessageThread(deviceId);
|
||||
if (null != handleMessageThread) {
|
||||
|
@ -176,4 +178,6 @@ public abstract class AbstractDeviceManager extends Thread implements DeviceMana
|
|||
brand.setBrandName(manufacturer.toUpperCase());
|
||||
return brand;
|
||||
}
|
||||
|
||||
public abstract void stopWebScreen(String udid, Session session);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
package net.northking.cctp.upperComputer.deviceManager;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import net.northking.cctp.upperComputer.deviceManager.screen.AndroidScreenResponseThread;
|
||||
import net.northking.cctp.upperComputer.deviceManager.thread.AndroidDeviceInitThread;
|
||||
import net.northking.cctp.upperComputer.driver.adb.Adb;
|
||||
import net.northking.cctp.upperComputer.driver.adb.AdbDevice;
|
||||
import net.northking.cctp.upperComputer.driver.adb.AndroidDeviceListener;
|
||||
import net.northking.cctp.upperComputer.webSocket.thread.AndroidScreenResponseThread;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -73,6 +74,11 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
|
|||
deviceSystemIsReady.put(serial, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDeviceSystemStatus(String serial) {
|
||||
return deviceSystemIsReady.get(serial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
clearAndShutdownDevices();
|
||||
|
@ -205,7 +211,7 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
|
|||
for (AndroidScreenResponseThread screenResponseThread : screenMap.values()) {
|
||||
logger.debug("上位机重启,中断残余获取屏幕线程");
|
||||
if (null != screenResponseThread && screenResponseThread.isAlive() && !screenResponseThread.isInterrupted()) {
|
||||
screenResponseThread.stopAndExit();
|
||||
screenResponseThread.stopFetchPic();
|
||||
}
|
||||
}
|
||||
screenMap.clear();
|
||||
|
@ -226,4 +232,23 @@ public class AndroidDeviceManager extends AbstractDeviceManager {
|
|||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offlineDevice(String serial) {
|
||||
synchronized (onlineDeviceInitMap){
|
||||
AndroidDeviceInitThread initThread = onlineDeviceInitMap.remove(serial);
|
||||
if (null != initThread && initThread.isAlive() && !initThread.isInterrupted()) {
|
||||
logger.info("设备【{}】初始化线程准备退出",serial);
|
||||
initThread.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopWebScreen(String udid, Session session) {
|
||||
AndroidScreenResponseThread androidScreenResponseThread = screenMap.get(udid);
|
||||
if (null != androidScreenResponseThread) {
|
||||
androidScreenResponseThread.stopWebSessionTransform(session);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package net.northking.cctp.upperComputer.deviceManager;
|
|||
|
||||
import net.northking.cctp.upperComputer.config.BuildWdaConfig;
|
||||
import net.northking.cctp.upperComputer.deviceManager.common.PyMobileDevice;
|
||||
import net.northking.cctp.upperComputer.deviceManager.screen.IosScreenResponseThread;
|
||||
import net.northking.cctp.upperComputer.deviceManager.thread.IosDeviceInitThread;
|
||||
import net.northking.cctp.upperComputer.deviceManager.thread.MacIosDeviceInitThread;
|
||||
import net.northking.cctp.upperComputer.deviceManager.thread.WindowsAndLinuxIosDeviceInitThread;
|
||||
|
@ -13,10 +14,10 @@ import net.northking.cctp.upperComputer.driver.usbmuxd.UsbMuxd;
|
|||
import net.northking.cctp.upperComputer.driver.usbmuxd.payload.usbmuxd.entity.DeviceConnectionDetail;
|
||||
import net.northking.cctp.upperComputer.entity.PhoneEntity;
|
||||
import net.northking.cctp.upperComputer.utils.SpringUtils;
|
||||
import net.northking.cctp.upperComputer.webSocket.thread.IosScreenResponseThread;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -396,4 +397,12 @@ public class IOSDeviceManager extends AbstractDeviceManager {
|
|||
public PyMobileDevice.SpecificAppleDeviceInfo getSpecificAppleDeviceInfo(String serial){
|
||||
return pyMobileDeviceMap.get(serial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopWebScreen(String udid, Session session) {
|
||||
IosScreenResponseThread iosScreenResponseThread = screenMap.get(udid);
|
||||
if (null != iosScreenResponseThread) {
|
||||
iosScreenResponseThread.stopWebSessionTransform(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package net.northking.cctp.upperComputer.webSocket.thread;
|
||||
package net.northking.cctp.upperComputer.deviceManager.screen;
|
||||
|
||||
import net.northking.cctp.upperComputer.constants.ResponseCmd;
|
||||
import net.northking.cctp.upperComputer.deviceManager.AndroidDeviceManager;
|
||||
|
@ -7,10 +7,9 @@ import net.northking.cctp.upperComputer.driver.agent.AndroidAgentSession;
|
|||
import net.northking.cctp.upperComputer.driver.agent.command.ScreenStreamCommand;
|
||||
import net.northking.cctp.upperComputer.driver.agent.command.WatchScreenStreamCommand;
|
||||
import net.northking.cctp.upperComputer.utils.SessionUtils;
|
||||
import net.northking.cctp.upperComputer.webSocket.entity.CatchParam;
|
||||
import net.northking.cctp.upperComputer.webSocket.entity.CmdRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.io.DataInput;
|
||||
|
@ -18,42 +17,35 @@ import java.io.IOException;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AndroidScreenResponseThread extends Thread {
|
||||
public class AndroidScreenResponseThread extends ImageScreenResponse {
|
||||
|
||||
private AndroidAgentSession asyncAgentSession;
|
||||
|
||||
private Session wsSession;
|
||||
|
||||
private AdbDevice adbDevice;
|
||||
|
||||
private CmdRequest screenOnRequest;
|
||||
|
||||
private CatchParam catchParam;
|
||||
|
||||
private byte[] lastData;
|
||||
|
||||
private boolean sendDeviceStatus = true;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(AndroidScreenResponseThread.class);
|
||||
|
||||
public AndroidScreenResponseThread(Session wsSession, AdbDevice adbDevice, CatchParam catchParam) {
|
||||
this.wsSession = wsSession;
|
||||
public AndroidScreenResponseThread(AdbDevice adbDevice) {
|
||||
this.adbDevice = adbDevice;
|
||||
this.catchParam = catchParam;
|
||||
this.deviceId = adbDevice.getSerial();
|
||||
setName("[" + adbDevice.getSerial() + "-response]");
|
||||
}
|
||||
|
||||
public void setScreenOnRequest(CmdRequest screenOnRequest) {
|
||||
this.screenOnRequest = screenOnRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!isInterrupted()) {
|
||||
if (!CollectionUtils.isEmpty(webSessions)) {
|
||||
//通知前端开始连接
|
||||
Map<String, Object> messageMap = new HashMap<>();
|
||||
messageMap.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.CONNECTING);
|
||||
SessionUtils.sendMessageInitiative(wsSession, ResponseCmd.DEVICE_STATUS, adbDevice.getSerial(), messageMap, "设备掉线了");
|
||||
for (Session webSession : webSessions) {
|
||||
if (webSession.isOpen()) {
|
||||
SessionUtils.sendMessageInitiative(webSession, ResponseCmd.DEVICE_STATUS, adbDevice.getSerial(), messageMap, "设备掉线了");
|
||||
}
|
||||
}
|
||||
}
|
||||
AdbDevice currentDevice = AndroidDeviceManager.getInstance().getCurrentDevice(adbDevice.getSerial());
|
||||
if (null == currentDevice) {
|
||||
logger.warn("设备【{}】掉线了,等待设备准备好再打开图片流........", adbDevice.getSerial());
|
||||
|
@ -74,15 +66,24 @@ public class AndroidScreenResponseThread extends Thread {
|
|||
this.asyncAgentSession.send(screenStreamCommand);
|
||||
} catch (IOException e) {
|
||||
logger.error("创建设备【{}】agentSession出错。。。。。。", adbDevice.getSerial(), e);
|
||||
Thread.currentThread().interrupt();
|
||||
interrupt();
|
||||
if (!CollectionUtils.isEmpty(webSessions)) {
|
||||
//通知前端断开
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.DISCONNECT);
|
||||
SessionUtils.sendMessageInitiative(wsSession, ResponseCmd.DEVICE_STATUS, adbDevice.getSerial(), result, "设备连接失败");
|
||||
for (Session webSession : webSessions) {
|
||||
if (webSession.isOpen()) {
|
||||
SessionUtils.sendMessageInitiative(webSession, ResponseCmd.DEVICE_STATUS, adbDevice.getSerial(), result, "设备连接失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.asyncAgentSession.closeSilence();
|
||||
break;
|
||||
}
|
||||
sendConnectInfo2Web();
|
||||
// sendConnectInfo2Web();
|
||||
DataInput dataInput = this.asyncAgentSession.getDataInput();
|
||||
int receive = 1;
|
||||
int send = 1;
|
||||
while (!isInterrupted()) {
|
||||
try {
|
||||
int commandId = dataInput.readInt();
|
||||
|
@ -94,23 +95,38 @@ public class AndroidScreenResponseThread extends Thread {
|
|||
//将获取的最新帧进行缓存
|
||||
if (null != screenPicContent && screenPicContent.length > 0) {
|
||||
this.lastData = screenPicContent;
|
||||
logger.info("设备【{}】收到图片:{}张,大小:{}",adbDevice.getSerial(),receive++,screenPicContent.length);
|
||||
} else {
|
||||
logger.warn("设备【{}】command读取最新帧为空!",adbDevice.getSerial());
|
||||
logger.info("设备【{}】收到图片:{}张,大小为零",adbDevice.getSerial(),receive++);
|
||||
continue;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("读取数据出错了", e);
|
||||
break;
|
||||
}
|
||||
//录屏
|
||||
if (null != screenRecorder) {
|
||||
screenRecorder.addImgToVideo(screenPicContent);
|
||||
}
|
||||
//有后端会话则给后端推送屏幕图片
|
||||
if (wsSession != null && wsSession.isOpen()) {
|
||||
SessionUtils.sendBinary(wsSession, screenPicContent);
|
||||
if (!CollectionUtils.isEmpty(webSessions)) {
|
||||
for (Session webSession : webSessions) {
|
||||
if (webSession.isOpen()) {
|
||||
if (sendDeviceStatus) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.CONNECTED);
|
||||
SessionUtils.sendMessageInitiative(wsSession, ResponseCmd.DEVICE_STATUS, adbDevice.getSerial(), result, "设备连接失败");
|
||||
SessionUtils.sendMessageInitiative(webSession, ResponseCmd.DEVICE_STATUS, adbDevice.getSerial(), result, "设备连接失败");
|
||||
sendDeviceStatus = false;
|
||||
}
|
||||
logger.info("设备【{}】发送图片到微服务:{}张",adbDevice.getSerial(),send++);
|
||||
SessionUtils.sendBinary(webSession, screenPicContent);
|
||||
logger.info("设备【{}】发送图片到微服务完成:{}张",adbDevice.getSerial(),send);
|
||||
} else {
|
||||
logger.warn("推送到web端的session已经断开,sessionId:{}",webSession.getId());
|
||||
//todo:操作一下,去掉webSessions里面的无效session
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -129,58 +145,36 @@ public class AndroidScreenResponseThread extends Thread {
|
|||
logger.warn("设备【{}】响应到上位机的屏幕线程退出..........................", adbDevice.getSerial());
|
||||
}
|
||||
|
||||
public void sendConnectInfo2Web() {
|
||||
//新连接需要先发送状态
|
||||
if (null != screenOnRequest) { //只发第一次screen_on指令
|
||||
//向前端推送之前缓存的最新帧
|
||||
if (null != adbDevice) {
|
||||
if (null != lastData && lastData.length > 0) {
|
||||
SessionUtils.sendBinary(wsSession, lastData);
|
||||
logger.debug("上位机发送缓存帧成功,大小:{}", lastData.length);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.CONNECTED);
|
||||
SessionUtils.sendMessageInitiative(wsSession, ResponseCmd.DEVICE_STATUS, adbDevice.getSerial(), result, "设备连接失败");
|
||||
sendDeviceStatus = false;
|
||||
} else {
|
||||
logger.warn("设备【{}】缓存帧获取为空...", adbDevice.getSerial());
|
||||
}
|
||||
}
|
||||
//向前端推送之前缓存的最新帧后发screenOn回复
|
||||
SessionUtils.sendSuccessData(wsSession, screenOnRequest, null, "开启屏幕成功");
|
||||
setScreenOnRequest(null);
|
||||
}
|
||||
}
|
||||
// public void sendConnectInfo2Web() {
|
||||
// //新连接需要先发送状态
|
||||
// if (null != screenOnRequest) { //只发第一次screen_on指令
|
||||
// //向前端推送之前缓存的最新帧
|
||||
// if (null != adbDevice) {
|
||||
// if (null != lastData && lastData.length > 0) {
|
||||
// SessionUtils.sendBinary(wsSession, lastData);
|
||||
// logger.debug("上位机发送缓存帧成功,大小:{}", lastData.length);
|
||||
// Map<String, Object> result = new HashMap<>();
|
||||
// result.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.CONNECTED);
|
||||
// SessionUtils.sendMessageInitiative(wsSession, ResponseCmd.DEVICE_STATUS, adbDevice.getSerial(), result, "设备连接失败");
|
||||
// sendDeviceStatus = false;
|
||||
// } else {
|
||||
// logger.warn("设备【{}】缓存帧获取为空...", adbDevice.getSerial());
|
||||
// }
|
||||
// }
|
||||
// //向前端推送之前缓存的最新帧后发screenOn回复
|
||||
// SessionUtils.sendSuccessData(wsSession, screenOnRequest, null, "开启屏幕成功");
|
||||
// setScreenOnRequest(null);
|
||||
// }
|
||||
// }
|
||||
|
||||
public void stopAndExit() {
|
||||
logger.warn("设备【{}】退出屏幕获取线程...", adbDevice.getSerial());
|
||||
@Override
|
||||
public void stopFetchPic() {
|
||||
logger.warn("设备【{}】即将退出屏幕获取线程...", adbDevice.getSerial());
|
||||
ScreenStreamCommand screenStreamCommand = new ScreenStreamCommand(false, catchParam.getRotation(), catchParam.getWidth(), catchParam.getHeight(), catchParam.getFrameRate(), catchParam.getQuality());
|
||||
asyncAgentSession.send(screenStreamCommand);
|
||||
asyncAgentSession.closeSilence();
|
||||
this.lastData = null;
|
||||
AndroidDeviceManager.getInstance().removeScreenThread(adbDevice.getSerial());
|
||||
interrupt();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新关联的后端会话和屏幕尺寸
|
||||
*
|
||||
* @param session
|
||||
* @param catchParam
|
||||
*/
|
||||
public void startSendScreenToWeb(Session session, CatchParam catchParam) {
|
||||
this.wsSession = session;
|
||||
this.catchParam = catchParam;
|
||||
// this.isNewConnect = true;
|
||||
sendConnectInfo2Web();
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开后端会话连接,保留接收最新帧数据
|
||||
*/
|
||||
public void stopSendPic2Web() {
|
||||
this.wsSession = null;
|
||||
// logger.debug("后端会话关联已置空!屏幕获取线程是否被中断:"+isInterrupted());
|
||||
}
|
||||
|
||||
public void setSendDeviceStatus(boolean sendDeviceStatus) {
|
||||
this.sendDeviceStatus = sendDeviceStatus;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package net.northking.cctp.upperComputer.webSocket.thread;
|
||||
package net.northking.cctp.upperComputer.deviceManager.screen;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import net.northking.cctp.upperComputer.constants.ResponseCmd;
|
|
@ -0,0 +1,114 @@
|
|||
package net.northking.cctp.upperComputer.deviceManager.screen;
|
||||
|
||||
import net.northking.cctp.upperComputer.constants.ResponseCmd;
|
||||
import net.northking.cctp.upperComputer.utils.SessionUtils;
|
||||
import net.northking.cctp.upperComputer.webSocket.entity.CatchParam;
|
||||
import net.northking.cctp.upperComputer.webSocket.entity.CmdRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author : yineng.huang
|
||||
* @date : 2024/7/18 17:48
|
||||
*/
|
||||
public abstract class ImageScreenResponse extends Thread{
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(IosScreenResponseThread.class);
|
||||
|
||||
protected List<Session> webSessions = new ArrayList<>(3); //与微服务之间的连接session,传送屏幕的
|
||||
|
||||
protected ScreenRecorder screenRecorder;
|
||||
|
||||
protected boolean sendDeviceStatus = true;
|
||||
|
||||
protected Map<String,CmdRequest> allConnectionScreenOnRequestMap; //只是第一次连接需要,发送给前端代表连接成功
|
||||
|
||||
protected String deviceId;
|
||||
|
||||
protected CatchParam catchParam;
|
||||
|
||||
public void setCatchParam(CatchParam catchParam) {
|
||||
this.catchParam = catchParam;
|
||||
}
|
||||
|
||||
public void startRecordScreen(String tenantId, int width, int height, String taskId) {
|
||||
logger.info("收到设备【{}】的录屏请求,当前请求的taskId为:{}",deviceId,taskId);
|
||||
if (null != screenRecorder) {
|
||||
logger.warn("上一次设备【{}】的录频还在跑呢,上一次跑的taskId为:{}",deviceId,screenRecorder.getTaskId());
|
||||
String previousRecordPath = screenRecorder.endRecord();
|
||||
logger.warn("设备【{}】上一次的录频结束,taskId为:{},上传的地址为:{}",deviceId,screenRecorder.getTaskId(),previousRecordPath);
|
||||
}
|
||||
logger.info("开启设备【{}】的录屏请求,当前请求的taskId为:{}",deviceId,taskId);
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
|
||||
String dateFormat = format.format(new Date());
|
||||
String videoName = deviceId + "_" + dateFormat + ".mp4";
|
||||
screenRecorder = new ScreenRecorder(deviceId, videoName, tenantId,taskId, width, height);
|
||||
screenRecorder.startRecordVideo();
|
||||
}
|
||||
|
||||
public String stopRecord() {
|
||||
String result = null;
|
||||
String taskId = null;
|
||||
if (null != screenRecorder) {
|
||||
result = screenRecorder.endRecord();
|
||||
taskId = screenRecorder.getTaskId();
|
||||
screenRecorder = null;
|
||||
}
|
||||
if (CollectionUtils.isEmpty(webSessions)) {
|
||||
logger.info("设备【{}】在taskId:{}的录屏结束了,而且没有前端的连接,直接退出屏幕抓取的线程了.............", deviceId, taskId);
|
||||
stopFetchPic();
|
||||
} else {
|
||||
logger.info("设备【{}】在taskId:{}的录屏结束了,但是还有前端的连接再用着,先不断开.............", deviceId, taskId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void startSendScreenToWeb(Session session, CatchParam catchParam) {
|
||||
logger.info("设备【{}】当前连接了{}个web客户端...............",deviceId,this.webSessions.size());
|
||||
if (this.webSessions.size() > 3) {
|
||||
//通知前端断开连接,最多只能连接三个
|
||||
Map<String, Object> messageMap = new HashMap<>();
|
||||
messageMap.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.DISCONNECT);
|
||||
SessionUtils.sendMessageInitiative(session, ResponseCmd.DEVICE_STATUS, deviceId, messageMap, "最多支持三个客户端同时浏览手机");
|
||||
return;
|
||||
}
|
||||
this.catchParam = catchParam;
|
||||
this.webSessions.add(session);
|
||||
//通知前端开始连接
|
||||
Map<String, Object> messageMap = new HashMap<>();
|
||||
messageMap.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.CONNECTING);
|
||||
SessionUtils.sendMessageInitiative(session, ResponseCmd.DEVICE_STATUS, deviceId, messageMap, "设备掉线了");
|
||||
this.sendDeviceStatus = true;
|
||||
}
|
||||
|
||||
public void setSendDeviceStatus(boolean sendDeviceStatus) {
|
||||
this.sendDeviceStatus = sendDeviceStatus;
|
||||
}
|
||||
|
||||
public void stopWebSessionTransform(Session session) {
|
||||
logger.info("移除设备【{}】的web投屏连接,sessionId为:{}...............",deviceId,session.getId());
|
||||
webSessions.remove(session);
|
||||
logger.info("设备【{}】的web投屏连接数还剩下:{}...............",deviceId,webSessions.size());
|
||||
if (webSessions.size() > 0) {
|
||||
logger.info("设备【{}】还有其他人连着这个屏幕的,还保留一下这个线程............",deviceId);
|
||||
} else {
|
||||
if (null != screenRecorder) {
|
||||
logger.info("设备【{}】还录着屏幕的,还保留一下这个线程............", deviceId);
|
||||
} else {
|
||||
logger.info("设备【{}】没有web端连接,也没有录频,退出............", deviceId);
|
||||
stopFetchPic();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setScreenOnRequest(Session session, CmdRequest screenOnRequest) {
|
||||
SessionUtils.sendSuccessData(session, screenOnRequest, null, "开启屏幕成功");
|
||||
}
|
||||
|
||||
public abstract void stopFetchPic();
|
||||
}
|
|
@ -1,27 +1,22 @@
|
|||
package net.northking.cctp.upperComputer.webSocket.thread;
|
||||
package net.northking.cctp.upperComputer.deviceManager.screen;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import net.northking.cctp.upperComputer.constants.ResponseCmd;
|
||||
import net.northking.cctp.upperComputer.deviceManager.IOSDeviceManager;
|
||||
import net.northking.cctp.upperComputer.deviceManager.thread.IosDeviceInitThread;
|
||||
import net.northking.cctp.upperComputer.driver.ios.NKAgent;
|
||||
import net.northking.cctp.upperComputer.driver.usbmuxd.AppleDevice;
|
||||
import net.northking.cctp.upperComputer.driver.usbmuxd.UsbMuxd;
|
||||
import net.northking.cctp.upperComputer.driver.usbmuxd.UsbMuxdConnectFailedException;
|
||||
import net.northking.cctp.upperComputer.driver.usbmuxd.payload.usbmuxd.entity.DeviceConnectionDetail;
|
||||
import net.northking.cctp.upperComputer.entity.PhoneEntity;
|
||||
import net.northking.cctp.upperComputer.utils.SessionUtils;
|
||||
import net.northking.cctp.upperComputer.webSocket.entity.CatchParam;
|
||||
import net.northking.cctp.upperComputer.webSocket.entity.CmdRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -30,7 +25,7 @@ import java.util.Map;
|
|||
* @author : yineng.huang
|
||||
* @date : 2023/10/17 16:41
|
||||
*/
|
||||
public class IosScreenResponseThread extends Thread {
|
||||
public class IosScreenResponseThread extends ImageScreenResponse {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(IosScreenResponseThread.class);
|
||||
|
||||
|
@ -53,32 +48,24 @@ public class IosScreenResponseThread extends Thread {
|
|||
|
||||
private PhoneEntity phone;
|
||||
|
||||
private Session webSession;
|
||||
|
||||
private long num = 1;
|
||||
|
||||
private CmdRequest screenOnRequest; //只是第一次连接需要,发送给前端代表连接成功
|
||||
|
||||
private UsbMuxd.ConnectOperator connectOperator;
|
||||
|
||||
private IosScreenRecordThread screenRecordThread;
|
||||
|
||||
private String recordingType = "0"; //录屏类型0-未录,1-真机录屏,2-自动化执行任务录屏
|
||||
|
||||
private boolean sendDeviceStatus = true;
|
||||
|
||||
private String currentTaskId;
|
||||
|
||||
// private IosScreenCompressHandleThread screenCompressHandle;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
logger.info("即将开始拉取设备【{}】图片................................", phone.getUdid());
|
||||
while (!isInterrupted()) {
|
||||
if (!CollectionUtils.isEmpty(webSessions)) {
|
||||
//通知前端开始连接
|
||||
Map<String, Object> messageMap = new HashMap<>();
|
||||
messageMap.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.CONNECTING);
|
||||
for (Session webSession : webSessions) {
|
||||
if (webSession.isOpen()) {
|
||||
SessionUtils.sendMessageInitiative(webSession, ResponseCmd.DEVICE_STATUS, phone.getUdid(), messageMap, "设备掉线了");
|
||||
}
|
||||
}
|
||||
}
|
||||
UsbMuxd usbmuxd = new UsbMuxd();
|
||||
connectOperator = getDeviceConnectOperator(usbmuxd);
|
||||
if (connectOperator == null) {
|
||||
|
@ -97,7 +84,7 @@ public class IosScreenResponseThread extends Thread {
|
|||
try {
|
||||
sleep(500);
|
||||
} catch (InterruptedException ignored) {
|
||||
Thread.currentThread().interrupt();
|
||||
interrupt();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -151,8 +138,8 @@ public class IosScreenResponseThread extends Thread {
|
|||
}
|
||||
byte[] rawImageFileByteArray = chunkBuffer.toByteArray();
|
||||
//这里是录屏
|
||||
if (null != screenRecordThread && screenRecordThread.isAlive()) {
|
||||
screenRecordThread.addImgToVideo(rawImageFileByteArray);
|
||||
if (null != screenRecorder) {
|
||||
screenRecorder.addImgToVideo(rawImageFileByteArray);
|
||||
}
|
||||
// if (compressQuality != 1f) {
|
||||
//
|
||||
|
@ -174,17 +161,23 @@ public class IosScreenResponseThread extends Thread {
|
|||
// lastRawChunkSize = rawImageFileByteArray.length;
|
||||
// }
|
||||
|
||||
if (null != this.webSession && this.webSession.isOpen()) {
|
||||
SessionUtils.sendBinary(this.webSession, rawImageFileByteArray);
|
||||
//有后端会话则给后端推送屏幕图片
|
||||
if (!CollectionUtils.isEmpty(webSessions)) {
|
||||
for (Session webSession : webSessions) {
|
||||
if (webSession.isOpen()) {
|
||||
if (sendDeviceStatus) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.CONNECTED);
|
||||
SessionUtils.sendMessageInitiative(webSession, ResponseCmd.DEVICE_STATUS, phone.getUdid(), result, "设备连接失败");
|
||||
sendDeviceStatus = false;
|
||||
}
|
||||
SessionUtils.sendBinary(webSession, rawImageFileByteArray);
|
||||
} else {
|
||||
logger.warn("推送到web端的session已经断开,sessionId:{}",webSession.getId());
|
||||
//todo:操作一下,去掉webSessions里面的无效session
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (null != screenCompressHandle && screenCompressHandle.isAlive() && !screenCompressHandle.isInterrupted()) {
|
||||
// screenCompressHandle.addData(rawImageFileByteArray);
|
||||
// }
|
||||
|
@ -227,10 +220,12 @@ public class IosScreenResponseThread extends Thread {
|
|||
/**
|
||||
* @param phone
|
||||
*/
|
||||
public IosScreenResponseThread(PhoneEntity phone, String currentTaskId) {
|
||||
public IosScreenResponseThread(PhoneEntity phone) {
|
||||
// screenCompressHandle = new IosScreenCompressHandleThread(phone.getUdid());
|
||||
// screenCompressHandle.start();
|
||||
this.phone = phone;
|
||||
this.deviceId = phone.getUdid();
|
||||
setName(phone.getUdid() + "拉取屏幕");
|
||||
this.currentTaskId = currentTaskId;
|
||||
}
|
||||
|
||||
private UsbMuxd.ConnectOperator getDeviceConnectOperator(UsbMuxd usbMuxd) {
|
||||
|
@ -254,12 +249,6 @@ public class IosScreenResponseThread extends Thread {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void setScreenOnRequest(CmdRequest screenOnRequest) {
|
||||
if (!isInterrupted() && null != this.webSession && this.webSession.isOpen()) { //只发第一次screen_on指令
|
||||
SessionUtils.sendSuccessData(this.webSession, screenOnRequest, null, "开启屏幕成功");
|
||||
}
|
||||
}
|
||||
|
||||
public void changeSize(int width, int height) {
|
||||
// if (this.screenCompressHandle != null && this.screenCompressHandle.isAlive() && !this.screenCompressHandle.isInterrupted()) {
|
||||
// this.screenCompressHandle.setScreenSize(width,height);
|
||||
|
@ -272,30 +261,14 @@ public class IosScreenResponseThread extends Thread {
|
|||
IosDeviceInitThread iosInitThread = IOSDeviceManager.getInstance().getIosInitThread(phone.getUdid());
|
||||
if (null != iosInitThread && !iosInitThread.isInterrupted() && iosInitThread.isAlive()) {
|
||||
logger.warn("设置手机【{}】推送图片的帧率:{}",phone.getUdid(),frameRate);
|
||||
NKAgent nkAgent = iosInitThread.getNkAgent();
|
||||
nkAgent.setMJPEGServerRate(frameRate);
|
||||
iosInitThread.setMJPEGServerRate(frameRate);
|
||||
} else {
|
||||
logger.warn("设备【{}】已经不在线了............................");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 1.判断是否处于自动化任务录屏中,若是,保留该线程,等待自动化录屏完成之后再退出
|
||||
* 2.若不处于自动化任务录屏中,判断是否真机录屏中,是则先退出真机的录屏,将录屏地址发送到服务端,若没有真机录屏,直接关闭
|
||||
*/
|
||||
public void stopFetchPic() {
|
||||
if (recordingType.equals("2")) { //直播退出
|
||||
logger.warn("该设备【{}】处于自动化的录屏阶段,稍后自动化录屏完成之后再退出手机屏幕的获取。。。。。。", phone.getUdid());
|
||||
this.webSession = null;
|
||||
return;
|
||||
}
|
||||
logger.warn("该设备【{}】未处于自动化的录屏阶段,现在退出屏幕抓取。。。。。。", phone.getUdid());
|
||||
String videoUrl = stopRecord();
|
||||
if (null != videoUrl) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("videoInfo", videoUrl);
|
||||
SessionUtils.sendMessageInitiative(webSession, ResponseCmd.RECORD_FINISH, this.phone.getUdid(), result, "结束录屏成功");
|
||||
}
|
||||
logger.warn("设备【{}】即将退出屏幕的抓取。。。。。。", phone.getUdid());
|
||||
if (null != connectOperator) {
|
||||
try {
|
||||
connectOperator.close();
|
||||
|
@ -304,63 +277,8 @@ public class IosScreenResponseThread extends Thread {
|
|||
}
|
||||
}
|
||||
IOSDeviceManager.getInstance().removeScreenThread(phone.getUdid());
|
||||
this.webSession = null;
|
||||
interrupt();
|
||||
}
|
||||
|
||||
public void startRecordScreen(String tenantId, int width, int height,String recordType, String currentTaskId){
|
||||
this.recordingType = recordType;
|
||||
if (null != screenRecordThread && screenRecordThread.isAlive()) {
|
||||
screenRecordThread.killRecord();
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
|
||||
String dateFormat = format.format(new Date());
|
||||
String videoName = this.phone.getUdid() + "_" + dateFormat + ".mp4";
|
||||
screenRecordThread = new IosScreenRecordThread(this.phone.getUdid(), videoName, tenantId,width, height, currentTaskId);
|
||||
screenRecordThread.start();
|
||||
}
|
||||
|
||||
//真机结束录屏
|
||||
public String stopRecord() {
|
||||
this.recordingType = "0";
|
||||
if (null == screenRecordThread || screenRecordThread.isInterrupted() || !screenRecordThread.isAlive()) {
|
||||
return null;
|
||||
}
|
||||
String result = screenRecordThread.endRecord();
|
||||
screenRecordThread = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
//自动化结束录屏
|
||||
public String stopRecord(String tenantId,boolean isSave) {
|
||||
this.recordingType = "0";
|
||||
if (null == screenRecordThread || screenRecordThread.isInterrupted() || !screenRecordThread.isAlive()) {
|
||||
return null;
|
||||
}
|
||||
String result = screenRecordThread.endRecord(tenantId,isSave);
|
||||
JSONObject object = JSONObject.parseObject(result, JSONObject.class);
|
||||
screenRecordThread = null;
|
||||
String videoUrl = object.getString("videoUrl");
|
||||
logger.debug("上传录屏的地址:{}", videoUrl);
|
||||
if (this.webSession == null) {
|
||||
logger.info("设备【{}】自动化录屏退出,同时退出设备的屏幕获取", phone.getUdid());
|
||||
stopFetchPic();
|
||||
} else {
|
||||
logger.info("设备【{}】正链接前端的屏幕,稍后退出", phone.getUdid());
|
||||
}
|
||||
return videoUrl;
|
||||
}
|
||||
|
||||
public void startSendScreenToWeb(Session session, CatchParam catchParam) {
|
||||
this.webSession = session;
|
||||
//通知前端开始连接
|
||||
Map<String, Object> messageMap = new HashMap<>();
|
||||
messageMap.put(ResponseCmd.DeviceStatus.STATUS, ResponseCmd.DeviceStatus.CONNECTING);
|
||||
SessionUtils.sendMessageInitiative(webSession, ResponseCmd.DEVICE_STATUS, phone.getUdid(), messageMap, "设备掉线了");
|
||||
this.sendDeviceStatus = true;
|
||||
}
|
||||
|
||||
public void setSendDeviceStatus(boolean sendDeviceStatus) {
|
||||
this.sendDeviceStatus = sendDeviceStatus;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
package net.northking.cctp.upperComputer.webSocket.thread;
|
||||
package net.northking.cctp.upperComputer.deviceManager.screen;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import net.northking.cctp.upperComputer.deviceManager.UpperComputerManager;
|
||||
import net.northking.cctp.upperComputer.enums.FileBusinessTypeEnum;
|
||||
import net.northking.cctp.upperComputer.entity.Attachment;
|
||||
import net.northking.cctp.upperComputer.utils.HttpUtils;
|
||||
import net.northking.cctp.upperComputer.utils.SpringUtils;
|
||||
|
@ -26,9 +25,9 @@ import java.util.Map;
|
|||
* @author : yineng.huang
|
||||
* @date : 2023/10/25 16:30
|
||||
*/
|
||||
public class IosScreenRecordThread extends Thread{
|
||||
public class ScreenRecorder {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(IosScreenRecordThread.class);
|
||||
private Logger logger = LoggerFactory.getLogger(ScreenRecorder.class);
|
||||
|
||||
private FFmpegFrameRecorder recorder;
|
||||
|
||||
|
@ -48,12 +47,13 @@ public class IosScreenRecordThread extends Thread{
|
|||
|
||||
private int videoHeight;
|
||||
|
||||
private String currentTaskId;
|
||||
private String taskId;
|
||||
|
||||
public IosScreenRecordThread(String udid, String videoName, String tenantId, int videoWidth, int videoHeight, String currentTaskId) {
|
||||
public ScreenRecorder(String udid, String videoName, String tenantId,String taskId, int videoWidth, int videoHeight) {
|
||||
this.udid = udid;
|
||||
this.videoName = videoName;
|
||||
this.tenantId = tenantId;
|
||||
this.taskId = taskId;
|
||||
this.videoWidth = videoWidth;
|
||||
this.videoHeight = videoHeight;
|
||||
this.filePath = UpperComputerManager.getInstance().getApplicationPath() + "/screenRecordTmp/";
|
||||
|
@ -63,40 +63,35 @@ public class IosScreenRecordThread extends Thread{
|
|||
}
|
||||
//todo:这里注意改正linux的配置参数,写文件
|
||||
recorder = new FFmpegFrameRecorder(filePath + videoName, videoWidth, videoHeight);
|
||||
// recorder.setFormat("mp4");
|
||||
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
|
||||
// recorder.setVideoCodec(opencv_cudacodec.MPEG4);
|
||||
recorder.setFrameRate(FRAME_RATE);
|
||||
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
|
||||
this.currentTaskId = currentTaskId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public void startRecordVideo() {
|
||||
try {
|
||||
recorder.start();
|
||||
} catch (FFmpegFrameRecorder.Exception e) {
|
||||
logger.warn("录屏启动失败。。。。。。。", e);
|
||||
}
|
||||
while (!isInterrupted()) {
|
||||
logger.info("ios设备【{}】录屏中。。。。。。。。。。。。。", udid);
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
logger.info("结束ios设备【{}】任务【{}】的录屏。。。。。。。", udid, videoName);
|
||||
logger.info("设备【{}】已开启录屏.............................",udid);
|
||||
}
|
||||
|
||||
public void addImgToVideo(byte[] imgData) {
|
||||
try {
|
||||
BufferedImage read = ImageIO.read(new ByteArrayInputStream(imgData));
|
||||
if (!recorder.isCloseOutputStream()) {
|
||||
recorder.record(converter.getFrame(read));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.warn("添加图片文件出现错误。。。。。",e);
|
||||
}
|
||||
}
|
||||
|
||||
public String endRecord() {
|
||||
logger.info("准备结束设备【{}】在taskId:{}的视频录制.............",udid,taskId);
|
||||
try {
|
||||
recorder.stop();
|
||||
} catch (FFmpegFrameRecorder.Exception e) {
|
||||
|
@ -108,37 +103,10 @@ public class IosScreenRecordThread extends Thread{
|
|||
logger.warn("释放录屏失败。。。。。。", e);
|
||||
}
|
||||
String result = uploadVideoToServer();
|
||||
this.interrupt();
|
||||
logger.info("设备【{}】在taskId:{}的视频录制已经结束,得到的视频地址为:{}.............",udid,taskId,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public String endRecord(Boolean save) {
|
||||
try {
|
||||
recorder.stop();
|
||||
} catch (FFmpegFrameRecorder.Exception e) {
|
||||
logger.warn("结束录屏失败。。。。。。", e);
|
||||
}
|
||||
try {
|
||||
recorder.release();
|
||||
} catch (FFmpegFrameRecorder.Exception e) {
|
||||
logger.warn("释放录屏失败。。。。。。", e);
|
||||
}
|
||||
String result = null;
|
||||
if (null != save && save) {
|
||||
result = uploadVideoToServer();
|
||||
}else {
|
||||
logger.debug("录屏文件不保存!");
|
||||
}
|
||||
this.interrupt();
|
||||
return result;
|
||||
}
|
||||
|
||||
public String endRecord(String tenantId,Boolean save) {
|
||||
this.tenantId = tenantId;
|
||||
return endRecord(save);
|
||||
}
|
||||
|
||||
|
||||
private String uploadVideoToServer() {
|
||||
Map<String, String> resultMap = new HashMap<>();
|
||||
try {
|
||||
|
@ -146,36 +114,22 @@ public class IosScreenRecordThread extends Thread{
|
|||
logger.debug("[" +udid+ "]录屏停止,开始上传视屏文件");
|
||||
String serverAddress = SpringUtils.getProperties("nk.mobile-computer.serverAddr");
|
||||
String pubUploadPath = SpringUtils.getProperties("nk.mobile-computer.publicUploadAddr");
|
||||
logger.info("开始上传ios视频文件");
|
||||
Attachment upload = HttpUtils.upload(serverAddress + pubUploadPath, filePath + videoName, tenantId, currentTaskId, FileBusinessTypeEnum.MOBILE_TASK_VIDEO.getCode());
|
||||
Attachment upload = HttpUtils.upload(serverAddress + pubUploadPath, filePath + videoName, tenantId);
|
||||
if (null != upload && StringUtils.isNotBlank(upload.getId())) {
|
||||
logger.info("文件上传成功,返回id:{}", upload.getId());
|
||||
logger.debug("文件上传成功,返回id:{}", upload.getId());
|
||||
resultMap.put("videoUrl", upload.getUrlPath());
|
||||
resultMap.put("videoRef", videoWidth + "x" + videoHeight);
|
||||
return JSON.toJSONString(resultMap);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("上传视频文件失败。。。。。。。。", e);
|
||||
}finally {
|
||||
|
||||
}
|
||||
//todo:上传完之后要删除
|
||||
return null;
|
||||
}
|
||||
|
||||
public void killRecord() {
|
||||
try {
|
||||
recorder.stop();
|
||||
} catch (FFmpegFrameRecorder.Exception e) {
|
||||
logger.warn("结束录屏失败。。。。。。", e);
|
||||
}
|
||||
try {
|
||||
recorder.release();
|
||||
} catch (FFmpegFrameRecorder.Exception e) {
|
||||
logger.warn("释放录屏失败。。。。。。", e);
|
||||
}
|
||||
File file = new File(filePath + videoName);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
interrupt();
|
||||
public String getTaskId() {
|
||||
return taskId;
|
||||
}
|
||||
}
|
|
@ -431,6 +431,7 @@ public class AndroidDeviceInitThread extends Thread {
|
|||
Map<String, Integer> sizeMap = new HashMap<>();
|
||||
sizeMap.put("width", displayData.getWidth());
|
||||
sizeMap.put("height", displayData.getHeight());
|
||||
sizeMap.put("rotation", displayData.getRotation());
|
||||
return sizeMap;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -27,6 +27,8 @@ public abstract class IosDeviceInitThread extends Thread {
|
|||
|
||||
protected AppleDevice appleDevice;
|
||||
|
||||
private int frame = 12;
|
||||
|
||||
public IosDeviceInitThread(PhoneEntity phone, AppleDevice appleDevice) {
|
||||
this.phone = phone;
|
||||
this.appleDevice = appleDevice;
|
||||
|
@ -45,8 +47,8 @@ public abstract class IosDeviceInitThread extends Thread {
|
|||
nkAgentReady = nkAgent.getStatus();
|
||||
logger.debug("设备【{}】的nkAgent连接完成,结果:{}", phone.getUdid(),nkAgentReady);
|
||||
if (nkAgentReady) {
|
||||
logger.debug("设置设备【{}】的帧数为:{}", phone.getUdid(), 25);
|
||||
nkAgent.setMJPEGServerRate(25);
|
||||
logger.debug("设置设备【{}】的帧数为:{}", phone.getUdid(), frame);
|
||||
nkAgent.setMJPEGServerRate(frame);
|
||||
} else {
|
||||
logger.error("第{}次连接设备【{}】的agent不成功,等待下一次......",reTryTime, phone.getUdid());
|
||||
}
|
||||
|
@ -91,5 +93,9 @@ public abstract class IosDeviceInitThread extends Thread {
|
|||
return String.format("%s%d%d_%d-%d-%d", calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
|
||||
}
|
||||
|
||||
public void setMJPEGServerRate(int frameRate){
|
||||
this.frame = frameRate;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import io.appium.java_client.AppiumDriver;
|
|||
import io.appium.java_client.android.AndroidDriver;
|
||||
import io.appium.java_client.ios.IOSDriver;
|
||||
import net.northking.cctp.upperComputer.config.MobileProperty;
|
||||
import net.northking.cctp.upperComputer.deviceManager.screen.AndroidScreenResponseThread;
|
||||
import net.northking.cctp.upperComputer.deviceManager.thread.AndroidDeviceInitThread;
|
||||
import net.northking.cctp.upperComputer.driver.adb.Adb;
|
||||
import net.northking.cctp.upperComputer.driver.adb.AdbDevice;
|
||||
import net.northking.cctp.upperComputer.driver.adb.AdbTransport;
|
||||
|
@ -18,9 +20,11 @@ import net.northking.cctp.upperComputer.entity.DebuggerDeviceInfo;
|
|||
import net.northking.cctp.upperComputer.exception.AppiumException;
|
||||
import net.northking.cctp.upperComputer.exception.ExecuteException;
|
||||
import net.northking.cctp.upperComputer.deviceManager.AndroidDeviceManager;
|
||||
import net.northking.cctp.upperComputer.exception.ParamMistakeException;
|
||||
import net.northking.cctp.upperComputer.service.thread.AndroidDeviceAllInfoThread;
|
||||
import net.northking.cctp.upperComputer.service.thread.AndroidDeviceInfoByPackageThread;
|
||||
import net.northking.cctp.upperComputer.utils.*;
|
||||
import net.northking.cctp.upperComputer.webSocket.entity.CatchParam;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||
|
@ -705,111 +709,172 @@ public class AndroidDebuggerServiceImpl extends AbstractDebuggerService {
|
|||
|
||||
private Map<String, Process> processMap = new HashMap<>();
|
||||
|
||||
// @Override
|
||||
// public boolean startRecord(DebuggerDeviceInfo info) {
|
||||
// logger.info("开启录屏");
|
||||
// String taskId = info.getTaskId();
|
||||
// if (StringUtils.isBlank(taskId)) {
|
||||
// logger.warn("任务id必填");
|
||||
// return false;
|
||||
// }
|
||||
// String videoPath = mobileProperty.getStfPath() + "/temp";
|
||||
// Thread thread = new Thread(() -> {
|
||||
// File file = new File(videoPath);
|
||||
// if (!file.isDirectory()) {
|
||||
// file.mkdirs();
|
||||
// }
|
||||
// logger.info("录屏前先kill掉所有scrcpy进程");
|
||||
// String pullCmd = String.format("ps -ef|grep 'scrcpy -s %s -b 2M -Nr %s' |grep -v grep |awk '{print $2}' |xargs --no-run-if-empty kill -9", info.getDeviceId(), videoPath + "/" + taskId + ".mp4");
|
||||
// String[] delCmd = {"/bin/sh", "-c", pullCmd};
|
||||
// try {
|
||||
// Process delProcess = Runtime.getRuntime().exec(delCmd, null, null);
|
||||
// delProcess.waitFor();
|
||||
// logger.info("录屏开启命令:" + pullCmd);
|
||||
// delProcess.destroy();
|
||||
// } catch (Exception e) {
|
||||
// logger.error("删除scrcpy进程失败:", e);
|
||||
// }
|
||||
// String cmd = String.format("scrcpy -s %s -b 2M -Nr %s ", info.getDeviceId(), videoPath + "/" + taskId + ".mp4");
|
||||
// logger.info(cmd);
|
||||
//// if(props.getProperty("os.name").contains("Linux")){
|
||||
//// }
|
||||
// try {
|
||||
// Process process = Runtime.getRuntime().exec(cmd);
|
||||
// processMap.put(taskId, process);
|
||||
// logger.info("开启scrcpy进程");
|
||||
// } catch (IOException e) {
|
||||
// logger.error("开启录屏异常:", e);
|
||||
// }
|
||||
// });
|
||||
// thread.start();
|
||||
// try {
|
||||
// Thread.sleep(2000);
|
||||
// } catch (InterruptedException e) {
|
||||
// logger.warn("线程终止。。。。。。", e);
|
||||
// Thread.currentThread().interrupt();
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean startRecord(DebuggerDeviceInfo info) {
|
||||
logger.info("开启录屏");
|
||||
String taskId = info.getTaskId();
|
||||
logger.info("收到设备【{}】在任务【{}】开启录屏的请求............",info.getDeviceId(),taskId);
|
||||
if (StringUtils.isBlank(taskId)) {
|
||||
logger.warn("任务id必填");
|
||||
logger.error("设备【{}】在录屏的时候任务id不存在",info.getDeviceId());
|
||||
return false;
|
||||
}
|
||||
String videoPath = mobileProperty.getStfPath() + "/temp";
|
||||
Thread thread = new Thread(() -> {
|
||||
File file = new File(videoPath);
|
||||
if (!file.isDirectory()) {
|
||||
file.mkdirs();
|
||||
AdbDevice currentDevice = AndroidDeviceManager.getInstance().getCurrentDevice(info.getDeviceId());
|
||||
if (null == currentDevice) {
|
||||
logger.error("设备【{}】当前不在线,无法录视频..........",info.getDeviceId());
|
||||
return false;
|
||||
}
|
||||
logger.info("录屏前先kill掉所有scrcpy进程");
|
||||
String pullCmd = String.format("ps -ef|grep 'scrcpy -s %s -b 2M -Nr %s' |grep -v grep |awk '{print $2}' |xargs --no-run-if-empty kill -9", info.getDeviceId(), videoPath + "/" + taskId + ".mp4");
|
||||
String[] delCmd = {"/bin/sh", "-c", pullCmd};
|
||||
try {
|
||||
Process delProcess = Runtime.getRuntime().exec(delCmd, null, null);
|
||||
delProcess.waitFor();
|
||||
logger.info("录屏开启命令:" + pullCmd);
|
||||
delProcess.destroy();
|
||||
} catch (Exception e) {
|
||||
logger.error("删除scrcpy进程失败:", e);
|
||||
logger.info("获取手机【{}】的实际宽高............................",info.getDeviceId());
|
||||
AndroidDeviceInitThread androidInitThread = AndroidDeviceManager.getInstance().getAndroidInitThread(info.getDeviceId());
|
||||
if (null == androidInitThread) {
|
||||
throw new ParamMistakeException(String.format("手机【%s】已离线,请稍后再试!", info.getDeviceId()));
|
||||
}
|
||||
Map<String, Integer> screenSizeMap = androidInitThread.getRealScreenSize();
|
||||
if (null == screenSizeMap) {
|
||||
throw new ParamMistakeException(String.format("获取手机【%s】实际宽高失败,请稍后再试!", info.getDeviceId()));
|
||||
}
|
||||
CatchParam catchParam = new CatchParam();
|
||||
catchParam.setRealHeight(screenSizeMap.get("height"));
|
||||
catchParam.setRealWidth(screenSizeMap.get("width"));
|
||||
catchParam.setWidth(screenSizeMap.get("width")/2);
|
||||
catchParam.setHeight(screenSizeMap.get("width")/2);
|
||||
catchParam.setFrameRate(30);
|
||||
catchParam.setQuality(75);
|
||||
catchParam.setRotation(screenSizeMap.get("rotation"));
|
||||
logger.info("手机【{}】的实际宽:{}高:{}............................",info.getDeviceId() ,catchParam.getRealWidth(), catchParam.getRealHeight());
|
||||
AndroidScreenResponseThread screenThread = AndroidDeviceManager.getInstance().getScreenThread(info.getDeviceId());
|
||||
if (null == screenThread || screenThread.isInterrupted() || !screenThread.isAlive()) { //没人连手机
|
||||
screenThread = new AndroidScreenResponseThread(currentDevice);
|
||||
screenThread.setCatchParam(catchParam);
|
||||
screenThread.start();
|
||||
AndroidDeviceManager.getInstance().saveDeviceScreenThread(info.getDeviceId(),screenThread);
|
||||
}
|
||||
screenThread.startRecordScreen(info.getTenantId(), catchParam.getRealWidth(), catchParam.getRealHeight(),taskId);
|
||||
return true;
|
||||
}
|
||||
String cmd = String.format("scrcpy -s %s -b 2M -Nr %s ", info.getDeviceId(), videoPath + "/" + taskId + ".mp4");
|
||||
logger.info(cmd);
|
||||
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec(cmd);
|
||||
processMap.put(taskId, process);
|
||||
logger.info("开启scrcpy进程");
|
||||
} catch (IOException e) {
|
||||
logger.error("开启录屏异常:", e);
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
logger.warn("线程终止。。。。。。", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// @Override
|
||||
// public String endRecord(DebuggerDeviceInfo info) {
|
||||
// String taskId = info.getTaskId();
|
||||
// if (StringUtils.isBlank(taskId)) {
|
||||
// logger.warn("任务id必填");
|
||||
// return null;
|
||||
// }
|
||||
// String videoPath = null;
|
||||
// String filePath = mobileProperty.getStfPath() + "/temp";
|
||||
// logger.info("关闭scrcpy进程");
|
||||
// try {
|
||||
// Process process = processMap.remove(taskId);
|
||||
// if (process != null) {
|
||||
// process.destroy();
|
||||
// process = null;
|
||||
// }
|
||||
// Thread.sleep(2000);
|
||||
// } catch (Exception e) {
|
||||
// logger.error("关闭录屏异常", e);
|
||||
// return videoPath;
|
||||
// }
|
||||
// Boolean save = info.getSave();
|
||||
// logger.info("上传视频文件");
|
||||
// String fileName = filePath + "/" + taskId + ".mp4";
|
||||
// File temp = new File(fileName);
|
||||
// if (save) {
|
||||
// try {
|
||||
// //等待文件生成
|
||||
// Thread.sleep(3000);
|
||||
// } catch (InterruptedException e) {
|
||||
// logger.warn("线程终止。。。。。。", e);
|
||||
// Thread.currentThread().interrupt();
|
||||
// }
|
||||
// if (!temp.exists()) {
|
||||
// logger.warn("结束录屏失败:视频文件不存在,文件路径:{}", fileName);
|
||||
// return videoPath;
|
||||
// }
|
||||
// try {
|
||||
// //租户id
|
||||
// String tenantId = info.getTenantId();
|
||||
//// NKFile nkFile = simpleStorageService.upload(tenantId, temp);
|
||||
//// if (nkFile != null && StringUtils.isNotBlank(nkFile.getId())) {
|
||||
//// logger.debug("文件上传成功,返回id:{}", nkFile.getId());
|
||||
//// String fileId = nkFile.getId();
|
||||
//// videoPath = pathToId(tenantId,fileId);
|
||||
//// }
|
||||
// Attachment upload = HttpUtils.upload(mobileProperty.getServerAddr() + mobileProperty.getPublicUploadAddr(), temp.getAbsolutePath(), tenantId);
|
||||
// if (null != upload && StringUtils.isNotBlank(upload.getId())) {
|
||||
// logger.debug("文件上传成功,返回id:{}", upload.getId());
|
||||
// videoPath = upload.getUrlPath();
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// logger.error("结束录屏失败,文件上传未成功:", e);
|
||||
// return videoPath;
|
||||
// }
|
||||
// }
|
||||
// try {
|
||||
// temp.deleteOnExit();
|
||||
// } catch (Exception e) {
|
||||
// logger.error("删除文件失败:", e);
|
||||
// }
|
||||
// return videoPath;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String endRecord(DebuggerDeviceInfo info) {
|
||||
String taskId = info.getTaskId();
|
||||
if (StringUtils.isBlank(taskId)) {
|
||||
logger.warn("任务id必填");
|
||||
return null;
|
||||
String result = null;
|
||||
logger.info("收到设备【{}】在任务【{}】关闭录屏的请求............",info.getDeviceId(),info.getTaskId());
|
||||
AndroidScreenResponseThread screenThread = AndroidDeviceManager.getInstance().getScreenThread(info.getDeviceId());
|
||||
if (null != screenThread && screenThread.isAlive() && !screenThread.isInterrupted()) {
|
||||
result = screenThread.stopRecord();
|
||||
return result;
|
||||
} else {
|
||||
logger.info("设备【{}】在任务【{}】录屏不存在............",info.getDeviceId(),info.getTaskId());
|
||||
}
|
||||
String videoPath = null;
|
||||
String filePath = mobileProperty.getStfPath() + "/temp";
|
||||
logger.info("关闭scrcpy进程");
|
||||
try {
|
||||
Process process = processMap.remove(taskId);
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
process = null;
|
||||
}
|
||||
Thread.sleep(2000);
|
||||
} catch (Exception e) {
|
||||
logger.error("关闭录屏异常", e);
|
||||
return videoPath;
|
||||
}
|
||||
Boolean save = info.getSave();
|
||||
logger.info("上传视频文件");
|
||||
String fileName = filePath + "/" + taskId + ".mp4";
|
||||
File temp = new File(fileName);
|
||||
if (save) {
|
||||
try {
|
||||
//等待文件生成
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException e) {
|
||||
logger.warn("线程终止。。。。。。", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
if (!temp.exists()) {
|
||||
logger.warn("结束录屏失败:视频文件不存在,文件路径:{}", fileName);
|
||||
return videoPath;
|
||||
}
|
||||
logger.info("视频文件路径:{},视频文件大小:{}", temp.getAbsolutePath(), temp.length());
|
||||
try {
|
||||
//租户id
|
||||
String tenantId = info.getTenantId();
|
||||
|
||||
logger.info("开始上传视频文件,任务信息:{},android设备{}", JSON.toJSONString(info), info.getDeviceId());
|
||||
Attachment upload = HttpUtils.upload(mobileProperty.getServerAddr() + mobileProperty.getPublicUploadAddr(), temp.getAbsolutePath(), tenantId, taskId, FileBusinessTypeEnum.MOBILE_TASK_VIDEO.getCode());
|
||||
if (null != upload && StringUtils.isNotBlank(upload.getId())) {
|
||||
logger.debug("文件上传成功,返回id:{}", upload.getId());
|
||||
videoPath = upload.getUrlPath();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("结束录屏失败,文件上传未成功:", e);
|
||||
return videoPath;
|
||||
}
|
||||
}
|
||||
try {
|
||||
temp.deleteOnExit();
|
||||
} catch (Exception e) {
|
||||
logger.error("删除文件失败:", e);
|
||||
}
|
||||
return videoPath;
|
||||
logger.info("设备【{}】在任务【{}】录屏保存的地址:{}............",info.getDeviceId(),info.getTaskId(),result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSON;
|
|||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.appium.java_client.AppiumDriver;
|
||||
import net.northking.cctp.upperComputer.config.MobileProperty;
|
||||
import net.northking.cctp.upperComputer.deviceManager.screen.IosScreenResponseThread;
|
||||
import net.northking.cctp.upperComputer.entity.Attachment;
|
||||
import net.northking.cctp.upperComputer.entity.DebuggerDeviceInfo;
|
||||
import net.northking.cctp.upperComputer.entity.PhoneEntity;
|
||||
|
@ -17,7 +18,6 @@ import net.northking.cctp.upperComputer.service.thread.IOSDeviceInfoByPackageThr
|
|||
import net.northking.cctp.upperComputer.deviceManager.IOSDeviceManager;
|
||||
import net.northking.cctp.upperComputer.utils.HttpUtils;
|
||||
import net.northking.cctp.upperComputer.utils.ScreenShotUtils;
|
||||
import net.northking.cctp.upperComputer.webSocket.thread.IosScreenResponseThread;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -219,10 +219,13 @@ public class IosDebuggerServiceImpl extends AbstractDebuggerService {
|
|||
return path;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean startRecord(DebuggerDeviceInfo info) {
|
||||
IosScreenResponseThread screenThread = IOSDeviceManager.getInstance().getScreenThread(info.getDeviceId());
|
||||
logger.info("收到设备【{}】在任务【{}】开启录屏的请求............",info.getDeviceId(),info.getTaskId());
|
||||
net.northking.cctp.upperComputer.deviceManager.screen.IosScreenResponseThread screenThread = IOSDeviceManager.getInstance().getScreenThread(info.getDeviceId());
|
||||
String taskId = info.getTaskId();
|
||||
String tenantId = info.getTenantId();
|
||||
String resolution = info.getResolution();
|
||||
String[] split = resolution.split("\\*");
|
||||
int width = Integer.parseInt(split[0]);
|
||||
|
@ -235,24 +238,27 @@ public class IosDebuggerServiceImpl extends AbstractDebuggerService {
|
|||
}
|
||||
if (null == screenThread || screenThread.isInterrupted() || !screenThread.isAlive()) { //没人连手机
|
||||
PhoneEntity phoneEntity = IOSDeviceManager.getInstance().getPhoneEntity(info.getDeviceId());
|
||||
screenThread = new IosScreenResponseThread(phoneEntity, taskId);
|
||||
screenThread = new net.northking.cctp.upperComputer.deviceManager.screen.IosScreenResponseThread(phoneEntity);
|
||||
screenThread.start();
|
||||
IOSDeviceManager.getInstance().saveDeviceScreenThread(info.getDeviceId(),screenThread);
|
||||
}
|
||||
screenThread.startRecordScreen("default", width, height,"2", taskId);
|
||||
screenThread.startRecordScreen(tenantId, width, height,taskId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String endRecord(DebuggerDeviceInfo info) {
|
||||
String result = null;
|
||||
logger.info("收到设备【{}】在任务【{}】关闭录屏的请求............",info.getDeviceId(),info.getTaskId());
|
||||
IosScreenResponseThread screenThread = IOSDeviceManager.getInstance().getScreenThread(info.getDeviceId());
|
||||
if (null != screenThread && screenThread.isAlive() && !screenThread.isInterrupted()) {
|
||||
String tenantId = info.getTenantId();
|
||||
//增加是否保存录屏文件的参数
|
||||
String result = screenThread.stopRecord(tenantId,info.getSave());
|
||||
result = screenThread.stopRecord();
|
||||
return result;
|
||||
} else {
|
||||
logger.info("设备【{}】在任务【{}】录屏不存在............",info.getDeviceId(),info.getTaskId());
|
||||
}
|
||||
return null;
|
||||
logger.info("设备【{}】在任务【{}】录屏保存的地址:{}............",info.getDeviceId(),info.getTaskId(),result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,6 +2,7 @@ package net.northking.cctp.upperComputer.webSocket.thread;
|
|||
|
||||
import net.northking.cctp.upperComputer.constants.KeyBoardCodeEnum;
|
||||
import net.northking.cctp.upperComputer.deviceManager.IOSDeviceManager;
|
||||
import net.northking.cctp.upperComputer.deviceManager.screen.IosScreenResponseThread;
|
||||
import net.northking.cctp.upperComputer.deviceManager.thread.IosDeviceInitThread;
|
||||
import net.northking.cctp.upperComputer.driver.ios.NKAgent;
|
||||
import net.northking.cctp.upperComputer.driver.ios.command.data.UiNodeData;
|
||||
|
@ -34,8 +35,6 @@ public abstract class AbstractIosMessageHandlerThread extends AbstractMessageHan
|
|||
|
||||
protected IosFunctionByAgent function;
|
||||
|
||||
protected IosScreenResponseThread screenResponseThread;
|
||||
|
||||
protected GetNodeTreeThread nodeTreeThread;
|
||||
|
||||
protected StopWatch handleWatch = new StopWatch();
|
||||
|
@ -160,7 +159,6 @@ public abstract class AbstractIosMessageHandlerThread extends AbstractMessageHan
|
|||
SessionUtils.sendSuccessData(session, request, uiNodeData, "获取节点树成功");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clearAndCloseDeviceAgentConnection() {
|
||||
//通知前端设备现在处于掉线的状态,前端开始转圈
|
||||
|
@ -170,8 +168,12 @@ public abstract class AbstractIosMessageHandlerThread extends AbstractMessageHan
|
|||
@Override
|
||||
public void reConnectDeviceAgent() {
|
||||
notifyDeviceOnlineToWeb();
|
||||
//发送前端重连成功消息的标志
|
||||
IosScreenResponseThread screenResponseThread = IOSDeviceManager.getInstance().getScreenThread(phoneEntity.getUdid());
|
||||
if (null != screenResponseThread) {
|
||||
screenResponseThread.setSendDeviceStatus(true); //发送连接成功消息
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -551,35 +553,6 @@ public abstract class AbstractIosMessageHandlerThread extends AbstractMessageHan
|
|||
return new Point(realX.floatValue(), realY.floatValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopRecordScreen(CmdRequest request) {
|
||||
String recordFileInfo = screenResponseThread.stopRecord();
|
||||
if (recordFileInfo != null) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("videoInfo", recordFileInfo);
|
||||
SessionUtils.sendSuccessData(session, request, result, "结束录屏成功");
|
||||
} else {
|
||||
SessionUtils.sendFailureMessage(session, request, "该设备未开启录屏");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startRecordScreen(CmdRequest request) {
|
||||
Map<String, Object> data = request.getData();
|
||||
ParamCheck tenantIdCheck = ParamCheck.build().name("tenantId").type("string").length(32);
|
||||
Map<String, Object> params = null;
|
||||
try {
|
||||
params = checkParam(data, false, tenantIdCheck);
|
||||
} catch (Exception e) {
|
||||
logger.error("参数校验失败!", e);
|
||||
if (e instanceof ParamMistakeException) {
|
||||
SessionUtils.sendFailureMessage(session, request, e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
screenResponseThread.startRecordScreen((String) params.get("tenantId"), catchParam.getRealWidth(), catchParam.getRealHeight(), "1", null);
|
||||
SessionUtils.sendSuccessData(session, request, null, "开启录屏成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeScreenQuality(CmdRequest request) {
|
||||
|
@ -601,6 +574,7 @@ public abstract class AbstractIosMessageHandlerThread extends AbstractMessageHan
|
|||
int frameRateUse = (int) params.get("framerate");
|
||||
catchParam.setFrameRate(frameRateUse);
|
||||
logger.debug("改变屏幕质量=====>width:{} height:{} quality:{} frameRate:{}", catchParam.getWidth(), catchParam.getHeight(), qualityUse, frameRateUse);
|
||||
IosScreenResponseThread screenResponseThread = IOSDeviceManager.getInstance().getScreenThread(phoneEntity.getUdid());
|
||||
screenResponseThread.changeQuality(qualityUse / 100f,frameRateUse);
|
||||
}
|
||||
|
||||
|
@ -624,6 +598,7 @@ public abstract class AbstractIosMessageHandlerThread extends AbstractMessageHan
|
|||
int heightUse = (int) params.get("height");
|
||||
catchParam.setHeight(heightUse);
|
||||
logger.debug("改变宽高屏幕=====>width:{} height:{} quality:{} frameRate:{}", widthUse, heightUse, catchParam.getQuality(), catchParam.getFrameRate());
|
||||
IosScreenResponseThread screenResponseThread = IOSDeviceManager.getInstance().getScreenThread(phoneEntity.getUdid());
|
||||
screenResponseThread.changeSize(widthUse, heightUse);
|
||||
}
|
||||
|
||||
|
@ -657,25 +632,23 @@ public abstract class AbstractIosMessageHandlerThread extends AbstractMessageHan
|
|||
int rotationUse = (int) params.get("rotation");
|
||||
catchParam.setRotation(rotationUse);
|
||||
logger.debug("开启屏幕=====>width:{} height:{} quality:{} frameRate:{},rotation:{}", widthUse, heightUse, qualityUse, frameRateUse, rotationUse);
|
||||
screenResponseThread = IOSDeviceManager.getInstance().getScreenThread(phoneEntity.getUdid());
|
||||
IosScreenResponseThread screenResponseThread = IOSDeviceManager.getInstance().getScreenThread(phoneEntity.getUdid());
|
||||
if (null == screenResponseThread || screenResponseThread.isInterrupted() || !screenResponseThread.isAlive()) {
|
||||
//读取手机端响应线程
|
||||
screenResponseThread = new IosScreenResponseThread(phoneEntity, null);
|
||||
screenResponseThread = new IosScreenResponseThread(phoneEntity);
|
||||
screenResponseThread.start();
|
||||
screenResponseThread.startSendScreenToWeb(session, catchParam);
|
||||
screenResponseThread.setScreenOnRequest(request);
|
||||
screenResponseThread.setScreenOnRequest(session,request);
|
||||
IOSDeviceManager.getInstance().saveDeviceScreenThread(phoneEntity.getUdid(), screenResponseThread);
|
||||
} else {
|
||||
screenResponseThread.startSendScreenToWeb(session, catchParam);
|
||||
screenResponseThread.setScreenOnRequest(request);
|
||||
screenResponseThread.setScreenOnRequest(session,request);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopAndExit() {
|
||||
if (null != screenResponseThread) {
|
||||
screenResponseThread.stopFetchPic();
|
||||
}
|
||||
IOSDeviceManager.getInstance().stopWebScreen(phoneEntity.getUdid(),session);
|
||||
if (null != iosPerfThread) {
|
||||
iosPerfThread.stopThread();
|
||||
}
|
||||
|
|
|
@ -60,10 +60,6 @@ public abstract class AbstractMessageHandler extends Thread implements MessageHa
|
|||
changeScreenSize(request);
|
||||
} else if (RequestCmd.SCREEN_QUALITY.equals(request.getCmd())) { //改变屏幕质量
|
||||
changeScreenQuality(request);
|
||||
} else if (RequestCmd.SCREEN_RECORD_ON.equals(request.getCmd())) {//开启录屏
|
||||
startRecordScreen(request);
|
||||
} else if (RequestCmd.SCREEN_RECORD_OFF.equals(request.getCmd())) { //结束录屏
|
||||
stopRecordScreen(request);
|
||||
} else if (RequestCmd.SCREEN_CAPTURE.equals(request.getCmd())) {//截图
|
||||
screenShot(request);
|
||||
} else if (RequestCmd.INPUT_TOUCH_DOWN.equals(request.getCmd())) { //鼠标摁下
|
||||
|
|
|
@ -6,6 +6,8 @@ import net.northking.cctp.upperComputer.constants.KeyBoardCodeEnum;
|
|||
import net.northking.cctp.upperComputer.constants.ResponseCmd;
|
||||
import net.northking.cctp.upperComputer.deviceManager.AndroidDeviceManager;
|
||||
import net.northking.cctp.upperComputer.deviceManager.UpperComputerManager;
|
||||
import net.northking.cctp.upperComputer.deviceManager.screen.AndroidScreenResponseThread;
|
||||
import net.northking.cctp.upperComputer.deviceManager.screen.AndroidVideoScreenResponseThread;
|
||||
import net.northking.cctp.upperComputer.deviceManager.thread.AndroidDeviceInitThread;
|
||||
import net.northking.cctp.upperComputer.driver.adb.AdbDevice;
|
||||
import net.northking.cctp.upperComputer.driver.adb.AdbTransport;
|
||||
|
@ -16,7 +18,6 @@ import net.northking.cctp.upperComputer.driver.agent.command.*;
|
|||
import net.northking.cctp.upperComputer.driver.agent.command.data.PackageInfo;
|
||||
import net.northking.cctp.upperComputer.driver.agent.command.protocol.ProtocolCommand;
|
||||
import net.northking.cctp.upperComputer.entity.Attachment;
|
||||
import net.northking.cctp.upperComputer.enums.FileBusinessTypeEnum;
|
||||
import net.northking.cctp.upperComputer.exception.ExecuteException;
|
||||
import net.northking.cctp.upperComputer.exception.ParamMistakeException;
|
||||
import net.northking.cctp.upperComputer.utils.HttpUtils;
|
||||
|
@ -50,8 +51,6 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
|
||||
private String tenantId;
|
||||
|
||||
private AndroidScreenRecordThread screenRecordThread;
|
||||
|
||||
private AndroidLogThread androidLogThread;
|
||||
|
||||
private AndroidPerfThread androidPerfThread;
|
||||
|
@ -68,8 +67,6 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
|
||||
private boolean capsDown = false;
|
||||
|
||||
private AndroidScreenResponseThread responseThread;
|
||||
|
||||
private AndroidVideoScreenResponseThread videoScreenResponseThread;
|
||||
|
||||
private List<String> capsUpLetters = Arrays.asList("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z");
|
||||
|
@ -154,7 +151,7 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
//上传到服务器
|
||||
String serverIp = SpringUtils.getProperties("nk.mobile-computer.serverAddr");
|
||||
String fileUploadPath = SpringUtils.getProperties("nk.mobile-computer.publicUploadAddr");
|
||||
String fileId = HttpUtils.doUpload(serverIp + fileUploadPath, tmpFile, tenantId,null, FileBusinessTypeEnum.MOBILE_TASK_SCREENSHOT.getCode());
|
||||
String fileId = HttpUtils.doUpload(serverIp + fileUploadPath, tmpFile, tenantId);
|
||||
logger.info("上传文件到服务器完成:{}", fileId);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("fileName", fileName);
|
||||
|
@ -325,7 +322,6 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void getNodeTreeOnce(CmdRequest request) {
|
||||
|
||||
|
@ -365,8 +361,10 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
throw new ExecuteException("设备还未准备好,请稍后再试");
|
||||
}
|
||||
notifyDeviceOnlineToWeb();
|
||||
if(responseThread != null){
|
||||
responseThread.setSendDeviceStatus(true); //发送连接成功消息
|
||||
//发送前端重连成功消息的标志
|
||||
AndroidScreenResponseThread screenThread = AndroidDeviceManager.getInstance().getScreenThread(adbDevice.getSerial());
|
||||
if (null != screenThread) {
|
||||
screenThread.setSendDeviceStatus(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1152,7 +1150,7 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
String pubUploadPath = SpringUtils.getProperties("nk.mobile-computer.publicUploadAddr");
|
||||
Attachment upload = null;
|
||||
try {
|
||||
upload = HttpUtils.upload(serverAddress + pubUploadPath, screenShotData, tenantId,null,FileBusinessTypeEnum.MOBILE_TASK_SCREENSHOT.getCode());
|
||||
upload = HttpUtils.upload(serverAddress + pubUploadPath, screenShotData, tenantId);
|
||||
} catch (Exception e) {
|
||||
logger.debug("[{}]上传截图失败", adbDevice.getSerial(),e);
|
||||
}
|
||||
|
@ -1172,45 +1170,9 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopRecordScreen(CmdRequest request) {
|
||||
if (screenRecordThread != null && screenRecordThread.isAlive()) {
|
||||
String recordFilePath = screenRecordThread.stopRecord();
|
||||
if (recordFilePath != null) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("videoInfo", recordFilePath);
|
||||
SessionUtils.sendSuccessData(session, request, result, "结束录屏成功");
|
||||
} else {
|
||||
SessionUtils.sendFailureMessage(session, request, "上传录屏失败");
|
||||
}
|
||||
screenRecordThread = null;
|
||||
} else {
|
||||
SessionUtils.sendFailureMessage(session, request, "未找到开启录屏信息");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startRecordScreen(CmdRequest request) {
|
||||
Map<String, Object> data = request.getData();
|
||||
ParamCheck tenantIdCheck = ParamCheck.build().name("tenantId").type("string").length(32);
|
||||
Map<String, Object> params = null;
|
||||
try {
|
||||
params = checkParam(data, false, tenantIdCheck);
|
||||
} catch (Exception e) {
|
||||
logger.error("参数校验失败!", e);
|
||||
if (e instanceof ParamMistakeException) {
|
||||
SessionUtils.sendFailureMessage(session, request, e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (null == screenRecordThread || screenRecordThread.isInterrupted() || !screenRecordThread.isAlive()) {
|
||||
screenRecordThread = new AndroidScreenRecordThread(adbDevice.getSerial(), (String) params.get("tenantId"), catchParam.getRealWidth(), catchParam.getRealHeight());
|
||||
screenRecordThread.start();
|
||||
} else {
|
||||
logger.info("设备【{}】正在录屏。。。。。",serial);
|
||||
}
|
||||
SessionUtils.sendSuccessData(session, request, null, "开启录屏成功");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void changeScreenQuality(CmdRequest request) {
|
||||
|
@ -1232,6 +1194,7 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
int frameRateUse = (int) params.get("framerate");
|
||||
catchParam.setFrameRate(frameRateUse);
|
||||
logger.debug("改变屏幕质量=====>width:{} height:{} quality:{} frameRate:{}", catchParam.getWidth(), catchParam.getHeight(), qualityUse, frameRateUse);
|
||||
AndroidScreenResponseThread responseThread = AndroidDeviceManager.getInstance().getScreenThread(adbDevice.getSerial());
|
||||
if (null != responseThread) { //图片流
|
||||
ScreenStreamCommand screenStreamCommand = new ScreenStreamCommand(true, 0, catchParam.getWidth(), catchParam.getHeight(), frameRateUse, qualityUse);
|
||||
asyncSendCommand(screenStreamCommand);
|
||||
|
@ -1264,6 +1227,7 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
int heightUse = (int) params.get("height");
|
||||
catchParam.setHeight(heightUse);
|
||||
logger.debug("改变宽高屏幕=====>width:{} height:{} quality:{} frameRate:{}", widthUse, heightUse, catchParam.getQuality(), catchParam.getFrameRate());
|
||||
AndroidScreenResponseThread responseThread = AndroidDeviceManager.getInstance().getScreenThread(adbDevice.getSerial());
|
||||
if (null != responseThread) { //图片流
|
||||
ScreenStreamCommand screenStreamCommand = new ScreenStreamCommand(true, 0, widthUse, heightUse, catchParam.getFrameRate(), catchParam.getQuality());
|
||||
asyncSendCommand(screenStreamCommand);
|
||||
|
@ -1313,19 +1277,20 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
catchParam.setRotation(rotationUse);
|
||||
if ("image".equals(type)) {
|
||||
logger.debug("接收到开启屏幕指令=====>width:{} height:{} quality:{} frameRate:{},rotation:{}", widthUse, heightUse, qualityUse, frameRateUse, rotationUse);
|
||||
responseThread = AndroidDeviceManager.getInstance().getScreenThread(adbDevice.getSerial());
|
||||
AndroidScreenResponseThread responseThread = AndroidDeviceManager.getInstance().getScreenThread(adbDevice.getSerial());
|
||||
if (null == responseThread || responseThread.isInterrupted() || !responseThread.isAlive()) {
|
||||
//之前未开启过设备屏幕获取线程则新建
|
||||
logger.debug("设备【{}】新建屏幕获取线程------",serial);
|
||||
responseThread = new AndroidScreenResponseThread(session, adbDevice, catchParam);
|
||||
responseThread.setScreenOnRequest(request);
|
||||
responseThread = new AndroidScreenResponseThread(adbDevice);
|
||||
responseThread.startSendScreenToWeb(session,catchParam);
|
||||
responseThread.setScreenOnRequest(session,request);
|
||||
responseThread.start();
|
||||
AndroidDeviceManager.getInstance().saveDeviceScreenThread(adbDevice.getSerial(), responseThread);
|
||||
} else {
|
||||
//之前开启过则复用原屏幕获取线程
|
||||
logger.debug("设备【{}】复用原屏幕获取线程=====",serial);
|
||||
responseThread.setScreenOnRequest(request);
|
||||
responseThread.startSendScreenToWeb(session,catchParam);
|
||||
responseThread.setScreenOnRequest(session,request);
|
||||
}
|
||||
} else if ("video".equals(type)) {
|
||||
//视频流专属的参数
|
||||
|
@ -1413,9 +1378,7 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
|
||||
@Override
|
||||
public void stopAndExit() {
|
||||
if (null != responseThread) {
|
||||
responseThread.stopSendPic2Web();
|
||||
}
|
||||
AndroidDeviceManager.getInstance().stopWebScreen(adbDevice.getSerial(),session);
|
||||
if (null != videoScreenResponseThread) {
|
||||
videoScreenResponseThread.stopAndExit();
|
||||
}
|
||||
|
@ -1425,9 +1388,6 @@ public class AndroidMessageHandlerThread extends AbstractMessageHandler {
|
|||
if (null != syncAgentSession) {
|
||||
syncAgentSession.closeSilence();
|
||||
}
|
||||
if (null != screenRecordThread) {
|
||||
screenRecordThread.stopRecord();
|
||||
}
|
||||
if (null != androidPerfThread) {
|
||||
androidPerfThread.stopThread();
|
||||
}
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
package net.northking.cctp.upperComputer.webSocket.thread;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import net.northking.cctp.upperComputer.deviceManager.UpperComputerManager;
|
||||
import net.northking.cctp.upperComputer.enums.FileBusinessTypeEnum;
|
||||
import net.northking.cctp.upperComputer.entity.Attachment;
|
||||
import net.northking.cctp.upperComputer.utils.HttpUtils;
|
||||
import net.northking.cctp.upperComputer.utils.ProcessCmdUtils;
|
||||
import net.northking.cctp.upperComputer.utils.SpringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 录屏线程
|
||||
*/
|
||||
public class AndroidScreenRecordThread extends Thread{
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(AndroidScreenRecordThread.class);
|
||||
|
||||
private String serial;
|
||||
|
||||
private Process process;
|
||||
|
||||
private String recordFileName;
|
||||
|
||||
private String tenantId;
|
||||
|
||||
private int videoWidth;
|
||||
|
||||
private int videoHeight;
|
||||
|
||||
public AndroidScreenRecordThread(String serial,String tenantId,int width,int height){
|
||||
this.serial = serial;
|
||||
this.tenantId = tenantId;
|
||||
this.videoWidth = width;
|
||||
this.videoHeight = height;
|
||||
setName("[" + serial+"]-record");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String applicationPath = UpperComputerManager.getInstance().getApplicationPath();
|
||||
applicationPath = applicationPath.replace("\\","/");
|
||||
File screenRecordPath = new File(applicationPath + "/screenRecordTmp/");
|
||||
if (!screenRecordPath.exists()) {
|
||||
screenRecordPath.mkdirs();
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
|
||||
String dateFormat = format.format(new Date());
|
||||
String tmpPath = screenRecordPath.getAbsolutePath();
|
||||
tmpPath = tmpPath.replace("\\","/");
|
||||
recordFileName = tmpPath + "/" + serial + "_" + dateFormat + ".mp4";
|
||||
List<String> cmdList = new ArrayList<>();
|
||||
cmdList.add("scrcpy");
|
||||
cmdList.add("-s");
|
||||
cmdList.add(serial);
|
||||
cmdList.add("-b");
|
||||
cmdList.add("2M");
|
||||
cmdList.add("-Nr");
|
||||
cmdList.add(recordFileName);
|
||||
logger.info("[" +serial+ "]录屏开启,时间:{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
process = ProcessCmdUtils.execCmd(cmdList);
|
||||
InputStreamReader ir = null;
|
||||
LineNumberReader input = null;
|
||||
try {
|
||||
ir = new InputStreamReader(process.getInputStream(),"UTF-8");
|
||||
input = new LineNumberReader(ir);
|
||||
String line;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while ((line = input.readLine()) != null) {
|
||||
logger.debug(line);
|
||||
sb.append(line);
|
||||
}
|
||||
input.close();
|
||||
} catch (Exception e) {
|
||||
logger.warn("读取录屏输出失败",e);
|
||||
}
|
||||
logger.info("[" +serial+ "]录屏结束,时间:{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
}
|
||||
|
||||
public String stopRecord(){
|
||||
if (null != process) {
|
||||
process.destroy();
|
||||
logger.debug("录屏进程是否存活:{}",process.isAlive());
|
||||
//上传文件
|
||||
logger.debug("[" +serial+ "]录屏停止,开始上传视屏文件");
|
||||
String serverAddress = SpringUtils.getProperties("nk.mobile-computer.serverAddr");
|
||||
String pubUploadPath = SpringUtils.getProperties("nk.mobile-computer.publicUploadAddr");
|
||||
try {
|
||||
if (StringUtils.isNotBlank(recordFileName)) {
|
||||
File file = new File(recordFileName);
|
||||
//文件存在才上传
|
||||
if (null != file && file.exists()) {
|
||||
logger.info("开始上传安卓视频文件,设备Id:{}", serial);
|
||||
Attachment upload = HttpUtils.upload(serverAddress + pubUploadPath, recordFileName, tenantId, null, FileBusinessTypeEnum.MOBILE_TASK_VIDEO.getCode());
|
||||
if (null != upload && StringUtils.isNotBlank(upload.getId())) {
|
||||
logger.debug("文件上传成功,返回id:{}", upload.getId());
|
||||
Map<String, String> resultMap = new HashMap<>();
|
||||
resultMap.put("videoUrl", upload.getUrlPath());
|
||||
resultMap.put("videoRef", videoWidth + "x" + videoHeight);
|
||||
return JSON.toJSONString(resultMap);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
logger.warn("[" +serial+ "]录屏文件路径为空");
|
||||
}
|
||||
}catch (Exception e) {
|
||||
logger.error("上传录像文件异常,",e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void killRecord(){
|
||||
if (null != process) {
|
||||
process.destroy();
|
||||
logger.debug("原录屏进程是否存活:",process.isAlive());
|
||||
File file = new File(recordFileName);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package net.northking.cctp.upperComputer.webSocket.thread;
|
|||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import net.northking.cctp.upperComputer.constants.HandCommand;
|
||||
import net.northking.cctp.upperComputer.constants.IosInputKeyBoardEnum;
|
||||
import net.northking.cctp.upperComputer.constants.KeyBoardCodeEnum;
|
||||
import net.northking.cctp.upperComputer.deviceManager.IOSDeviceManager;
|
||||
|
@ -10,13 +9,8 @@ import net.northking.cctp.upperComputer.deviceManager.UpperComputerManager;
|
|||
import net.northking.cctp.upperComputer.deviceManager.common.PyMobileDevice;
|
||||
import net.northking.cctp.upperComputer.deviceManager.thread.IosDeviceInitThread;
|
||||
import net.northking.cctp.upperComputer.driver.ios.NKAgent;
|
||||
import net.northking.cctp.upperComputer.driver.ios.command.data.DragXYData;
|
||||
import net.northking.cctp.upperComputer.driver.ios.command.data.ForceTapXYData;
|
||||
import net.northking.cctp.upperComputer.driver.ios.command.data.TypeKeysUiNodeData;
|
||||
import net.northking.cctp.upperComputer.driver.ios.packet.EmptyCommandData;
|
||||
import net.northking.cctp.upperComputer.entity.Attachment;
|
||||
import net.northking.cctp.upperComputer.entity.PhoneEntity;
|
||||
import net.northking.cctp.upperComputer.enums.FileBusinessTypeEnum;
|
||||
import net.northking.cctp.upperComputer.exception.ExecuteException;
|
||||
import net.northking.cctp.upperComputer.exception.ParamMistakeException;
|
||||
import net.northking.cctp.upperComputer.utils.HttpUtils;
|
||||
|
@ -41,6 +35,7 @@ public class IosMacMessageHandlerThread extends AbstractIosMessageHandlerThread
|
|||
|
||||
private final Logger logger = LoggerFactory.getLogger(IosMacMessageHandlerThread.class);
|
||||
|
||||
|
||||
public IosMacMessageHandlerThread(PhoneEntity phoneEntity, Session session) throws ParamMistakeException {
|
||||
super(phoneEntity, session);
|
||||
}
|
||||
|
@ -689,7 +684,7 @@ public class IosMacMessageHandlerThread extends AbstractIosMessageHandlerThread
|
|||
String pubUploadPath = SpringUtils.getProperties("nk.mobile-computer.publicUploadAddr");
|
||||
Attachment upload = null;
|
||||
try {
|
||||
upload = HttpUtils.upload(serverAddress + pubUploadPath, screenShotData, tenantId, null, FileBusinessTypeEnum.MOBILE_RECORD_SCREENSHOT.getCode());
|
||||
upload = HttpUtils.upload(serverAddress + pubUploadPath, screenShotData, tenantId);
|
||||
} catch (Exception e) {
|
||||
logger.debug("[{}]上传截图失败", phoneEntity.getUdid(), e);
|
||||
}
|
||||
|
@ -712,9 +707,7 @@ public class IosMacMessageHandlerThread extends AbstractIosMessageHandlerThread
|
|||
|
||||
@Override
|
||||
public void stopAndExit() {
|
||||
if (null != screenResponseThread) {
|
||||
screenResponseThread.stopFetchPic();
|
||||
}
|
||||
IOSDeviceManager.getInstance().stopWebScreen(phoneEntity.getUdid(),session);
|
||||
if (null != iosPerfThread) {
|
||||
iosPerfThread.stopThread();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import net.northking.cctp.upperComputer.deviceManager.thread.IosDeviceInitThread
|
|||
import net.northking.cctp.upperComputer.driver.ios.NKAgent;
|
||||
import net.northking.cctp.upperComputer.entity.Attachment;
|
||||
import net.northking.cctp.upperComputer.entity.PhoneEntity;
|
||||
import net.northking.cctp.upperComputer.enums.FileBusinessTypeEnum;
|
||||
import net.northking.cctp.upperComputer.exception.ExecuteException;
|
||||
import net.northking.cctp.upperComputer.exception.ParamMistakeException;
|
||||
import net.northking.cctp.upperComputer.utils.HttpUtils;
|
||||
|
@ -20,7 +19,6 @@ import net.northking.cctp.upperComputer.utils.SpringUtils;
|
|||
import net.northking.cctp.upperComputer.webSocket.entity.CmdRequest;
|
||||
import net.northking.cctp.upperComputer.webSocket.entity.ParamCheck;
|
||||
import net.northking.cctp.upperComputer.webSocket.entity.Point;
|
||||
import net.northking.cctp.upperComputer.webSocket.function.IosFunction;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -112,7 +110,6 @@ public class IosWindowsAndLinuxMessageHandlerThread extends AbstractIosMessageHa
|
|||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void stopLogcat(CmdRequest request) {
|
||||
Map<String, Object> data = request.getData();
|
||||
|
@ -648,9 +645,7 @@ public class IosWindowsAndLinuxMessageHandlerThread extends AbstractIosMessageHa
|
|||
function.swipe(startX, startY, endX, endY);
|
||||
} else { //点击
|
||||
if (time < 2000) {//点击
|
||||
logger.debug("设备【{}】准备请求点击坐标x:{},y:{}",phoneEntity.getUdid(),startX,startY);
|
||||
function.click(startX, startY);
|
||||
logger.debug("设备【{}】点击完成",phoneEntity.getUdid(),startX,startY);
|
||||
} else { //长按
|
||||
function.longPress(startX, startY);
|
||||
}
|
||||
|
@ -718,7 +713,7 @@ public class IosWindowsAndLinuxMessageHandlerThread extends AbstractIosMessageHa
|
|||
String pubUploadPath = SpringUtils.getProperties("nk.mobile-computer.publicUploadAddr");
|
||||
Attachment upload = null;
|
||||
try {
|
||||
upload = HttpUtils.upload(serverAddress + pubUploadPath, screenShotData, tenantId, null, FileBusinessTypeEnum.MOBILE_TASK_SCREENSHOT.getCode());
|
||||
upload = HttpUtils.upload(serverAddress + pubUploadPath, screenShotData, tenantId);
|
||||
} catch (Exception e) {
|
||||
logger.debug("[{}]上传截图失败", phoneEntity.getUdid(), e);
|
||||
}
|
||||
|
@ -740,9 +735,7 @@ public class IosWindowsAndLinuxMessageHandlerThread extends AbstractIosMessageHa
|
|||
|
||||
@Override
|
||||
public void stopAndExit() {
|
||||
if (null != screenResponseThread) {
|
||||
screenResponseThread.stopFetchPic();
|
||||
}
|
||||
IOSDeviceManager.getInstance().stopWebScreen(phoneEntity.getUdid(),session);
|
||||
if (null != iosPerfThread) {
|
||||
iosPerfThread.stopThread();
|
||||
}
|
||||
|
|
|
@ -23,10 +23,6 @@ public interface MessageHandler {
|
|||
|
||||
public void changeScreenQuality(CmdRequest request);
|
||||
|
||||
public void startRecordScreen(CmdRequest request);
|
||||
|
||||
public void stopRecordScreen(CmdRequest request);
|
||||
|
||||
public void screenShot(CmdRequest request);
|
||||
|
||||
public void touchDown(CmdRequest request);
|
||||
|
|
Loading…
Reference in New Issue