# hmElectronAI-camerat **Repository Path**: HMPC2Dtest/hmelectronai-camerat ## Basic Information - **Project Name**: hmElectronAI-camerat - **Description**: 基于 HarmonyOS Electron 框架开发的多媒体功能应用,展示了如何在鸿蒙系统上使用 Electron 框架实现摄像头调用、视频预览和保存功能。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-04 - **Last Updated**: 2026-03-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 鸿蒙应用electron框架开发屏幕录制与摄像头测试功能 ## 项目简介 本项目是基于 HarmonyOS Electron 框架开发的多媒体功能应用,展示了如何在鸿蒙系统上使用 Electron 框架实现摄像头调用、视频预览和保存功能。 主要功能包括: - 屏幕和窗口选择录制 - 摄像头实时预览 - 拍照和视频录制 - 实时录制状态显示 - 录制时长计时 - 视频预览功能 - 自定义保存路径和文件名 - 现代化用户界面 ## AI提示词 by trae ### 摄像头调用测试功能 时间:2026-03-04 在鸿蒙应用的主页面中添加一个标题为"摄像头调用测试"的按钮组件。当用户点击该按钮时,应弹出一个子窗口(或模态窗口),该子窗口需用electron框架实现以下功能: 1. 摄像头预览功能:在子窗口中实时显示当前设备摄像头捕获的画面 2. 拍照功能: - 提供一个"拍照"按钮 - 点击后捕获当前摄像头画面并生成图片 - 实现图片保存功能,将生成的图片保存到设备本地文件管理系统 3. 视频录制功能: - 提供"录制"按钮,点击后开始录制视频 - 提供"结束"按钮,点击后停止录制并生成视频文件 - 实现视频保存功能,将录制的视频保存到设备本地文件管理系统 4. 权限处理: - 当用户首次点击"摄像头调用测试"按钮时,必须弹出摄像头权限申请对话框 - 只有在用户同意授予摄像头权限后,才能打开子窗口并启动摄像头预览 - 若用户拒绝权限,需显示友好提示信息,说明功能需要摄像头权限才能使用 ### 屏幕录制功能 基于 #web `https://developer.huawei.com/consumer/cn/forum/topic/0201205407303759568` 提供的技术参考,使用Electron框架开发一个具备屏幕录制功能的鸿蒙应用。具体实现要求如下: 1. 应用主页设计: - 在现有主页界面中新增一个视觉突出的"屏幕录制"按钮 - 按钮需符合鸿蒙应用设计规范,包含适当的图标和文字说明 2. 子窗口功能实现: - 点击"屏幕录制"按钮后,打开一个独立的子窗口 - 子窗口标题固定为"屏幕录制器" - 窗口尺寸应设计为适合录制控制操作的合理大小 3. 屏幕录制功能: - 提供屏幕选择功能,允许用户选择需要录制的屏幕区域或特定窗口 - 实现"录制"按钮,点击后启动屏幕录制功能 - 实现"停止"按钮,点击后终止当前录制进程 - 录制过程中应显示录制状态指示和时长计时器 4. 视频保存功能: - 录制停止后,自动弹出文件保存对话框 - 支持用户自定义保存路径和文件名 - 视频文件格式应选择鸿蒙系统兼容的常用格式(如MP4) - 保存过程中需显示进度指示,完成后给予明确提示 5. 技术要求: - 确保屏幕录制功能在鸿蒙系统环境下稳定运行 - 优化录制性能,避免过度占用系统资源 - 实现必要的错误处理和用户提示 - 确保应用符合鸿蒙应用的安全规范和权限要求 ## AI生成代码统计 AI新增生成的代码行数累计:1576 项目新增代码行数累计(不含so等二进制):1576 AI占比:100% ## 最新功能更新 时间:2026-03-04 - 新增"摄像头调用测试"功能按钮,与其他按钮保持一致的样式 - 点击按钮后打开独立的摄像头测试子窗口 - 实现摄像头实时预览功能,支持前置摄像头 - 实现拍照功能,可捕获当前画面并生成PNG图片 - 实现视频录制功能,支持录制摄像头画面和音频 - 录制过程中显示实时计时器和录制状态指示 - 拍照和录制完成后可在媒体库中预览 - 支持保存照片和视频文件到本地文件系统 - 实现摄像头权限申请对话框,首次使用时弹出 - 处理权限拒绝、设备无摄像头等异常情况 - 现代化深色主题UI设计,与屏幕录制器风格一致 ### 屏幕录制功能更新 - 新增"屏幕录制"功能按钮,与其他按钮保持一致的样式 - 点击按钮后打开独立的屏幕录制器子窗口 - 实现屏幕源选择功能,支持选择整个屏幕或特定窗口进行录制 - 使用desktopCapturer API获取可录制的屏幕源列表(通过主进程调用) - 使用MediaRecorder API实现视频录制功能 - 录制过程中显示实时计时器和录制状态指示 - 录制完成后可预览录制的视频内容 - 支持保存视频文件,可选择保存路径和文件名 - 支持WebM格式视频文件 - 修复desktopCapturer在渲染进程不可用的问题 - 将"选择录制源"提示改为"需要先选中录制源" - 优化了主界面按钮布局,使所有按钮整齐排列 ## 技术架构 - **HarmonyOS Electron 框架**:提供跨平台桌面应用支持 - **HarmonyOS**:华为鸿蒙操作系统 - **Web 技术**:HTML5 Canvas + CSS3 + JavaScript - **双模块设计**:electron 主模块 + web_engine 引擎模块 ## 功能特性 ### 摄像头测试器 - 完整的摄像头调用功能 - 支持实时预览摄像头画面 - 拍照功能,生成PNG格式图片 - 视频录制功能,支持音频录制 - 录制过程中显示计时器和状态指示 - 拍照和录制完成后可在媒体库预览 - 支持保存照片和视频到本地文件系统 - 摄像头权限申请对话框 - 异常处理(权限拒绝、设备无摄像头等) - 现代化深色主题UI设计 ### 屏幕录制器 - 完整的屏幕录制功能 - 支持选择整个屏幕或特定窗口进行录制 - 实时显示可录制源的缩略图预览 - 录制过程中显示计时器和状态指示 - 录制完成后可预览视频内容 - 支持保存为WebM格式视频文件 - 现代化深色主题UI设计 - 录制状态动画效果 ### 贪食蛇游戏 - 完整的贪食蛇游戏逻辑 - 现代化 UI 设计(渐变背景、发光效果) - 得分和最高分记录(使用 localStorage 保存) - 键盘控制(方向键 / WASD) - 移动端触控支持 - 暂停/继续功能 - 游戏结束检测和重新开始 - 随分数增加的游戏速度提升 ### 窗口管理 - 主窗口:应用主界面 - 子窗口:贪食蛇游戏窗口、屏幕录制器窗口、摄像头测试窗口 - 悬浮窗:始终置顶的小窗口 - IPC 进程间通信 ## 项目结构 ``` ohos_hap347tanshishe/ ├── electron/ # Electron 主应用模块 │ ├── src/main/ets/ # ETS 代码 │ │ ├── entryability/ # 入口能力 │ │ ├── pages/ # 页面 │ │ │ ├── Index.ets # 主页面 │ │ │ └── SubWindow.ets # 子窗口页面 │ │ └── process/ # 进程管理 │ └── build-profile.json5 # 构建配置 ├── web_engine/ # Web 引擎模块 │ ├── src/main/ets/ # ETS 适配器代码 │ │ ├── ability/ # 能力实现 │ │ ├── adapter/ # 平台适配器 │ │ │ └── SubWindowAdapter.ets # 子窗口适配器 │ │ └── components/ # 组件 │ └── src/main/resources/resfile/resources/app/ # Web 应用资源 │ ├── main.js # Electron 主进程 │ ├── index.html # 主页面 │ ├── renderer.js # 渲染进程 │ ├── snake.html # 贪食蛇游戏页面 │ ├── screen-recorder.html # 屏幕录制器页面 │ ├── camera.html # 摄像头测试页面 │ ├── child.html # 子窗口页面 │ └── float.html # 悬浮窗页面 ├── AppScope/ # 应用全局配置 ├── docs/ # 项目文档 └── readme.md # 项目说明文档 ``` ## 开发环境 - DevEco Studio - HarmonyOS SDK - Node.js ## 使用说明 ### 运行应用 1. 使用 DevEco Studio 打开项目 2. 构建并运行应用 3. 在主窗口中点击相应功能按钮 4. 子窗口将弹出并显示对应功能界面 ### 游戏操作 | 操作 | 按键 | |------|------| | 向上移动 | ↑ 或 W | | 向下移动 | ↓ 或 S | | 向左移动 | ← 或 A | | 向右移动 | → 或 D | | 暂停/继续 | 空格键 | ## 核心代码说明 ### 摄像头权限申请(重要) 在 HarmonyOS Electron 框架中,摄像头权限申请需要遵循以下步骤: #### 1. 在 module.json5 中声明权限 **重要**:必须在 `web_engine/src/main/module.json5` 文件中声明权限: ```json { "module": { "name": "web_engine", "type": "har", "requestPermissions": [ { "name": "ohos.permission.CAMERA", "reason": "$string:camera_permission_reason", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } } ] } } ``` #### 2. 添加权限说明字符串 在 `web_engine/src/main/resources/base/element/string.json` 中添加: ```json { "string": [ { "name": "camera_permission_reason", "value": "用于摄像头拍照和视频录制功能" } ] } ``` #### 3. 主进程请求权限 ```javascript // main.js const { systemPreferences } = require('electron'); // 请求摄像头权限 ipcMain.handle('request-camera-permission', async function() { try { var result = await systemPreferences.requestSystemPermission('camera'); // 重要:返回值可能是布尔值 true,而不是字符串 'granted' var granted = result === true || result === 'granted'; return { granted: granted, status: result }; } catch (error) { return { granted: false, status: 'error', error: error.message }; } }); // 打开权限设置页面 ipcMain.handle('open-permission-settings', async function() { systemPreferences.openApplicationInfoEntry(); }); ``` #### 4. 渲染进程调用 ```javascript // renderer.js const { ipcRenderer } = require('electron'); async function requestCameraPermission() { var result = await ipcRenderer.invoke('request-camera-permission'); if (result.granted) { // 权限已授予,启动摄像头 await startCamera(); } else { // 权限被拒绝,引导用户去设置 ipcRenderer.invoke('open-permission-settings'); } } ``` #### 常见错误 | 错误 | 原因 | 解决方案 | |------|------|---------| | `result === 'granted'` 判断失败 | 返回值是布尔值 `true` 而非字符串 | 使用 `result === true \|\| result === 'granted'` | | `getSystemPermissionStatus is not a function` | 该 API 不存在 | 直接使用 `requestSystemPermission` | | 权限声明不生效 | 声明位置错误 | 在 `web_engine` 模块而非 `electron` 模块声明 | ### 摄像头测试核心代码 启动摄像头: ```javascript cameraStream = await navigator.mediaDevices.getUserMedia({ video: { width: { ideal: 1280 }, height: { ideal: 720 }, facingMode: 'user' }, audio: true }); cameraVideo.srcObject = cameraStream; ``` 拍照: ```javascript captureCanvas.width = settings.width || 1280; captureCanvas.height = settings.height || 720; const ctx = captureCanvas.getContext('2d'); ctx.drawImage(cameraVideo, 0, 0, captureCanvas.width, captureCanvas.height); captureCanvas.toBlob(function(blob) { // 保存图片 }, 'image/png'); ``` 录制视频: ```javascript mediaRecorder = new MediaRecorder(cameraStream, { mimeType: 'video/webm;codecs=vp9,opus' }); mediaRecorder.ondataavailable = (event) => { if (event.data.size > 0) { recordedChunks.push(event.data); } }; mediaRecorder.start(1000); ``` ### 屏幕录制器核心代码 获取屏幕源: ```javascript const sources = await desktopCapturer.getSources({ types: ['screen', 'window'], thumbnailSize: { width: 320, height: 180 } }); ``` 开始录制: ```javascript const stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: { mandatory: { chromeMediaSource: 'desktop', chromeMediaSourceId: selectedSource.id, minWidth: 1280, maxWidth: 1920, minHeight: 720, maxHeight: 1080 } } }); mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm;codecs=vp9' }); mediaRecorder.start(1000); ``` 保存视频: ```javascript mediaRecorder.onstop = () => { recordedBlob = new Blob(recordedChunks, { type: 'video/webm' }); const url = URL.createObjectURL(recordedBlob); previewVideo.src = url; }; ``` ### 创建子窗口 ```javascript function createCameraWindow() { cameraWindow = new BrowserWindow({ width: 950, height: 750, parent: mainWindow, title: '摄像头调用测试', resizable: true, webPreferences: { nodeIntegration: true, contextIsolation: false } }); cameraWindow.loadFile(path.join(__dirname, 'camera.html')); } ``` ### IPC 通信 主进程监听: ```javascript ipcMain.on('open-camera', function() { createCameraWindow(); }); ``` 渲染进程发送: ```javascript cameraBtn.addEventListener('click', () => { ipcRenderer.send('open-camera'); }); ``` ### 游戏核心逻辑 ```javascript function update() { direction = { x: nextDirection.x, y: nextDirection.y }; const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y }; // 边界检测 if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) { gameOver(); return; } // 自身碰撞检测 for (let i = 0; i < snake.length; i++) { if (snake[i].x === head.x && snake[i].y === head.y) { gameOver(); return; } } snake.unshift(head); // 吃食物 if (head.x === food.x && head.y === food.y) { score += 10; spawnFood(); } else { snake.pop(); } } ``` ## HarmonyOS Electron 窗口类型 | 窗口类型 | 说明 | 特性 | |---------|------|------| | 主窗 | 应用主窗口 | 带边框、可拖拽、可改变大小、任务栏显示 | | 子窗 | 弹出对话框等 | 带边框、不可拖拽、不可改变大小 | | 悬浮窗 | 始终在前台显示 | 带边框、不可拖拽、默认置顶 | ## 最佳实践 1. **窗口类型选择**: - 主窗口:使用默认配置 - 模态对话框:使用 subWindow + parent - 始终置顶:使用 floatWindow 2. **IPC 通信**: - 开发阶段使用 `nodeIntegration: true` 和 `contextIsolation: false` - 生产环境建议使用 `contextBridge` 进行安全通信 3. **错误处理**: - 始终在控制台添加日志输出 - 使用 try-catch 捕获可能的异常 - 检查窗口创建是否成功 4. **摄像头权限处理**: - 首次使用时弹出权限申请对话框 - 处理权限拒绝情况,显示友好提示 - 处理设备无摄像头等异常情况 ## 许可证 Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. Use of this source code is governed by a BSD-style license. --- 版本: 1.1.0