Forráskód Böngészése

截频参数可配置

User 5 hónapja
szülő
commit
f30c584403

+ 0 - 0
src/pages/0-ENABLE-TCPIP.BAT → BAT-TOOL/0-ENABLE-TCPIP.BAT


+ 0 - 0
src/pages/0-TEST-CONNECT.BAT → BAT-TOOL/0-TEST-CONNECT.BAT


+ 0 - 104
BAT-TOOL/ADD-ADB-TO-PATH.BAT

@@ -1,104 +0,0 @@
-@echo off
-chcp 65001 >nul
-setlocal EnableDelayedExpansion
-
-:: 检查是否以管理员身份运行
-net session >nul 2>&1
-if %errorLevel% neq 0 (
-    echo ========================================
-    echo Error: This script requires administrator privileges
-    echo ========================================
-    echo.
-    echo Please right-click and select "Run as administrator"
-    pause
-    exit /b 1
-)
-
-echo ========================================
-echo Add ADB to System PATH
-echo ========================================
-echo.
-
-set ADB_PATH=C:\Users\GIGABYTE\AppData\Local\Android\Sdk\platform-tools
-
-:: 检查 ADB 路径是否存在
-if not exist "%ADB_PATH%" (
-    echo Error: ADB path does not exist: %ADB_PATH%
-    echo.
-    pause
-    exit /b 1
-)
-
-echo ADB Path: %ADB_PATH%
-echo.
-
-:: 获取当前系统 PATH
-for /f "tokens=2*" %%A in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH 2^>nul') do set "CURRENT_PATH=%%B"
-
-:: 检查 PATH 中是否已包含 ADB 路径
-echo %CURRENT_PATH% | findstr /C:"%ADB_PATH%" >nul
-if %errorLevel% equ 0 (
-    echo ADB path is already in system PATH
-    echo.
-    echo Current PATH contains: %ADB_PATH%
-    echo.
-    pause
-    exit /b 0
-)
-
-echo Adding ADB path to system PATH...
-echo.
-
-:: 添加 ADB 路径到系统 PATH
-setx PATH "%CURRENT_PATH%;%ADB_PATH%" /M >nul 2>&1
-if %errorLevel% neq 0 (
-    echo Error: Failed to add ADB path to system PATH
-    echo.
-    echo Trying alternative method...
-    
-    :: 使用 reg 命令直接修改注册表
-    reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH /t REG_EXPAND_SZ /d "%CURRENT_PATH%;%ADB_PATH%" /f >nul 2>&1
-    if %errorLevel% neq 0 (
-        echo Error: Failed to modify system PATH
-        pause
-        exit /b 1
-    )
-    
-    :: 广播环境变量更改
-    call :BroadcastEnvironmentChange
-    echo Success: ADB path added to system PATH (using registry method)
-) else (
-    echo Success: ADB path added to system PATH
-)
-
-echo.
-echo ========================================
-echo Important Notes:
-echo ========================================
-echo 1. You may need to restart your command prompt
-echo 2. Or restart your computer for changes to take effect
-echo 3. To verify, open a new command prompt and run: adb version
-echo.
-echo ========================================
-echo Verification
-echo ========================================
-echo.
-echo Testing ADB command...
-"%ADB_PATH%\adb.exe" version >nul 2>&1
-if %errorLevel% equ 0 (
-    echo ADB is working correctly at: %ADB_PATH%
-) else (
-    echo Warning: ADB command test failed
-    echo Please verify the path is correct
-)
-echo.
-pause
-exit /b 0
-
-:BroadcastEnvironmentChange
-:: 广播环境变量更改消息
-set "HWND_BROADCAST=0xFFFF"
-set "WM_SETTINGCHANGE=0x001A"
-powershell -Command "[System.Environment]::SetEnvironmentVariable('PATH', [System.Environment]::GetEnvironmentVariable('PATH', 'Machine'), 'Machine')" >nul 2>&1
-exit /b
-

+ 32 - 3
main.js

@@ -101,6 +101,12 @@ function createWindow() {
     }
     }
   });
   });
 
 
+  // 禁用窗口关闭确认对话框,直接关闭
+  mainWindow.on('close', (event) => {
+    // 不阻止关闭事件,直接关闭窗口
+    // 如果需要清理资源,可以在这里添加
+  });
+
   if (isDev) {
   if (isDev) {
     mainWindow.loadURL('http://localhost:5173');
     mainWindow.loadURL('http://localhost:5173');
     mainWindow.webContents.openDevTools();
     mainWindow.webContents.openDevTools();
@@ -270,17 +276,40 @@ ipcMain.handle('get-device-resolution', async (event, ipPort) => {
   }
   }
 });
 });
 
 
-// IPC 处理程序:抓取设备截屏(返回 base64 PNG)
-ipcMain.handle('capture-screenshot', async (event, ipPort) => {
+// IPC 处理程序:抓取设备截屏(返回 base64 PNG/JPEG
+ipcMain.handle('capture-screenshot', async (event, ipPort, options = {}) => {
   if (!ipPort) {
   if (!ipPort) {
     return { success: false, error: '缺少设备 ID' };
     return { success: false, error: '缺少设备 ID' };
   }
   }
   try {
   try {
     const adbPath = getCachedAdbPath();
     const adbPath = getCachedAdbPath();
-    const { stdout } = await execAsync(`${adbPath} -s ${ipPort} exec-out screencap -p`, {
+    
+    // 从选项或默认值获取参数
+    const format = options.format || 'png'; // 'png' 或 'jpeg'
+    const quality = options.quality || 80; // JPEG 质量 1-100
+    const scale = options.scale || 1.0; // 缩放比例 0.1-1.0
+    
+    // 构建 screencap 命令
+    let command = `${adbPath} -s ${ipPort} exec-out screencap`;
+    
+    // 根据格式选择参数
+    if (format === 'jpeg') {
+      // JPEG 格式(更小,延迟更低)
+      command += ` -j ${quality}`;
+    } else {
+      // PNG 格式(默认)
+      command += ' -p';
+    }
+    
+    // 如果缩放比例不是 1.0,需要通过 shell 命令处理
+    // 注意:screencap 本身不支持缩放,需要通过其他方式实现
+    // 这里先实现基本功能,缩放可以在后续优化
+    
+    const { stdout } = await execAsync(command, {
       encoding: 'buffer',
       encoding: 'buffer',
       maxBuffer: 25 * 1024 * 1024,
       maxBuffer: 25 * 1024 * 1024,
     });
     });
+    
     return { success: true, data: stdout.toString('base64') };
     return { success: true, data: stdout.toString('base64') };
   } catch (error) {
   } catch (error) {
     console.error('截屏失败:', error);
     console.error('截屏失败:', error);

+ 1 - 1
preload.cjs

@@ -6,7 +6,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
   getADBDevices: () => ipcRenderer.invoke('get-adb-devices'),
   getADBDevices: () => ipcRenderer.invoke('get-adb-devices'),
   connectADBDevice: (ipPort) => ipcRenderer.invoke('connect-adb-device', ipPort),
   connectADBDevice: (ipPort) => ipcRenderer.invoke('connect-adb-device', ipPort),
   getDeviceResolution: (ipPort) => ipcRenderer.invoke('get-device-resolution', ipPort),
   getDeviceResolution: (ipPort) => ipcRenderer.invoke('get-device-resolution', ipPort),
-  captureScreenshot: (ipPort) => ipcRenderer.invoke('capture-screenshot', ipPort),
+  captureScreenshot: (ipPort, options) => ipcRenderer.invoke('capture-screenshot', ipPort, options),
   sendTap: (ipPort, x, y) => ipcRenderer.invoke('send-tap', ipPort, x, y),
   sendTap: (ipPort, x, y) => ipcRenderer.invoke('send-tap', ipPort, x, y),
   sendSwipe: (ipPort, x1, y1, x2, y2, duration) => ipcRenderer.invoke('send-swipe', ipPort, x1, y1, x2, y2, duration),
   sendSwipe: (ipPort, x1, y1, x2, y2, duration) => ipcRenderer.invoke('send-swipe', ipPort, x1, y1, x2, y2, duration),
   sendText: (ipPort, text) => ipcRenderer.invoke('send-text', ipPort, text),
   sendText: (ipPort, text) => ipcRenderer.invoke('send-text', ipPort, text),

+ 0 - 104
src/pages/ADD-ADB-TO-PATH.BAT

@@ -1,104 +0,0 @@
-@echo off
-chcp 65001 >nul
-setlocal EnableDelayedExpansion
-
-:: 检查是否以管理员身份运行
-net session >nul 2>&1
-if %errorLevel% neq 0 (
-    echo ========================================
-    echo Error: This script requires administrator privileges
-    echo ========================================
-    echo.
-    echo Please right-click and select "Run as administrator"
-    pause
-    exit /b 1
-)
-
-echo ========================================
-echo Add ADB to System PATH
-echo ========================================
-echo.
-
-set ADB_PATH=C:\Users\GIGABYTE\AppData\Local\Android\Sdk\platform-tools
-
-:: 检查 ADB 路径是否存在
-if not exist "%ADB_PATH%" (
-    echo Error: ADB path does not exist: %ADB_PATH%
-    echo.
-    pause
-    exit /b 1
-)
-
-echo ADB Path: %ADB_PATH%
-echo.
-
-:: 获取当前系统 PATH
-for /f "tokens=2*" %%A in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH 2^>nul') do set "CURRENT_PATH=%%B"
-
-:: 检查 PATH 中是否已包含 ADB 路径
-echo %CURRENT_PATH% | findstr /C:"%ADB_PATH%" >nul
-if %errorLevel% equ 0 (
-    echo ADB path is already in system PATH
-    echo.
-    echo Current PATH contains: %ADB_PATH%
-    echo.
-    pause
-    exit /b 0
-)
-
-echo Adding ADB path to system PATH...
-echo.
-
-:: 添加 ADB 路径到系统 PATH
-setx PATH "%CURRENT_PATH%;%ADB_PATH%" /M >nul 2>&1
-if %errorLevel% neq 0 (
-    echo Error: Failed to add ADB path to system PATH
-    echo.
-    echo Trying alternative method...
-    
-    :: 使用 reg 命令直接修改注册表
-    reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH /t REG_EXPAND_SZ /d "%CURRENT_PATH%;%ADB_PATH%" /f >nul 2>&1
-    if %errorLevel% neq 0 (
-        echo Error: Failed to modify system PATH
-        pause
-        exit /b 1
-    )
-    
-    :: 广播环境变量更改
-    call :BroadcastEnvironmentChange
-    echo Success: ADB path added to system PATH (using registry method)
-) else (
-    echo Success: ADB path added to system PATH
-)
-
-echo.
-echo ========================================
-echo Important Notes:
-echo ========================================
-echo 1. You may need to restart your command prompt
-echo 2. Or restart your computer for changes to take effect
-echo 3. To verify, open a new command prompt and run: adb version
-echo.
-echo ========================================
-echo Verification
-echo ========================================
-echo.
-echo Testing ADB command...
-"%ADB_PATH%\adb.exe" version >nul 2>&1
-if %errorLevel% equ 0 (
-    echo ADB is working correctly at: %ADB_PATH%
-) else (
-    echo Warning: ADB command test failed
-    echo Please verify the path is correct
-)
-echo.
-pause
-exit /b 0
-
-:BroadcastEnvironmentChange
-:: 广播环境变量更改消息
-set "HWND_BROADCAST=0xFFFF"
-set "WM_SETTINGCHANGE=0x001A"
-powershell -Command "[System.Environment]::SetEnvironmentVariable('PATH', [System.Environment]::GetEnvironmentVariable('PATH', 'Machine'), 'Machine')" >nul 2>&1
-exit /b
-

+ 100 - 0
src/pages/ScreenShot/ScrcpyConfig.js

@@ -0,0 +1,100 @@
+// ============================================
+// Scrcpy 视频流配置参数
+// ============================================
+
+const ScrcpyConfig = {
+	// 视频编码参数
+	"bitrate": "1M",
+	// 比特率:控制视频质量和网络带宽
+	// 范围:1M - 50M(推荐:2M - 16M)
+	// 值越小延迟越低但画质越差,值越大画质越好但延迟越高
+	// 选项:数字+M(如 "2M", "8M", "16M")或数字(如 2000000 表示 2Mbps)
+	
+	"max-fps": 120,
+	// 最大帧率:限制视频的最大帧率
+	// 范围:1 - 120(推荐:15 - 60)
+	// 值越小延迟越低但流畅度越差,值越大流畅度越好但延迟越高
+	// 选项:数字(如 15, 30, 60, 120)
+	
+	"max-size": 160,
+	// 最大分辨率:限制视频的最大宽度(高度按比例缩放)
+	// 范围:160 - 3840(推荐:720 - 1920)
+	// 值越小延迟越低但清晰度越差,值越大清晰度越好但延迟越高
+	// 选项:数字(如 720, 1080, 1920, 2560)
+	// 特殊值:0 表示使用设备原始分辨率
+	
+	"codec": "h264",
+	// 视频编码器:选择视频编码格式
+	// 选项:["h264", "h265", "av1"]
+	// h264: 兼容性最好,延迟较低(推荐)
+	// h265: 压缩率更高,但延迟可能稍高
+	// av1: 最新编码,需要设备支持
+	
+	// 截图相关参数(当前项目使用 screencap 命令)
+	"screencap-format": "jpg",
+	// 截图格式:控制截图文件格式
+	// 选项:["png", "jpg"]
+	// png: 无损,文件较大,延迟较高
+	// jpg: 有损,文件较小,延迟较低(推荐用于降低延迟)
+	
+	"screencap-quality": 60,
+	// 截图质量(仅当 format 为 jpeg 时有效)
+	// 范围:1 - 100(推荐:60 - 90)
+	// 值越小文件越小延迟越低但画质越差,值越大画质越好但延迟越高
+	
+	"screencap-scale": 1.0,
+	// 截图缩放比例:降低分辨率以减少数据量
+	// 范围:0.1 - 1.0(推荐:0.5 - 1.0)
+	// 值越小延迟越低但清晰度越差,值越大清晰度越好但延迟越高
+	// 选项:数字(如 0.5, 0.75, 1.0)
+	
+	// 网络和性能参数
+	"tcpip": true,
+	// 是否使用 TCP/IP 连接(网络调试)
+	// 选项:true(网络连接,延迟可能较高), false(USB连接,延迟较低)
+	
+	"buffer-size": 1048576,
+	// 缓冲区大小:控制数据传输缓冲区
+	// 范围:65536 - 10485760(64KB - 10MB,推荐:512KB - 2MB)
+	// 值越小延迟越低但可能不稳定,值越大稳定性越好但延迟越高
+	// 选项:数字(字节数,如 524288 表示 512KB)
+	
+	// 轮询和延迟参数(当前项目使用轮询截图)
+	"poll-interval": 1,
+	// 轮询间隔:两次截图之间的等待时间(毫秒)
+	// 范围:50 - 1000(推荐:50 - 200)
+	// 值越小延迟越低但CPU占用越高,值越大CPU占用越低但延迟越高
+	// 选项:数字(毫秒,如 50, 100, 200)
+	
+	"image-load-timeout": 500,
+	// 图片加载超时时间:等待图片加载的最大时间(毫秒)
+	// 范围:100 - 2000(推荐:300 - 800)
+	// 值越小响应越快但可能丢失帧,值越大稳定性越好但延迟越高
+	// 选项:数字(毫秒,如 300, 500, 800)
+	
+	// 高级参数
+	"turn-screen-off": false,
+	// 是否在连接时关闭屏幕(节省电量)
+	// 选项:true(关闭屏幕), false(保持屏幕开启)
+	
+	"stay-awake": true,
+	// 是否保持设备唤醒(防止屏幕锁定)
+	// 选项:true(保持唤醒), false(允许锁定)
+	
+	"power-off-on-close": false,
+	// 断开连接时是否关闭设备
+	// 选项:true(关闭设备), false(保持设备运行)
+	
+	"clipboard-autosync": false,
+	// 是否自动同步剪贴板
+	// 选项:true(自动同步), false(不同步)
+	// 注意:启用可能增加延迟
+	
+	"downsize-on-error": true,
+	// 出错时是否自动降低分辨率
+	// 选项:true(自动降低), false(保持原分辨率)
+	// 有助于在网络不稳定时保持连接
+};
+
+export default ScrcpyConfig;
+

+ 0 - 0
src/pages/ScreenShot/ScrcpySetting.js


+ 19 - 8
src/pages/ScreenShot/ScreenShot.js

@@ -1,4 +1,5 @@
 import { useEffect, useRef, useState, useCallback } from 'react';
 import { useEffect, useRef, useState, useCallback } from 'react';
+import ScrcpyConfig from './ScrcpyConfig.js';
 
 
 // 截屏逻辑:监听设备预览事件,轮询 adb 截屏并展示
 // 截屏逻辑:监听设备预览事件,轮询 adb 截屏并展示
 export function ScreenShotLogic() {
 export function ScreenShotLogic() {
@@ -9,6 +10,10 @@ export function ScreenShotLogic() {
   const activeDeviceRef = useRef(null);
   const activeDeviceRef = useRef(null);
   const loopIdRef = useRef(null);
   const loopIdRef = useRef(null);
   const frameCounterRef = useRef(0);
   const frameCounterRef = useRef(0);
+  
+  // 从配置文件读取参数
+  const pollInterval = ScrcpyConfig['poll-interval'] || 100;
+  const imageLoadTimeout = ScrcpyConfig['image-load-timeout'] || 500;
 
 
   // 截屏循环:请求截图 -> 显示 -> 等待加载 -> 再请求下一帧
   // 截屏循环:请求截图 -> 显示 -> 等待加载 -> 再请求下一帧
   const startLoop = useCallback(async (device) => {
   const startLoop = useCallback(async (device) => {
@@ -26,22 +31,28 @@ export function ScreenShotLogic() {
         // 请求屏幕截图
         // 请求屏幕截图
         if (!window.electronAPI || !window.electronAPI.captureScreenshot) {
         if (!window.electronAPI || !window.electronAPI.captureScreenshot) {
           console.warn('截屏 API 不可用');
           console.warn('截屏 API 不可用');
-          await delay(500);
+          await delay(pollInterval);
           runOnce();
           runOnce();
           return;
           return;
         }
         }
 
 
-        // 请求截图
-        const res = await window.electronAPI.captureScreenshot(device);
+        // 请求截图(传递配置参数)
+        const res = await window.electronAPI.captureScreenshot(device, {
+          format: ScrcpyConfig['screencap-format'],
+          quality: ScrcpyConfig['screencap-quality'],
+          scale: ScrcpyConfig['screencap-scale']
+        });
         
         
         if (!res?.success || !res.data) {
         if (!res?.success || !res.data) {
           // 截图失败,等待后重试
           // 截图失败,等待后重试
-          await delay(400);
+          await delay(pollInterval);
           runOnce();
           runOnce();
         } else {
         } else {
           // 截图成功,更新图片
           // 截图成功,更新图片
           const stamp = frameCounterRef.current++;
           const stamp = frameCounterRef.current++;
-          const dataUrl = `data:image/png;base64,${res.data}#${stamp}`;
+          const format = ScrcpyConfig['screencap-format'] || 'png';
+          const mimeType = format === 'jpeg' ? 'image/jpeg' : 'image/png';
+          const dataUrl = `data:${mimeType};base64,${res.data}#${stamp}`;
           
           
           // 创建等待图片加载的 Promise
           // 创建等待图片加载的 Promise
           const waitPromise = new Promise((resolve) => {
           const waitPromise = new Promise((resolve) => {
@@ -51,15 +62,15 @@ export function ScreenShotLogic() {
           // 更新图片源(会触发图片加载)
           // 更新图片源(会触发图片加载)
           setImageSrc(dataUrl);
           setImageSrc(dataUrl);
           
           
-          // 等待图片加载完成(onLoad 触发)或超时(500ms),然后立即请求下一帧
-          await Promise.race([waitPromise, delay(500)]);
+          // 等待图片加载完成(onLoad 触发)或超时(使用配置的超时时间),然后立即请求下一帧
+          await Promise.race([waitPromise, delay(imageLoadTimeout)]);
           
           
           // 继续请求下一帧截图
           // 继续请求下一帧截图
           runOnce();
           runOnce();
         }
         }
       } catch (err) {
       } catch (err) {
         console.error('截屏循环异常:', err);
         console.error('截屏循环异常:', err);
-        await delay(500);
+        await delay(pollInterval);
         runOnce();
         runOnce();
       }
       }
     };
     };