7.3 KiB
7.3 KiB
直播中台控制系统 - 功能使用说明
🎯 项目架构
系统组成
- 主进程 (Main Process): 负责系统管理、数据中心、核心业务逻辑、多窗口协调
- 中控平台 (Renderer): 渲染UI、处理用户输入,仅包含轻量级IPC通信代码
- 数字人窗口 (Renderer): 渲染数字人界面和iframe,接收主进程数据
技术架构
- 桌面端: Electron 28 + TypeScript
- 前端: Vue 3 + Composition API + Ant Design Vue
- 状态管理: Pinia (仅UI状态)
- 通信机制: IPC (进程间通信)
🚀 核心功能实现
1. 开始直播
功能描述: 完整的直播启动流程 实现流程:
- 从 UserStore 获取用户ID (固定值: 'rs876543')
- 创建/显示直播窗口
- 等待页面和iframe加载完成 (30秒超时)
- 获取数字人平台sessionId
- 设置直播状态
- 发送欢迎消息
前端调用:
// userId 自动从 userStore.user?.userId 获取 (固定值: 'rs876543')
await window.electron.ipcRenderer.invoke('start-live', { userId })
主进程处理: [src/main/ipc/live.ts:80-118]
2. 结束直播
功能描述: 清理直播资源和状态 实现流程:
- 重置直播状态
- 关闭直播窗口
- 清空sessionId
- 重置所有插播状态
前端调用:
await window.electron.ipcRenderer.invoke('stop-live')
主进程处理: [src/main/ipc/live.ts:124-145]
2.1. 强制关闭
功能描述: 强制关闭直播窗口并清理所有资源(紧急情况使用) 实现流程:
- 发送清理指令到直播窗口
- 强制清理所有媒体资源(摄像头、麦克风、音频、视频状态)
- 恢复iframe内视频音量到正常状态
- 强制销毁直播窗口(移除所有监听器)
- 重置所有直播状态和插播状态
- 不管当前直播状态,强制执行关闭
前端调用:
await window.electron.ipcRenderer.invoke('force-close-live')
主进程处理: [src/main/ipc/live.ts:147-183]
2.2. 媒体资源清理
功能描述: 在强制关闭时彻底清理所有媒体资源 清理内容:
- 摄像头资源: 停止摄像头视频流,清理video元素
- 麦克风资源: 停止麦克风流,清理audio元素
- 音频资源: 暂停所有播放中的音频,重置播放状态
- 视频状态: 恢复iframe内视频音量,清理插播状态
- 应用状态: 重置所有媒体相关的变量和标志位
实现细节:
// 主进程发送清理指令
liveState.liveWindow.webContents.send("force-cleanup-media");
// 直播窗口接收并处理
window.electron.ipcRenderer.on('force-cleanup-media', handleForceCleanup);
// 清理函数会执行:
forceCleanupMedia() // 停止所有媒体流、重置状态
3. 全屏插播
功能描述: 切换摄像头全屏显示 实现方式: 切换视频插入状态,发送指令到直播窗口
前端调用:
window.electron.ipcRenderer.send('toggle-camera-insert')
直播窗口响应: [src/renderer/src/views/Live/index.vue:92-113]
4. 窗口插播
功能描述: 开启摄像头画中画模式 实现方式: 在直播窗口右下角显示小窗口摄像头
前端调用:
window.electron.ipcRenderer.send('insert-camera-video')
直播窗口响应: [src/renderer/src/views/Live/index.vue:84-90]
5. 音频插入
功能描述: 插入音频文件播放 实现方式: 降低主视频音量,播放插入音频
前端调用:
window.electron.ipcRenderer.send('insert-video-audio')
直播窗口响应: [src/renderer/src/views/Live/index.vue:116-147]
6. 镜头切换
功能描述: 摄像头开启/关闭切换 实现方式: 切换摄像头激活状态
前端调用:
window.electron.ipcRenderer.send('toggle-camera-insert')
7. 发送消息到数字人
功能描述: 向数字人发送文本内容 实现流程:
- 验证直播状态和sessionId
- 构建消息参数
- 调用数字人平台API
- 处理响应结果
前端调用:
await window.electron.ipcRenderer.invoke('push-explain-position', '消息内容')
主进程处理: [src/main/ipc/live.ts:145-164]
🔄 状态管理
主进程状态
interface LiveState {
sessionId: string | null; // 数字人会话ID
userId: string | null; // 用户ID
isVideoInserted: boolean; // 视频插入状态
isLiveOn: boolean; // 直播状态
jobList: any[]; // 岗位列表
currentJob: any; // 当前岗位
cameraActive: boolean; // 摄像头激活状态
audioActive: boolean; // 音频激活状态
liveWindow: BrowserWindow | null; // 直播窗口
}
状态同步
- 获取直播状态:
get-live-statusIPC接口 - UI状态自动同步: 每2秒从主进程同步状态
- 状态变化实时响应: 按钮状态根据直播状态动态更新
🎮 用户界面
中控台布局
- 顶部导航: 应用标题和用户信息
- 左侧边栏: 岗位列表和详情信息
- 主内容区: 直播控制面板、AI模型管理
- 底部输入区: 消息输入和快捷指令
按钮状态管理
- 开始直播: loading状态,直播中时禁用
- 结束直播: 仅直播时可用,loading状态
- 插播功能: 仅直播时可用
- 发送消息: 仅直播时可用
快捷指令
- 欢迎新观众
- 感谢陪伴
- 互动提问
- 行业分享
🔗 外部服务集成
数字人平台
- API地址:
http://ywpt.hx.cn/dmhx/ - 获取会话:
get_sessionid接口 - 发送消息:
human接口 - 参数格式:
{ sessionid, text, type: "echo", interrupt: true }
直播展示
- 直播地址:
https://dmdemo.hx.cn/dashboard.html - 参数传递:
?userId=${userId} - 嵌入方式: iframe 全屏显示
🛠️ 开发和调试
启动项目
npm run dev # 开发模式
npm run build # 生产构建
npm run typecheck # 类型检查
调试接口
// 获取主进程实时状态
const state = getLiveState();
// 获取直播状态 (IPC)
const status = await window.electron.ipcRenderer.invoke('get-live-status');
日志输出
- 主进程日志在Electron控制台查看
- 渲染进程日志在浏览器开发者工具查看
- API调用错误会在控制台详细显示
📝 注意事项
权限要求
- 摄像头权限: 需要用户授权
- 麦克风权限: 音频插入功能需要
- 网络权限: 访问外部API服务
错误处理
- 网络请求失败: 自动重试和错误提示
- 权限被拒绝: 友好的权限请求提示
- 状态不一致: 自动同步机制修复
性能优化
- 状态同步频率适中 (2秒)
- IPC通信异步处理
- 资源清理及时 (窗口关闭时)
🚀 使用流程
- 启动应用: 运行
npm run dev启动开发环境 - 开始直播: 点击"开始直播"按钮,系统自动获取sessionId并创建直播窗口
- 发送消息: 在输入框输入内容或使用快捷指令,数字人会实时播报
- 插播控制: 使用插播功能切换摄像头或插入音频
- 结束直播: 点击"结束直播"清理资源
系统已按照现代化架构设计,主进程负责核心逻辑,渲染进程专注于UI展示,通过IPC实现高效通信。