import { ipcMain } from 'electron'; import { exec } from 'child_process'; import { promisify } from 'util'; import { getCachedAdbPath } from '../config.js'; const execAsync = promisify(exec); // 截图缓存:存储最后一次截图的设备和数据 const screenshotCache = { device: null, data: null, timestamp: null, options: null, }; // 获取缓存的截图数据 export function getCachedScreenshot(ipPort) { // 如果缓存存在且设备匹配,且缓存时间在 5 秒内,返回缓存数据 if (screenshotCache.device === ipPort && screenshotCache.data && screenshotCache.timestamp) { const now = Date.now(); const cacheAge = now - screenshotCache.timestamp; // 缓存有效期:5 秒(可以根据需要调整) if (cacheAge < 5000) { return { success: true, data: screenshotCache.data, fromCache: true, }; } } return null; } // 更新截图缓存 function updateScreenshotCache(ipPort, data, options) { screenshotCache.device = ipPort; screenshotCache.data = data; screenshotCache.timestamp = Date.now(); screenshotCache.options = options; } // 抓取设备截屏(返回 base64 PNG/JPEG) export async function captureScreenshot(ipPort, options = {}) { if (!ipPort) { return { success: false, error: '缺少设备 ID' }; } try { const adbPath = getCachedAdbPath(); // 从选项或默认值获取参数 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', maxBuffer: 25 * 1024 * 1024, }); const base64Data = stdout.toString('base64'); // 更新缓存 updateScreenshotCache(ipPort, base64Data, options); return { success: true, data: base64Data }; } catch (error) { return { success: false, error: error.message }; } } // 注册 IPC 处理器 export function registerIpcHandlers() { // IPC 处理程序:抓取设备截屏(返回 base64 PNG/JPEG) ipcMain.handle('capture-screenshot', async (event, ipPort, options = {}) => { return await captureScreenshot(ipPort, options); }); // IPC 处理程序:获取缓存的截图(如果存在且未过期) ipcMain.handle('get-cached-screenshot', async (event, ipPort) => { const cached = getCachedScreenshot(ipPort); if (cached) { return cached; } return { success: false, error: '缓存不存在或已过期' }; }); }