news 2026/3/14 12:43:24

鸿蒙 Electron 深度整合:从桌面应用到鸿蒙全场景的进阶实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙 Electron 深度整合:从桌面应用到鸿蒙全场景的进阶实践

开发者还需要面对鸿蒙分布式能力的深度调用Electron 与鸿蒙的数据双向同步跨端权限管理等进阶问题。本文将聚焦这些核心痛点,通过实战代码案例,展示鸿蒙 Electron 整合的进阶玩法,帮助开发者打造真正的全场景跨端应用。

一、进阶整合的核心场景与技术选型

1. 核心场景定位

相较于基础的消息交互,进阶整合主要面向以下场景:

  • 分布式数据共享:Electron 桌面应用与鸿蒙设备共享同一套业务数据(如用户配置、任务列表),实现数据一处修改,多端实时同步。
  • 鸿蒙原生能力调用:在 Electron 中直接调用鸿蒙设备的原生能力(如相机、定位、设备信息获取)。
  • 跨端事件联动:Electron 触发鸿蒙设备的事件(如鸿蒙智慧屏弹窗、穿戴设备震动),反之亦然。

2. 技术选型升级

在基础案例的 WebSocket 之上,我们引入更成熟的技术栈解决进阶问题:

  • 鸿蒙侧:使用鸿蒙分布式数据服务(DDS)实现数据同步,鸿蒙 RPC 远程调用实现跨设备能力调用。
  • Electron 侧:使用MQTT 协议替代 WebSocket 实现更稳定的消息推送,结合鸿蒙 SDK for Node.js直接调用鸿蒙设备接口。
  • 数据同步:使用JSON Schema规范数据格式,结合增量更新减少数据传输开销。

二、环境准备:新增依赖与配置

在基础环境的基础上,我们需要安装以下新增依赖:

1. Electron 侧新增依赖

bash

运行

# MQTT客户端(替代WebSocket,更适合物联网场景) npm install mqtt --save # 鸿蒙Node.js SDK(模拟调用鸿蒙设备能力,实际项目需替换为官方SDK) npm install @harmonyos/node-sdk --save-dev # 数据序列化与增量更新 npm install jsondiffpatch --save

2. 鸿蒙侧新增配置

entry/src/main/module.json5中添加分布式数据服务权限:

json5

{ "module": { // 原有配置... "requestPermissions": [ { "name": "ohos.permission.INTERNET" }, { "name": "ohos.permission.DISTRIBUTED_DATASYNC" // 分布式数据同步权限 }, { "name": "ohos.permission.GET_NETWORK_INFO" // 网络信息权限 } ], "distributedConfiguration": { // 开启分布式能力 "deviceCommunication": true, "dataSync": true } } }

三、代码案例:分布式数据同步与跨端能力调用

本案例实现两个核心功能:

  1. 分布式任务列表同步:Electron 与鸿蒙设备的任务列表实时增量同步。
  2. 跨端能力调用:Electron 调用鸿蒙设备的相机能力,鸿蒙设备触发 Electron 的弹窗事件。

场景 1:分布式任务列表同步(增量更新)

1.1 鸿蒙侧:分布式数据服务(DDS)实现数据存储与同步

鸿蒙侧使用分布式 KV 存储存储任务列表,并通过 MQTT 将增量数据推送给 Electron。

typescript

运行

// entry/src/main/ets/utils/DistributedData.ts import distributedKVStore from '@ohos.data.distributedKVStore'; import { BusinessError } from '@ohos.base'; import mqtt from '@ohos/mqtt'; // 鸿蒙MQTT客户端(需安装对应依赖) // 初始化分布式KV存储 let kvStore: distributedKVStore.KVStore | null = null; // MQTT客户端实例 let mqttClient: mqtt.MqttClient | null = null; // 任务数据结构 export interface Task { id: string; content: string; completed: boolean; updateTime: number; } // 初始化分布式存储 export async function initKVStore() { try { const kvManagerConfig = { context: getContext(), bundleName: 'com.example.harmonyelectron' // 替换为你的应用包名 }; const kvManager = distributedKVStore.createKVManager(kvManagerConfig); const kvStoreConfig = { storeId: 'task_list_store', securityLevel: distributedKVStore.SecurityLevel.S1, encrypt: false }; kvStore = await kvManager.getKVStore(kvStoreConfig); console.log('分布式KV存储初始化成功'); // 监听数据变化 subscribeKVStoreChange(); // 连接MQTT服务器(Electron端启动的MQTT broker) connectMqtt(); } catch (error) { console.error('初始化KV存储失败:', error as BusinessError); } } // 监听KV存储数据变化 function subscribeKVStoreChange() { if (!kvStore) return; kvStore.on('dataChange', (data) => { console.log('数据变化:', data); // 读取变化后的任务列表 getTaskList().then((taskList) => { // 推送增量数据到Electron publishMqttMessage('task/list/change', JSON.stringify(taskList)); }); }); } // 连接MQTT服务器 function connectMqtt() { const options = { url: 'mqtt://192.168.1.100:1883', // Electron的MQTT broker地址 clientId: `harmony-device-${Math.random().toString(36).substr(2, 9)}`, username: 'harmony', password: '123456', keepalive: 60 }; mqttClient = mqtt.connect(options); mqttClient.on('connect', () => { console.log('MQTT连接成功'); // 订阅Electron的任务更新主题 mqttClient?.subscribe('task/list/update'); }); // 接收Electron的任务更新消息 mqttClient?.on('message', (topic, payload) => { if (topic === 'task/list/update') { const newTask: Task = JSON.parse(payload.toString()); // 更新分布式存储 updateTask(newTask); } }); } // 发布MQTT消息 function publishMqttMessage(topic: string, payload: string) { if (mqttClient && mqttClient.connected) { mqttClient.publish(topic, payload, { qos: 1 }); } } // 读取任务列表 export async function getTaskList(): Promise<Task[]> { if (!kvStore) return []; try { const entries = await kvStore.getEntries('task_'); const taskList: Task[] = []; entries.forEach((entry) => { taskList.push(JSON.parse(entry.value as string)); }); // 按更新时间排序 return taskList.sort((a, b) => b.updateTime - a.updateTime); } catch (error) { console.error('读取任务列表失败:', error as BusinessError); return []; } } // 更新任务(新增/修改) export async function updateTask(task: Task) { if (!kvStore) return; try { await kvStore.put(`task_${task.id}`, JSON.stringify(task)); console.log('任务更新成功:', task.id); } catch (error) { console.error('更新任务失败:', error as BusinessError); } } // 删除任务 export async function deleteTask(taskId: string) { if (!kvStore) return; try { await kvStore.delete(`task_${taskId}`); console.log('任务删除成功:', taskId); } catch (error) { console.error('删除任务失败:', error as BusinessError); } }
1.2 鸿蒙侧页面:任务列表展示与操作

typescript

运行

// entry/src/main/ets/pages/TaskPage.ets import { initKVStore, getTaskList, updateTask, deleteTask, Task } from '../utils/DistributedData'; import { uuid } from '../utils/UUID'; // 自定义UUID工具类 @Entry @Component struct TaskPage { @State taskList: Task[] = []; @State newTaskContent: string = ''; aboutToAppear() { // 初始化分布式存储 initKVStore().then(() => { // 加载任务列表 this.loadTaskList(); }); } // 加载任务列表 async loadTaskList() { this.taskList = await getTaskList(); } // 添加新任务 async addTask() { if (!this.newTaskContent.trim()) return; const newTask: Task = { id: uuid(), content: this.newTaskContent.trim(), completed: false, updateTime: Date.now() }; await updateTask(newTask); this.newTaskContent = ''; this.loadTaskList(); // 重新加载列表 } // 切换任务完成状态 async toggleTaskStatus(task: Task) { const updatedTask = { ...task, completed: !task.completed, updateTime: Date.now() }; await updateTask(updatedTask); this.loadTaskList(); } // 删除任务 async removeTask(taskId: string) { await deleteTask(taskId); this.loadTaskList(); } build() { Column() { // 新增任务输入框 Row() { Input({ placeholder: '请输入新任务...', value: this.newTaskContent }) .onChange((value) => { this.newTaskContent = value; }) .flexGrow(1) .margin(10); Button('添加') .onClick(() => this.addTask()) .margin(10); } .width('100%') .padding(10); // 任务列表 List() { ForEach(this.taskList, (task) => { ListItem() { Row() { Checkbox() .checked(task.completed) .onChange(() => this.toggleTaskStatus(task)) .margin(10); Text(task.content) .fontSize(18) .textDecoration(task.completed ? TextDecorationType.LineThrough : TextDecorationType.None) .flexGrow(1); Button('删除') .onClick(() => this.removeTask(task.id)) .backgroundColor(Color.Red) .margin(10); } .width('100%') .padding(5) .borderBottom(1, Color.Grey); } }); } .width('100%') .flexGrow(1); } .width('100%') .height('100%') .backgroundColor(Color.White); } }
1.3 Electron 侧:MQTT 服务与任务列表增量同步

Electron 端启动本地 MQTT broker(使用mosca),接收鸿蒙设备的任务增量数据,并实现本地数据与鸿蒙设备的同步。

1.3.1 Electron 主进程:MQTT 服务与数据管理

javascript

运行

// main.js(新增部分) const mosca = require('mosca'); const jsondiffpatch = require('jsondiffpatch'); const fs = require('fs'); const path = require('path'); // 本地任务数据存储路径 const TASK_DATA_PATH = path.join(app.getPath('userData'), 'tasks.json'); // 任务列表数据 let taskList = []; // MQTT服务器实例 let mqttServer; // 初始化本地任务数据 function initTaskData() { try { if (fs.existsSync(TASK_DATA_PATH)) { taskList = JSON.parse(fs.readFileSync(TASK_DATA_PATH, 'utf8')); } else { fs.writeFileSync(TASK_DATA_PATH, JSON.stringify([]), 'utf8'); } } catch (error) { console.error('初始化任务数据失败:', error); taskList = []; } } // 保存任务数据到本地 function saveTaskData() { try { fs.writeFileSync(TASK_DATA_PATH, JSON.stringify(taskList), 'utf8'); } catch (error) { console.error('保存任务数据失败:', error); } } // 增量更新任务列表 function updateTaskList(newTaskList) { const diff = jsondiffpatch.diff(taskList, newTaskList); if (diff) { taskList = [...newTaskList]; saveTaskData(); // 通知渲染进程更新UI mainWindow.webContents.send('task-list-update', taskList, diff); } } // 启动MQTT服务器 function startMqttServer() { mqttServer = new mosca.Server({ port: 1883 }); console.log('MQTT服务器已启动,端口:1883'); mqttServer.on('clientConnected', (client) => { console.log('客户端连接:', client.id); // 连接成功后,推送当前任务列表到鸿蒙设备 client.publish({ topic: 'task/list/init', payload: JSON.stringify(taskList), qos: 1 }); }); mqttServer.on('published', (packet, client) => { if (!client) return; const topic = packet.topic; const payload = packet.payload?.toString() || ''; // 接收鸿蒙设备的任务列表变化 if (topic === 'task/list/change') { const newTaskList = JSON.parse(payload); updateTaskList(newTaskList); } // 接收鸿蒙设备的跨端事件 if (topic === 'cross/device/event') { const event = JSON.parse(payload); handleCrossDeviceEvent(event); } }); mqttServer.on('error', (error) => { console.error('MQTT服务器错误:', error); }); } // 处理跨设备事件(如鸿蒙触发Electron弹窗) function handleCrossDeviceEvent(event) { switch (event.type) { case 'showDialog': mainWindow.webContents.send('show-dialog', event.data); break; case 'playSound': mainWindow.webContents.send('play-sound', event.data); break; default: console.log('未知事件类型:', event.type); } } // 在app.whenReady中添加初始化 app.whenReady().then(() => { createWindow(); initTaskData(); // 新增:初始化任务数据 startMqttServer(); // 新增:启动MQTT服务器 // 原有代码... // 新增:监听渲染进程的任务更新请求 ipcMain.on('update-task', (event, task) => { // 推送任务更新到鸿蒙设备 mqttServer.publish({ topic: 'task/list/update', payload: JSON.stringify(task), qos: 1 }); // 更新本地任务列表 const index = taskList.findIndex((t) => t.id === task.id); if (index > -1) { taskList[index] = task; } else { taskList.push(task); } saveTaskData(); event.reply('task-updated', true); }); // 新增:监听渲染进程的跨端能力调用请求 ipcMain.on('call-harmony-api', (event, apiName, params) => { // 推送能力调用请求到鸿蒙设备 mqttServer.publish({ topic: 'cross/device/api', payload: JSON.stringify({ apiName, params }), qos: 1 }); // 监听鸿蒙设备的响应 mqttServer.once('published', (packet) => { if (packet.topic === 'cross/device/api/response') { const response = JSON.parse(packet.payload.toString()); event.reply('harmony-api-response', response); } }); }); });
1.3.2 Electron 渲染进程:任务列表 UI 与跨端交互

html

预览

<!-- index.html(替换为任务列表页面) --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>鸿蒙Electron分布式任务列表</title> <style> /* 简化样式,实际项目可按需美化 */ body { font-family: Arial, sans-serif; padding: 20px; background-color: #f5f5f5; } .container { max-width: 800px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } .task-input { display: flex; margin-bottom: 20px; } #taskContent { flex-grow: 1; padding: 10px; font-size: 16px; border: 1px solid #ccc; border-radius: 4px; } #addTaskBtn { padding: 10px 20px; margin-left: 10px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; } #taskList { list-style: none; padding: 0; } .task-item { display: flex; align-items: center; padding: 10px; border-bottom: 1px solid #eee; } .task-item input[type="checkbox"] { margin-right: 10px; } .task-item .task-content { flex-grow: 1; } .task-item .task-content.completed { text-decoration: line-through; color: #999; } .task-item .delete-btn { padding: 5px 10px; background-color: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer; } .api-call-btn { margin-top: 20px; padding: 10px 20px; background-color: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer; } </style> </head> <body> <div class="container"> <h1>分布式任务列表(Electron ↔ 鸿蒙)</h1> <div class="task-input"> <input type="text" id="taskContent" placeholder="请输入任务内容..."> <button id="addTaskBtn">添加任务</button> </div> <ul id="taskList"></ul> <button class="api-call-btn" id="callCameraBtn">调用鸿蒙设备相机</button> <button class="api-call-btn" id="triggerHarmonyEventBtn">触发鸿蒙设备震动</button> </div> <script> const taskContent = document.getElementById('taskContent'); const addTaskBtn = document.getElementById('addTaskBtn'); const taskList = document.getElementById('taskList'); const callCameraBtn = document.getElementById('callCameraBtn'); const triggerHarmonyEventBtn = document.getElementById('triggerHarmonyEventBtn'); // 渲染任务列表 function renderTaskList(tasks) { taskList.innerHTML = ''; tasks.forEach(task => { const li = document.createElement('li'); li.className = 'task-item'; li.innerHTML = ` <input type="checkbox" ${task.completed ? 'checked' : ''} data-id="${task.id}"> <div class="task-content ${task.completed ? 'completed' : ''}">${task.content}</div> <button class="delete-btn" data-id="${task.id}">删除</button> `; taskList.appendChild(li); }); // 绑定复选框事件 document.querySelectorAll('.task-item input[type="checkbox"]').forEach(checkbox => { checkbox.addEventListener('change', (e) => { const taskId = e.target.dataset.id; const task = tasks.find(t => t.id === taskId); if (task) { const updatedTask = { ...task, completed: e.target.checked, updateTime: Date.now() }; window.electronAPI.updateTask(updatedTask); } }); }); // 绑定删除按钮事件 document.querySelectorAll('.task-item .delete-btn').forEach(btn => { btn.addEventListener('click', (e) => { const taskId = e.target.dataset.id; const updatedTasks = tasks.filter(t => t.id !== taskId); // 推送删除后的列表到鸿蒙(实际项目可单独写删除接口) window.electronAPI.updateTask({ id: taskId, isDelete: true }); renderTaskList(updatedTasks); }); }); } // 添加任务 addTaskBtn.addEventListener('click', () => { const content = taskContent.value.trim(); if (!content) return; const newTask = { id: Math.random().toString(36).substr(2, 9), content, completed: false, updateTime: Date.now() }; window.electronAPI.updateTask(newTask); taskContent.value = ''; }); // 调用鸿蒙相机能力 callCameraBtn.addEventListener('click', () => { window.electronAPI.callHarmonyApi('camera.takePhoto', { quality: 'high' }, (response) => { alert(`鸿蒙相机调用结果:${JSON.stringify(response)}`); }); }); // 触发鸿蒙设备震动 triggerHarmonyEventBtn.addEventListener('click', () => { window.electronAPI.callHarmonyApi('device.vibrate', { duration: 1000 }, (response) => { alert(`鸿蒙震动触发结果:${JSON.stringify(response)}`); }); }); // 监听主进程的任务列表更新 window.electronAPI.onTaskListUpdate((tasks) => { renderTaskList(tasks); }); // 监听主进程的弹窗事件 window.electronAPI.onShowDialog((data) => { alert(`鸿蒙触发弹窗:${data.message}`); }); // 初始化时请求任务列表 window.electronAPI.getTaskList((tasks) => { renderTaskList(tasks); }); </script> </body> </html>

场景 2:跨端能力调用(Electron 调用鸿蒙相机)

2.1 鸿蒙侧:RPC 远程调用处理相机能力

typescript

运行

// entry/src/main/ets/utils/RpcServer.ts import rpc from '@ohos.rpc'; import camera from '@ohos.camera'; import mqtt from '@ohos/mqtt'; // RPC服务端实现 class HarmonyApiServer extends rpc.RemoteObject { constructor(descriptor: string) { super(descriptor); } // 处理远程调用请求 onRemoteRequest(code: number, data: rpc.MessageParcel, reply: rpc.MessageParcel, option: rpc.MessageOption): boolean { switch (code) { case 1: // 相机拍照 const quality = data.readString(); const photoPath = this.takePhoto(quality); reply.writeString(JSON.stringify({ success: true, path: photoPath })); break; case 2: // 设备震动 const duration = data.readInt32(); this.vibrate(duration); reply.writeString(JSON.stringify({ success: true })); break; default: reply.writeString(JSON.stringify({ success: false, error: '未知接口' })); break; } return true; } // 拍照方法 private takePhoto(quality: string): string { // 简化实现,实际项目需调用相机原生API const cameraManager = camera.getCameraManager(getContext()); const cameraDevices = cameraManager.getSupportedCameras(); if (cameraDevices.length === 0) { return ''; } // 模拟拍照,返回路径 return `/sdcard/photo_${Date.now()}.jpg`; } // 震动方法 private vibrate(duration: number): void { // 调用鸿蒙震动API const vibrator = require('@ohos.vibrator'); vibrator.vibrate({ type: 'time', duration: duration }).catch((error) => { console.error('震动失败:', error); }); } } // 启动RPC服务并监听MQTT的API调用请求 export function startRpcServer() { const rpcServer = new HarmonyApiServer('harmony.api.server'); // 注册RPC服务(实际项目需通过分布式能力发布服务) rpc.registerRpcService('harmony.api', rpcServer); // 监听MQTT的API调用请求 mqttClient?.on('message', (topic, payload) => { if (topic === 'cross/device/api') { const { apiName, params } = JSON.parse(payload.toString()); // 处理API调用 let response; if (apiName === 'camera.takePhoto') { response = { success: true, path: `/sdcard/photo_${Date.now()}.jpg` }; } else if (apiName === 'device.vibrate') { this.vibrate(params.duration); response = { success: true }; } else { response = { success: false, error: '未知API' }; } // 回复Electron mqttClient?.publish('cross/device/api/response', JSON.stringify(response), { qos: 1 }); } }); }

四、运行与测试要点

  1. MQTT 服务器启动:确保 Electron 的 MQTT 服务器在 1883 端口正常启动,鸿蒙设备与 Electron 在同一局域网。
  2. 分布式权限配置:鸿蒙设备需开启分布式数据同步权限,在设置中允许应用的分布式能力。
  3. 增量数据同步测试:在 Electron 或鸿蒙设备中添加 / 修改 / 删除任务,观察另一端是否实时同步。
  4. 跨端能力调用测试:点击 Electron 的 “调用鸿蒙设备相机” 按钮,观察鸿蒙设备是否触发相机功能,并返回结果。

五、避坑指南与优化建议

1. 常见坑点

  • 分布式权限问题:鸿蒙的分布式数据同步需要申请DISTRIBUTED_DATASYNC权限,且设备需登录同一华为账号。
  • MQTT 断连重连:网络波动时需实现 MQTT 的自动重连机制,避免数据丢失。
  • 数据冲突处理:多端同时修改同一数据时,需通过时间戳或版本号解决冲突。

2. 优化建议

  • 数据压缩:使用gzip压缩增量数据,减少网络传输开销。
  • 离线同步:添加离线数据缓存,设备联网后自动同步未上传的数据。
  • 权限校验:跨端能力调用时添加身份校验,避免恶意设备调用。

六、总结

本文通过分布式任务列表同步和跨端能力调用两个核心案例,展示了鸿蒙 Electron 整合的进阶实践。相较于基础的消息交互,进阶整合更注重数据的一致性能力的互通性,这也是打造全场景应用的关键。

随着鸿蒙系统的持续迭代,以及 Electron 对跨平台支持的不断优化,两者的融合将覆盖更多场景:从桌面应用与鸿蒙智能设备的联动,到 Electron 应用直接部署到鸿蒙桌面版。开发者可以基于本文的思路,结合实际业务需求,探索更多跨端整合的可能性,真正实现 “一次开发,全场景部署” 的目的

欢迎大家加入[开源鸿蒙跨平台开发者社区](https://openharmonycrossplatform.csdn.net),一起共建开源鸿蒙跨平台生态。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/11 22:04:36

Wi-Fi® 网络管理技术

Wi-Fi Agile Multiband™ Wi-Fi Agile Multiband™ 有助于更好地管理 Wi-Fi 网络环境,并使 Wi-Fi 设备能够更好地响应不断变化的 Wi-Fi 网络条件。Wi-Fi 灵活多频段有助于高效利用多个频段,并包括更好地管理频谱和网络资源、平衡网络负载、提高移动性并提供最佳用户体验的机…

作者头像 李华
网站建设 2026/3/10 10:41:45

人工智能药学大会现场

如题&#xff0c;生信基地的小伙伴前两天参加了场学术会议&#xff0c;简单记录一下此次参会的收获。校长报告人工智能如何重塑药物研发的未来&#xff1f;智能药学将如何推动医药产业转型升级&#xff1f;是加速进程还是改变范式&#xff1f;首先上午第一场报告由校长提出三个…

作者头像 李华
网站建设 2026/3/12 22:02:21

X-CLIP多模态模型深度解析:视频理解的技术之旅

X-CLIP多模态模型深度解析&#xff1a;视频理解的技术之旅 【免费下载链接】xclip-base-patch32 项目地址: https://ai.gitcode.com/hf_mirrors/microsoft/xclip-base-patch32 在人工智能的快速发展中&#xff0c;多模态理解技术正成为连接视觉与语言世界的重要桥梁。X…

作者头像 李华
网站建设 2026/3/13 3:36:36

【Java】java 集合框架(详解)零基础入门到精通,收藏这篇就够了

1. 概述 &#x1f680; &#x1f525; Java集合框架 提供了一系列用于存储和操作对象组的接口和类。这些工具是为了解决不同数据结构通用操作的需求而设计的。集合框架主要包括两种类型的容器&#xff1a; 一种是 集合&#xff08;Collection&#xff09;&#xff0c;用于存储…

作者头像 李华
网站建设 2026/3/14 6:29:47

告别手动提交:用Git Auto Commit Action实现自动化工作流

告别手动提交&#xff1a;用Git Auto Commit Action实现自动化工作流 【免费下载链接】git-auto-commit-action Automatically commit and push changed files back to GitHub with this GitHub Action for the 80% use case. 项目地址: https://gitcode.com/gh_mirrors/gi/g…

作者头像 李华
网站建设 2026/3/12 9:10:48

解决ComfyUI-SeedVR2视频超分项目wandb依赖冲突的3种实用方法

解决ComfyUI-SeedVR2视频超分项目wandb依赖冲突的3种实用方法 【免费下载链接】ComfyUI-SeedVR2_VideoUpscaler Non-Official SeedVR2 Vudeo Upscaler for ComfyUI 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-SeedVR2_VideoUpscaler 你在使用ComfyUI-SeedVR2…

作者头像 李华