refactor: save screenshot in async

This commit is contained in:
lilong.129
2025-03-05 16:29:36 +08:00
parent 98d1ecb478
commit e187ba824a
7 changed files with 49 additions and 90 deletions
+1 -1
View File
@@ -1 +1 @@
v5.0.0+2503051452 v5.0.0+2503051629
-12
View File
@@ -544,18 +544,6 @@ func (ad *ADBDriver) ScreenShot(opts ...option.ActionOption) (raw *bytes.Buffer,
"adb screencap failed %v", err) "adb screencap failed %v", err)
} }
raw = bytes.NewBuffer(resp) raw = bytes.NewBuffer(resp)
actionOptions := option.NewActionOptions(opts...)
if actionOptions.ScreenShotFileName != "" {
// save screenshot to file
path, err := saveScreenShot(raw, actionOptions.ScreenShotFileName)
if err != nil {
return nil, errors.Wrapf(code.DeviceScreenShotError,
"save screenshot file failed %v", err)
}
log.Info().Str("path", path).Msg("screenshot saved")
}
return raw, nil return raw, nil
} }
+4 -3
View File
@@ -307,9 +307,10 @@ func (wd *BrowserDriver) ScreenShot(options ...option.ActionOption) (*bytes.Buff
data := resp.Data.(map[string]interface{}) data := resp.Data.(map[string]interface{})
screenshotBase64 := data["screenshot"].(string) screenshotBase64 := data["screenshot"].(string)
screenRaw, err := base64.StdEncoding.DecodeString(screenshotBase64) screenRaw, err := base64.StdEncoding.DecodeString(screenshotBase64)
res := bytes.NewBuffer(screenRaw) if err != nil {
return nil, err
return res, err }
return bytes.NewBuffer(screenRaw), nil
} }
func (wd *BrowserDriver) HttpPOST(data interface{}, pathElem ...string) (response *WebAgentResponse, err error) { func (wd *BrowserDriver) HttpPOST(data interface{}, pathElem ...string) (response *WebAgentResponse, err error) {
+40 -46
View File
@@ -49,6 +49,21 @@ func (s *ScreenResult) FilterTextsByScope(x1, y1, x2, y2 float64) ai.OCRTexts {
func (dExt *XTDriver) GetScreenResult(opts ...option.ActionOption) (screenResult *ScreenResult, err error) { func (dExt *XTDriver) GetScreenResult(opts ...option.ActionOption) (screenResult *ScreenResult, err error) {
screenshotOptions := option.NewActionOptions(opts...) screenshotOptions := option.NewActionOptions(opts...)
// take screenshot
bufSource, err := dExt.ScreenShot()
if err != nil {
return nil, errors.Wrapf(code.DeviceScreenShotError,
"take screenshot failed %v", err)
}
// compress screenshot
compressBufSource, err := compressImageBuffer(bufSource)
if err != nil {
return nil, errors.Wrapf(code.DeviceScreenShotError,
"compress screenshot failed %v", err)
}
// save compressed screenshot to file
var fileName string var fileName string
optionsList := screenshotOptions.List() optionsList := screenshotOptions.List()
if screenshotOptions.ScreenShotFileName != "" { if screenshotOptions.ScreenShotFileName != "" {
@@ -58,57 +73,33 @@ func (dExt *XTDriver) GetScreenResult(opts ...option.ActionOption) (screenResult
} else { } else {
fileName = builtin.GenNameWithTimestamp("%d_screenshot") fileName = builtin.GenNameWithTimestamp("%d_screenshot")
} }
imagePath := filepath.Join(config.GetConfig().ScreenShotsPath, fileName)
var bufSource *bytes.Buffer go func() {
var compressBufSource *bytes.Buffer path, err := saveScreenShot(compressBufSource, imagePath)
var imageResult *ai.CVResult
var imagePath string
var windowSize types.Size
var lastErr error
// get screenshot info with retry
for i := 0; i < 3; i++ {
imagePath = filepath.Join(config.GetConfig().ScreenShotsPath, fileName)
bufSource, err = dExt.ScreenShot(option.WithScreenShotFileName(imagePath))
if err != nil { if err != nil {
lastErr = err log.Error().Err(err).Msg("save screenshot file failed")
continue } else {
} log.Info().Str("path", path).Msg("screenshot saved")
compressBufSource, err = compressImageBuffer(bufSource)
if err != nil {
lastErr = err
continue
} }
}()
windowSize, err = dExt.WindowSize() windowSize, err := dExt.WindowSize()
if err != nil { if err != nil {
lastErr = errors.Wrap(code.DeviceGetInfoError, err.Error()) return nil, errors.Wrap(code.DeviceGetInfoError, err.Error())
continue
}
screenResult = &ScreenResult{
bufSource: compressBufSource,
ImagePath: imagePath,
Tags: nil,
Resolution: windowSize,
}
imageResult, err = dExt.CVService.ReadFromBuffer(compressBufSource, opts...)
if err != nil {
log.Error().Err(err).Msg("ReadFromBuffer from ImageService failed")
lastErr = err
continue
}
// success, break the loop
lastErr = nil
break
}
if lastErr != nil {
return nil, lastErr
} }
// cache screen result // read image from buffer with CV
dExt.screenResults = append(dExt.screenResults, screenResult) screenResult = &ScreenResult{
bufSource: compressBufSource,
ImagePath: imagePath,
Tags: nil,
Resolution: windowSize,
}
imageResult, err := dExt.CVService.ReadFromBuffer(compressBufSource, opts...)
if err != nil {
log.Error().Err(err).Msg("ReadFromBuffer from ImageService failed")
return nil, err
}
if imageResult != nil { if imageResult != nil {
screenResult.Texts = imageResult.OCRResult.ToOCRTexts() screenResult.Texts = imageResult.OCRResult.ToOCRTexts()
screenResult.UploadedURL = imageResult.URL screenResult.UploadedURL = imageResult.URL
@@ -128,6 +119,9 @@ func (dExt *XTDriver) GetScreenResult(opts ...option.ActionOption) (screenResult
} }
} }
// cache screen result
dExt.screenResults = append(dExt.screenResults, screenResult)
log.Debug(). log.Debug().
Str("imagePath", imagePath). Str("imagePath", imagePath).
Str("imageUrl", screenResult.UploadedURL). Str("imageUrl", screenResult.UploadedURL).
+1 -1
View File
@@ -42,7 +42,7 @@ func NewDriverSession() *DriverSession {
timeout := 30 * time.Second timeout := 30 * time.Second
session := &DriverSession{ session := &DriverSession{
ctx: context.Background(), ctx: context.Background(),
ID: "", ID: "<SessionNotInit>",
timeout: timeout, timeout: timeout,
client: &http.Client{ client: &http.Client{
Timeout: timeout, Timeout: timeout,
-12
View File
@@ -237,18 +237,6 @@ func (hd *HDCDriver) ScreenShot(opts ...option.ActionOption) (*bytes.Buffer, err
return nil, err return nil, err
} }
rawBuffer := bytes.NewBuffer(raw) rawBuffer := bytes.NewBuffer(raw)
actionOptions := option.NewActionOptions(opts...)
if actionOptions.ScreenShotFileName != "" {
// save screenshot to file
path, err := saveScreenShot(rawBuffer, actionOptions.ScreenShotFileName)
if err != nil {
return nil, errors.Wrapf(code.DeviceScreenShotError,
"save screenshot file failed %v", err)
}
log.Info().Str("path", path).Msg("screenshot saved")
}
return rawBuffer, nil return rawBuffer, nil
} }
+3 -15
View File
@@ -334,19 +334,7 @@ func (wd *WDADriver) ScreenShot(opts ...option.ActionOption) (raw *bytes.Buffer,
return nil, errors.Wrap(code.DeviceScreenShotError, return nil, errors.Wrap(code.DeviceScreenShotError,
fmt.Sprintf("decode WDA screenshot data failed: %v", err)) fmt.Sprintf("decode WDA screenshot data failed: %v", err))
} }
return raw, nil
actionOptions := option.NewActionOptions(opts...)
if actionOptions.ScreenShotFileName != "" {
// save screenshot to file
path, err := saveScreenShot(raw, actionOptions.ScreenShotFileName)
if err != nil {
return nil, errors.Wrapf(code.DeviceScreenShotError,
"save screenshot file failed %v", err)
}
log.Info().Str("path", path).Msg("screenshot saved")
}
return
} }
func (wd *WDADriver) toScale(x float64) float64 { func (wd *WDADriver) toScale(x float64) float64 {
@@ -614,13 +602,13 @@ func (wd *WDADriver) TapAbsXY(x, y float64, opts ...option.ActionOption) error {
func (wd *WDADriver) DoubleTap(x, y float64, opts ...option.ActionOption) error { func (wd *WDADriver) DoubleTap(x, y float64, opts ...option.ActionOption) error {
// [[FBRoute POST:@"/wda/doubleTap"] respondWithTarget:self action:@selector(handleDoubleTapCoordinate:)] // [[FBRoute POST:@"/wda/doubleTap"] respondWithTarget:self action:@selector(handleDoubleTapCoordinate:)]
var err error var err error
actionOptions := option.NewActionOptions(opts...)
x, y, err = convertToAbsolutePoint(wd, x, y) x, y, err = convertToAbsolutePoint(wd, x, y)
if err != nil { if err != nil {
return err return err
} }
x, y = actionOptions.ApplyOffset(x, y)
actionOptions := option.NewActionOptions(opts...)
x, y = actionOptions.ApplyOffset(x, y)
x = wd.toScale(x) x = wd.toScale(x)
y = wd.toScale(y) y = wd.toScale(y)
data := map[string]interface{}{ data := map[string]interface{}{