Merge branch 'main' of https://git.zhaozuohong.vip/mower-ng/mower-ng
This commit is contained in:
commit
20e8a59b62
9 changed files with 146 additions and 67 deletions
|
@ -346,6 +346,12 @@ class EmulatorPart(ConfModel):
|
|||
rotate: bool = False
|
||||
"将截图旋转180度"
|
||||
|
||||
class DroidCastRawConf(ConfModel):
|
||||
orientation: Literal["portrait", "landscape"] = "landscape"
|
||||
"屏幕方向"
|
||||
rotate: Literal[0, 90, 180, 270] = 0
|
||||
"截图旋转角度"
|
||||
|
||||
adb: str = "127.0.0.1:16384"
|
||||
"ADB连接地址"
|
||||
emulator: EmulatorConf
|
||||
|
@ -356,6 +362,8 @@ class EmulatorPart(ConfModel):
|
|||
"游戏服务器"
|
||||
droidcast: DroidCastConf
|
||||
"DroidCast截图设置"
|
||||
droidcast_raw: DroidCastRawConf
|
||||
"DroidCast截图设置"
|
||||
custom_screenshot: CustomScreenshotConf
|
||||
"自定义截图"
|
||||
tap_to_launch_game: TapToLaunchGameConf
|
||||
|
@ -369,10 +377,11 @@ class EmulatorPart(ConfModel):
|
|||
screencap_strategy: Literal[
|
||||
"adb",
|
||||
"droidcast",
|
||||
"droidcast_raw",
|
||||
"mumuipc",
|
||||
"diy",
|
||||
"scrcpy",
|
||||
] = "droidcast"
|
||||
] = "droidcast_raw"
|
||||
"截图方案"
|
||||
control_strategy: Literal["scrcpy", "mumuipc"] = "scrcpy"
|
||||
"触控方案"
|
||||
|
|
|
@ -12,6 +12,7 @@ from mower.utils.log import logger, save_screenshot
|
|||
method_map = {
|
||||
"adb": "mower.utils.device.method.adb.ADB",
|
||||
"droidcast": "mower.utils.device.method.droidcast.DroidCast",
|
||||
"droidcast_raw": "mower.utils.device.method.droidcast.DroidCast_raw",
|
||||
"scrcpy": "mower.utils.device.method.scrcpy.Scrcpy",
|
||||
"mumuipc": "mower.utils.device.method.mumu_ipc.MuMu12IPC",
|
||||
"diy": "mower.utils.device.method.adb.DIY",
|
||||
|
|
|
@ -285,7 +285,7 @@ class ADB:
|
|||
dpi = (override_dpi or physical_dpi).partition("density:")[2].strip()
|
||||
if (
|
||||
config.conf.emulator.name == "MuMu12"
|
||||
and config.conf.screencap_strategy == "droidcast"
|
||||
and config.conf.screencap_strategy.startswith("droidcast")
|
||||
):
|
||||
from mower.utils.device.method.mumumanager import MuMuManager
|
||||
|
||||
|
|
|
@ -2,15 +2,16 @@ import time
|
|||
from functools import cached_property, wraps
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
import requests
|
||||
|
||||
from mower import __rootdir__
|
||||
from mower.utils import config
|
||||
from mower.utils.csleep import MowerExit
|
||||
from mower.utils.device.method.adb import ADB
|
||||
from mower.utils.image import bytes2img
|
||||
from mower.utils.log import logger
|
||||
from mower.utils.network import get_new_port, is_port_in_use
|
||||
from mower.utils.path import get_path
|
||||
|
||||
|
||||
def retry_droidcast(func):
|
||||
|
@ -29,6 +30,10 @@ def retry_droidcast(func):
|
|||
|
||||
|
||||
class DroidCast:
|
||||
display_name = "DroidCast"
|
||||
package_name = "com.rayworks.droidcast"
|
||||
apk_file = "DroidCast-debug-1.2.1.apk"
|
||||
|
||||
def __init__(self):
|
||||
self.session = requests.Session()
|
||||
self.port = 0
|
||||
|
@ -40,7 +45,7 @@ class DroidCast:
|
|||
|
||||
def get_droidcast_classpath(self) -> str | None:
|
||||
# TODO: 退出时(并非结束mower线程时)关闭DroidCast进程、取消ADB转发
|
||||
out = self.adb.adb_shell("pm path com.rayworks.droidcast")
|
||||
out = self.adb.adb_shell(f"pm path {self.package_name}")
|
||||
if out is None:
|
||||
logger.exception("无法获取CLASSPATH")
|
||||
return None
|
||||
|
@ -54,15 +59,18 @@ class DroidCast:
|
|||
return class_path
|
||||
|
||||
def start_droidcast(self) -> bool:
|
||||
class_path = self.get_droidcast_classpath()
|
||||
try:
|
||||
class_path = self.get_droidcast_classpath()
|
||||
except Exception:
|
||||
class_path = None
|
||||
if not class_path:
|
||||
logger.info("安装DroidCast")
|
||||
apk_path = f"{__rootdir__}/vendor/DroidCast-debug-1.2.1.apk"
|
||||
logger.info(f"安装{self.display_name}")
|
||||
try:
|
||||
self.adb.adb.install(apk_path)
|
||||
logger.info("DroidCast安装完成,获取CLASSPATH")
|
||||
apk_path = get_path(f"@install/mower/vendor/{self.apk_file}")
|
||||
self.adb.adb.install(str(apk_path))
|
||||
logger.info(f"{self.display_name}安装完成,获取CLASSPATH")
|
||||
except Exception as e:
|
||||
logger.error(f"DroidCast安装失败: {e}")
|
||||
logger.error(f"{self.display_name}安装失败: {e}")
|
||||
return False
|
||||
class_path = self.get_droidcast_classpath()
|
||||
if not class_path:
|
||||
|
@ -83,24 +91,68 @@ class DroidCast:
|
|||
if port == 0:
|
||||
port = get_new_port()
|
||||
self.port = port
|
||||
logger.info(f"更新DroidCast端口为{port}")
|
||||
logger.info(f"更新{self.display_name}端口为{port}")
|
||||
else:
|
||||
logger.info(f"保持DroidCast端口为{port}")
|
||||
logger.info(f"保持{self.display_name}端口为{port}")
|
||||
self.adb.adb.forward(f"tcp:{port}", f"tcp:{port}")
|
||||
logger.info("ADB端口转发成功,启动DroidCast")
|
||||
cmd = f"{class_path} app_process / com.rayworks.droidcast.Main --port={port}"
|
||||
logger.info("ADB端口转发成功,启动{self.display_name}")
|
||||
cmd = f"{class_path} app_process / {self.package_name}.Main --port={port}"
|
||||
self.socket = self.adb.adb_shell(cmd, True)
|
||||
time.sleep(1) # TODO: 更好地等待DroidCast启动
|
||||
return True
|
||||
|
||||
@retry_droidcast
|
||||
def capture_display(self):
|
||||
if self.port == 0:
|
||||
raise Exception("DroidCast未启动")
|
||||
url = f"http://127.0.0.1:{self.port}/screenshot"
|
||||
logger.debug(f"GET {url}")
|
||||
r = self.session.get(url)
|
||||
img = bytes2img(r.content)
|
||||
def decode(self, data):
|
||||
img = bytes2img(data)
|
||||
if config.conf.droidcast.rotate:
|
||||
img = cv2.rotate(img, cv2.ROTATE_180)
|
||||
return img
|
||||
|
||||
@retry_droidcast
|
||||
def capture_display(self):
|
||||
if self.port == 0:
|
||||
raise Exception(f"{self.display_name}未启动")
|
||||
url = f"http://127.0.0.1:{self.port}/screenshot"
|
||||
logger.debug(f"GET {url}")
|
||||
r = self.session.get(url)
|
||||
return self.decode(r.content)
|
||||
|
||||
|
||||
class DroidCast_raw(DroidCast):
|
||||
display_name = "DroidCast_raw"
|
||||
package_name = "ink.mol.droidcast_raw"
|
||||
apk_file = "DroidCast_raw-release-1.1.apk"
|
||||
|
||||
def decode(self, data):
|
||||
# https://github.com/LmeSzinc/StarRailCopilot/blob/bf62eccaaa6f46ea9796a83175df0ab7882dd137/module/device/method/droidcast.py#L226
|
||||
arr = np.frombuffer(data, dtype=np.uint16)
|
||||
if config.conf.droidcast_raw.orientation == "portrait":
|
||||
shape = (1080, 1920)
|
||||
else:
|
||||
shape = (1920, 1080)
|
||||
arr = arr.reshape(shape)
|
||||
|
||||
r = cv2.bitwise_and(arr, 0b1111100000000000)
|
||||
r = cv2.convertScaleAbs(r, alpha=0.00390625)
|
||||
m = cv2.convertScaleAbs(r, alpha=0.03125)
|
||||
cv2.add(r, m, dst=r)
|
||||
|
||||
g = cv2.bitwise_and(arr, 0b0000011111100000)
|
||||
g = cv2.convertScaleAbs(g, alpha=0.125)
|
||||
m = cv2.convertScaleAbs(g, alpha=0.015625, dst=m)
|
||||
cv2.add(g, m, dst=g)
|
||||
|
||||
b = cv2.bitwise_and(arr, 0b0000000000011111)
|
||||
b = cv2.convertScaleAbs(b, alpha=8)
|
||||
m = cv2.convertScaleAbs(b, alpha=0.03125, dst=m)
|
||||
cv2.add(b, m, dst=b)
|
||||
|
||||
img = cv2.merge([r, g, b])
|
||||
|
||||
if config.conf.droidcast_raw.rotate == 90:
|
||||
img = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
|
||||
elif config.conf.droidcast_raw.rotate == 180:
|
||||
img = cv2.rotate(img, cv2.ROTATE_180)
|
||||
elif config.conf.droidcast_raw.rotate == 270:
|
||||
img = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
||||
|
||||
return img
|
||||
|
|
|
@ -145,7 +145,10 @@ class MuMuManager:
|
|||
width = int(float(self.get_field_value(data, "resolution_width.custom")))
|
||||
height = int(float(self.get_field_value(data, "resolution_height.custom")))
|
||||
dpi = int(float(self.get_field_value(data, "resolution_dpi.custom")))
|
||||
if config.conf.screencap_strategy == "droidcast" and self.app_kept_alive():
|
||||
if (
|
||||
config.conf.screencap_strategy.startswith("droidcast")
|
||||
and self.app_kept_alive()
|
||||
):
|
||||
logger.error("MuMu12的droidcast截图策略下,需要关闭应用后台保活")
|
||||
try:
|
||||
self.set_app_kept_alive_false()
|
||||
|
|
BIN
mower/vendor/DroidCast_raw-release-1.1.apk
vendored
Normal file
BIN
mower/vendor/DroidCast_raw-release-1.1.apk
vendored
Normal file
Binary file not shown.
2
ui/dist/assets/Settings.css
vendored
2
ui/dist/assets/Settings.css
vendored
|
@ -1 +1 @@
|
|||
.sss-container[data-v-2dffb781]{display:flex;width:100%;gap:8px}.wrapper[data-v-2dffb781]{white-space:pre-wrap;-webkit-user-select:text;user-select:text}.title[data-v-2dffb781]{font-size:18px;font-weight:500;margin-bottom:6px}p[data-v-d479d5bf]{margin:0 0 10px}.misc-container[data-v-d479d5bf]{display:flex;align-items:center;gap:12px}.header[data-v-d479d5bf]{margin:12px 0}.tasktable[data-v-6e42e723]{margin-top:4px;width:100%;overflow:scroll}.tasktable table[data-v-6e42e723]{border-collapse:collapse;width:100%}.btn-clear[data-v-6e42e723]{margin:4px}@media screen and (max-width: 1399px){.tasktable[data-v-6e42e723]{max-height:300px}.tasktable td[data-v-6e42e723]{width:10.2857142857%}.tasktable td[data-v-6e42e723]:first-child{width:10%}.tasktable td[data-v-6e42e723]:nth-child(2){width:18%}.tasktable thead[data-v-6e42e723]{position:sticky;top:0;background-color:#7ea5b4;z-index:1}}@media screen and (min-width: 1400px){.tasktable td[data-v-6e42e723]{width:10.2857142857%}.tasktable td[data-v-6e42e723]:first-child{width:10%}.tasktable td[data-v-6e42e723]:nth-child(2){width:18%}.tasktable thead[data-v-6e42e723]{background-color:#7ea5b4}}.class1[data-v-6e42e723]{background-color:var(--06f96d6a);text-align:center;vertical-align:middle}.class2[data-v-6e42e723]{background-color:var(--292d8683);text-align:center;vertical-align:middle}.custom-tag[data-v-6e42e723]{width:100%;height:100%;justify-content:space-between}.today[data-v-6e42e723]{font-weight:400;font-size:12px}.activity[data-v-6e42e723]{align-items:center;gap:4px!important}.card-title[data-v-6e42e723]{transition:.3s}.disabled[data-v-6e42e723]{color:var(--6d545694)}.form-item[data-v-6e42e723]{margin:0 0 4px}p[data-v-748f667d]{margin:2px 0}h4[data-v-748f667d]{margin:12px 0 8px}table[data-v-748f667d]{width:100%}td[data-v-748f667d]:nth-child(1){width:80px}.ignore-blacklist[data-v-748f667d]{margin-bottom:10px;display:flex;gap:12px}.h4[data-v-748f667d]{font-size:16px;font-weight:500}.maa-shop[data-v-748f667d]{margin:8px 0}.item[data-v-748f667d]{font-weight:500;font-size:16px}p[data-v-707c6f48]{margin:0 0 8px}h4[data-v-707c6f48]{margin:12px 0 10px}.big-table[data-v-707c6f48]{margin-top:10px;max-width:320px}.big-table th[data-v-707c6f48]{text-align:center}.big-table tr[data-v-707c6f48]{width:70px}.big-table td[data-v-707c6f48]{height:24px}.big-table td[data-v-707c6f48]:nth-child(1){width:70px;text-align:center}.big-table td[data-v-707c6f48]:nth-child(2){width:420px}.final[data-v-707c6f48]{margin:16px 0 0}.item[data-v-e95953da]{font-weight:500;font-size:16px}.n-divider[data-v-e95953da]:not(.n-divider--vertical){margin:6px 0}.subtitle[data-v-31c5d919]{margin:12px 0 6px}.misc-container{margin-top:12px;display:flex;align-items:center;gap:12px}.email-title[data-v-7cbc22ce]{width:100%}.expand[data-v-7cbc22ce]{flex-grow:1}.email-table[data-v-7cbc22ce]{width:100%;margin-bottom:12px}.email-test[data-v-7cbc22ce]{display:flex;align-items:center;gap:16px}.email-mode[data-v-7cbc22ce]{margin-left:20px}.email-label[data-v-7cbc22ce]{width:68px}p[data-v-7cbc22ce]{margin:0 0 10px}.mt-16[data-v-7cbc22ce]{margin-top:16px}.threshold[data-v-43df5096]{display:flex;align-items:center;gap:14px;width:100%}.mower-basic[data-v-43df5096]{width:100%}.mower-basic td[data-v-43df5096]:nth-child(1){width:120px}.mower-basic td[data-v-43df5096]:nth-child(3){padding-left:6px;width:40px}.riic-conf[data-v-43df5096]{width:100%}.riic-conf td[data-v-43df5096]:nth-child(1){width:130px}.riic-conf td[data-v-43df5096]:nth-child(3){padding-left:12px;width:120px}.coord td[data-v-43df5096]{width:120px}.coord td[data-v-43df5096]:nth-child(1),.coord td[data-v-43df5096]:nth-child(3){width:30px}.coord td[data-v-43df5096]:nth-child(2){padding-right:30px}.coord-label[data-v-43df5096]{width:40px;padding-left:8px}p[data-v-43df5096]{margin:0 0 8px}h4[data-v-43df5096]{margin:12px 0 10px}.time-table[data-v-43df5096]{width:100%;margin-bottom:12px}.time-table td[data-v-43df5096]:nth-child(1){width:40px}.scale[data-v-43df5096]{width:60px;text-align:right}.scale-apply[data-v-43df5096]{margin-left:24px}.waiting-table th[data-v-43df5096],.waiting-table td[data-v-43df5096]{padding:4px;min-width:70px;width:100px}.waiting-table th[data-v-43df5096]:first-child,.waiting-table td[data-v-43df5096]:first-child{width:auto;padding:4px 8px}@media (max-width: 1399px){.grid-two{margin:0 0 -10px;width:100%;max-width:600px}.grid-left{display:grid;row-gap:10px;grid-template-columns:100%}.grid-right{display:grid;row-gap:10px;grid-template-columns:100%;margin-top:10px}}@media (min-width: 1400px){.grid-two{display:grid;grid-template-columns:minmax(0px,1fr) minmax(0px,1fr);align-items:flex-start;gap:5px}.grid-left,.grid-right{display:grid;gap:5px;grid-template-columns:100%;max-width:600px}}.n-divider:not(.n-divider--vertical){margin:14px 0 8px}
|
||||
.sss-container[data-v-2dffb781]{display:flex;width:100%;gap:8px}.wrapper[data-v-2dffb781]{white-space:pre-wrap;-webkit-user-select:text;user-select:text}.title[data-v-2dffb781]{font-size:18px;font-weight:500;margin-bottom:6px}p[data-v-d479d5bf]{margin:0 0 10px}.misc-container[data-v-d479d5bf]{display:flex;align-items:center;gap:12px}.header[data-v-d479d5bf]{margin:12px 0}.tasktable[data-v-6e42e723]{margin-top:4px;width:100%;overflow:scroll}.tasktable table[data-v-6e42e723]{border-collapse:collapse;width:100%}.btn-clear[data-v-6e42e723]{margin:4px}@media screen and (max-width: 1399px){.tasktable[data-v-6e42e723]{max-height:300px}.tasktable td[data-v-6e42e723]{width:10.2857142857%}.tasktable td[data-v-6e42e723]:first-child{width:10%}.tasktable td[data-v-6e42e723]:nth-child(2){width:18%}.tasktable thead[data-v-6e42e723]{position:sticky;top:0;background-color:#7ea5b4;z-index:1}}@media screen and (min-width: 1400px){.tasktable td[data-v-6e42e723]{width:10.2857142857%}.tasktable td[data-v-6e42e723]:first-child{width:10%}.tasktable td[data-v-6e42e723]:nth-child(2){width:18%}.tasktable thead[data-v-6e42e723]{background-color:#7ea5b4}}.class1[data-v-6e42e723]{background-color:var(--06f96d6a);text-align:center;vertical-align:middle}.class2[data-v-6e42e723]{background-color:var(--292d8683);text-align:center;vertical-align:middle}.custom-tag[data-v-6e42e723]{width:100%;height:100%;justify-content:space-between}.today[data-v-6e42e723]{font-weight:400;font-size:12px}.activity[data-v-6e42e723]{align-items:center;gap:4px!important}.card-title[data-v-6e42e723]{transition:.3s}.disabled[data-v-6e42e723]{color:var(--6d545694)}.form-item[data-v-6e42e723]{margin:0 0 4px}p[data-v-748f667d]{margin:2px 0}h4[data-v-748f667d]{margin:12px 0 8px}table[data-v-748f667d]{width:100%}td[data-v-748f667d]:nth-child(1){width:80px}.ignore-blacklist[data-v-748f667d]{margin-bottom:10px;display:flex;gap:12px}.h4[data-v-748f667d]{font-size:16px;font-weight:500}.maa-shop[data-v-748f667d]{margin:8px 0}.item[data-v-748f667d]{font-weight:500;font-size:16px}p[data-v-707c6f48]{margin:0 0 8px}h4[data-v-707c6f48]{margin:12px 0 10px}.big-table[data-v-707c6f48]{margin-top:10px;max-width:320px}.big-table th[data-v-707c6f48]{text-align:center}.big-table tr[data-v-707c6f48]{width:70px}.big-table td[data-v-707c6f48]{height:24px}.big-table td[data-v-707c6f48]:nth-child(1){width:70px;text-align:center}.big-table td[data-v-707c6f48]:nth-child(2){width:420px}.final[data-v-707c6f48]{margin:16px 0 0}.item[data-v-e95953da]{font-weight:500;font-size:16px}.n-divider[data-v-e95953da]:not(.n-divider--vertical){margin:6px 0}.subtitle[data-v-31c5d919]{margin:12px 0 6px}.misc-container{margin-top:12px;display:flex;align-items:center;gap:12px}.email-title[data-v-7cbc22ce]{width:100%}.expand[data-v-7cbc22ce]{flex-grow:1}.email-table[data-v-7cbc22ce]{width:100%;margin-bottom:12px}.email-test[data-v-7cbc22ce]{display:flex;align-items:center;gap:16px}.email-mode[data-v-7cbc22ce]{margin-left:20px}.email-label[data-v-7cbc22ce]{width:68px}p[data-v-7cbc22ce]{margin:0 0 10px}.mt-16[data-v-7cbc22ce]{margin-top:16px}.threshold[data-v-58034e1c]{display:flex;align-items:center;gap:14px;width:100%}.mower-basic[data-v-58034e1c]{width:100%}.mower-basic td[data-v-58034e1c]:nth-child(1){width:120px}.mower-basic td[data-v-58034e1c]:nth-child(3){padding-left:6px;width:40px}.riic-conf[data-v-58034e1c]{width:100%}.riic-conf td[data-v-58034e1c]:nth-child(1){width:130px}.riic-conf td[data-v-58034e1c]:nth-child(3){padding-left:12px;width:120px}.coord td[data-v-58034e1c]{width:120px}.coord td[data-v-58034e1c]:nth-child(1),.coord td[data-v-58034e1c]:nth-child(3){width:30px}.coord td[data-v-58034e1c]:nth-child(2){padding-right:30px}.coord-label[data-v-58034e1c]{width:40px;padding-left:8px}p[data-v-58034e1c]{margin:0 0 8px}h4[data-v-58034e1c]{margin:12px 0 10px}.time-table[data-v-58034e1c]{width:100%;margin-bottom:12px}.time-table td[data-v-58034e1c]:nth-child(1){width:40px}.scale[data-v-58034e1c]{width:60px;text-align:right}.scale-apply[data-v-58034e1c]{margin-left:24px}.waiting-table th[data-v-58034e1c],.waiting-table td[data-v-58034e1c]{padding:4px;min-width:70px;width:100px}.waiting-table th[data-v-58034e1c]:first-child,.waiting-table td[data-v-58034e1c]:first-child{width:auto;padding:4px 8px}@media (max-width: 1399px){.grid-two{margin:0 0 -10px;width:100%;max-width:600px}.grid-left{display:grid;row-gap:10px;grid-template-columns:100%}.grid-right{display:grid;row-gap:10px;grid-template-columns:100%;margin-top:10px}}@media (min-width: 1400px){.grid-two{display:grid;grid-template-columns:minmax(0px,1fr) minmax(0px,1fr);align-items:flex-start;gap:5px}.grid-left,.grid-right{display:grid;gap:5px;grid-template-columns:100%;max-width:600px}}.n-divider:not(.n-divider--vertical){margin:14px 0 8px}
|
||||
|
|
58
ui/dist/assets/Settings.js
vendored
58
ui/dist/assets/Settings.js
vendored
File diff suppressed because one or more lines are too long
|
@ -70,9 +70,10 @@ async function select_maa_adb_path() {
|
|||
|
||||
const screencap_options = computed(() => {
|
||||
const result = [
|
||||
{ label: 'ADB+Gzip(主动截图,无损压缩,兼容性好,速度慢)', value: 'adb' },
|
||||
{ label: 'DroidCast(主动截图,有损压缩,速度较快)', value: 'droidcast' },
|
||||
{ label: 'scrcpy(被动截图,有损压缩,视频流,特殊)', value: 'scrcpy' },
|
||||
{ label: 'DroidCast_raw(主动,无损,较快)', value: 'droidcast_raw' },
|
||||
{ label: 'ADB+Gzip(主动,无损,很慢)', value: 'adb' },
|
||||
{ label: 'DroidCast(主动,有损,较快)', value: 'droidcast' },
|
||||
{ label: 'scrcpy(被动,有损,特殊)', value: 'scrcpy' },
|
||||
{ label: '自定义(以下命令需要向STDOUT打印截图文件)', value: 'diy' }
|
||||
]
|
||||
if (conf.value.emulator.name == 'MuMu12') {
|
||||
|
@ -275,15 +276,6 @@ const message = useMessage()
|
|||
>
|
||||
通过共享内存的方式直接获取无损截图,避免了编码、解码、跨进程传输等环节的开销,截图速度远高于通用截图方案。
|
||||
</n-alert>
|
||||
<n-alert
|
||||
title="请关闭MuMu模拟器12的后台保活"
|
||||
closable
|
||||
style="margin: 8px 0"
|
||||
type="warning"
|
||||
v-if="conf.emulator.name == 'MuMu12' && conf.screencap_strategy == 'droidcast'"
|
||||
>
|
||||
在MuMu模拟器12上使用DroidCast截图方式,需关闭后台保活,或换用ADB+Gzip截图方式。
|
||||
</n-alert>
|
||||
<n-form-item label="触控方案">
|
||||
<n-select v-model:value="conf.control_strategy" :options="touch_options" />
|
||||
</n-form-item>
|
||||
|
@ -298,6 +290,26 @@ const message = useMessage()
|
|||
</n-flex>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<template v-if="conf.screencap_strategy == 'droidcast_raw'">
|
||||
<n-form-item label="屏幕朝向">
|
||||
<n-radio-group v-model:value="conf.droidcast_raw.orientation">
|
||||
<n-flex>
|
||||
<n-radio value="portrait">竖屏</n-radio>
|
||||
<n-radio value="landscape">横屏</n-radio>
|
||||
</n-flex>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item label="旋转截图" v-if="conf.screencap_strategy == 'droidcast_raw'">
|
||||
<n-radio-group v-model:value="conf.droidcast_raw.rotate">
|
||||
<n-flex>
|
||||
<n-radio :value="0">不旋转</n-radio>
|
||||
<n-radio :value="90">旋转90度</n-radio>
|
||||
<n-radio :value="180">旋转180度</n-radio>
|
||||
<n-radio :value="270">旋转270度</n-radio>
|
||||
</n-flex>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
</template>
|
||||
<n-form-item label="截图命令" v-if="conf.screencap_strategy == 'diy'">
|
||||
<n-input
|
||||
v-model:value="conf.custom_screenshot.command"
|
||||
|
@ -313,8 +325,10 @@ const message = useMessage()
|
|||
<div v-if="screenshot_success">
|
||||
截图用时:<n-text strong :type="screenshot_type">{{ elapsed }}ms</n-text>
|
||||
</div>
|
||||
<n-text type="error" v-else>截图失败!</n-text>
|
||||
<div>{{ reason }}</div>
|
||||
<template v-else>
|
||||
<n-text type="error">截图失败!</n-text>
|
||||
<div>{{ reason }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</n-flex>
|
||||
<n-image
|
||||
|
|
Loading…
Add table
Reference in a new issue