UNPKG

@plasosdk/plaso-electron-sdk

Version:

伯索课堂Electron SDK

650 lines (495 loc) 26.2 kB
# 支持的平台与 Electron 版本 - MacOS 支持 x64、arm64架构 - Windows 支持 x86、x64架构 **<font color=red>Electron 版本要求: 14.0.0~22.3.27</font>** # 1、接入步骤 ## 1.1、安装 **<font color=red>注意: 不同平台依赖包不互通</font>** **第一步:安装 @electron/remote** ```shell npm install @electron/remote --global-style --legacy-peer-deps ``` **第二步:安装 plaso-electron-sdk** ```shell npm install @plasosdk/plaso-electron-sdk --global-style ``` **<font color=red>注意: 不同平台需要单独安装,尤其是MacOS,请分别在Intel芯片和Apple芯片的电脑上安装</font>** ## electron-builder打包特别说明 使用electron-builder打包时,需要对工程的node_modules中的agora-electron-sdk-v4进行特殊处理,该包是在安装@plasosdk/plaso-electron-sdk时动态安装的,因此需要通过配置extraResources单独拷贝。配置入如下 ```json "extraResources": [ { "from": "node_modules/agora-electron-sdk-v4", "to": "app/node_modules/agora-electron-sdk-v4", "filter": ["**/*"] }, { "from": "node_modules/agora-electron-sdk-v4/node_modules", "to": "app/node_modules/agora-electron-sdk-v4/node_modules", "filter": ["**/*"] } ] ``` 同时,由于这个包是通过extraResources进行拷贝的,需要在签名脚本中额外配置这个包的路径。 另外在打包MacOS的包时有几个需要额外进行授权的可执行文件。建议通过额外的脚本来执行。下面的可执行文件是在安装@plasosdk/plaso-electron-sdk时动态下载的,因此授权的脚本需要保证是在文件下载之后。 ```shell // 截图会用到 chmod +x node_modules/@plasosdk/plaso-electron-sdk/lib/flameshot // 桌面共享会用到 chmod +x node_modules/@plasosdk/plaso-electron-sdk/lib/PlasoALD/PlasoALD.scpt ``` MacOS打包完毕后,建议安装打好的包后自行验证上述的操作时候生效了。 - 检查包内容中node_modules里面的agora-electron-sdk-v4包中是否包含node_modules,包含则说明打包正确。 - 上课测试截图功能是否正常,截图正常说明授权正确。 - 上课测试桌面共享功能,使用屏幕共享,并在浏览器里面播放一段视频,结束课堂后检查回放中能否听到桌面共享那一段播放的视频的声音,能听到说明授权正确。 ## 1.2、使用 ### 1.2.1、在主进程中使用 需要在主进程加载 `@plasosdk/plaso-electron-sdk` 依赖包 ```ts require('@plasosdk/plaso-electron-sdk'); // electron 版本>=14.0.0 时:需要在主进程里 初始化、启动 remote const electronVersion = process.versions['electron']; if (electronVersion && versionComp(electronVersion, '14.0.0') >= 0) { const electronStore = require('@electron/remote/main'); electronStore.initialize(); // mainWindow: 主进程打开的渲染进程窗口 electronStore.enable(mainWindow.webContents); } // 通过 initRemoteMain方法 传入 remoteMain const remoteMain = require('@electron/remote/main'); const { initRemoteMain } = require('@plasosdk/plaso-electron-sdk'); initRemoteMain(remoteMain); ``` ### 1.2.2、在渲染进程中使用 <a id="open-sdk-window-params"></a> **打开实时课堂/备课课堂方法入参类型定义** ```ts interface CreateClassPamras { classOptions: Object; electronWinOptions?: Electron.BrowserWindowConstructorOptions; onClassWindowReadyFn?: (winId: number) => void onClassWindowLeaveFn?: (winId: number) => void onClassFinishedFn?: (meetingId: string) => void; onSaveBoardFn?: ( params: { fileInfo: FileParams[]; fileName?: string; }, callback: (result: boolean) => void, ) => void; onOpenResourceCenterFn?: () => void; onGetExtFileNameFn?: (...args: any[]) => Promise<string>; } ``` #### 1.2.3.1、打开实时课堂 ```ts // 代码示例 const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk'); const createLiveClassParams: CreateClassPamras = { classOptions: { query } }; PlasoElectronSdk.createLiveClassWindow(createLiveClassParams); ``` 入参详见[实时课堂参数说明](#live-class-params) #### 1.2.3.2、打开备课课堂 ```ts // 代码示例 const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk'); const createPrepareClassParams: CreateClassPamras = { classOptions: { loginName: 'hello', userName: 'world' } }; PlasoElectronSdk.createPrepareClassWindow(createClassParams); ``` 入参详见[备课课堂入参说明](#prepare-class-params) <a id="live-class-params"></a> # 2、实时课堂入参说明 ## 2.1、参数 classOptions ``` 类型:Object ``` ### 2.1.1、属性列表 | 参数 | 是否必传 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | query | 是 | string | 无 | 进课堂必传字段,具体拼接逻辑见下文[query 属性说明](#query) | | displayAvatarUrl | 否 | string | 无 | 用户头像地址 | | classMembers | 否 | object[] | 无 | 1、课对应的班级用户信息<br />2、初始化课堂参与人<br /><br />3、最多支持 2000 人,需要支持更多学生需要联系伯索平台进行额外申请<br />{<br /><br />/** 唯一标识该用户的 id \*/<br />loginName: string,<br /><br />/** 用户显示的姓名 _/<br />name: string,<br />/\*\* 用户角色,"speaker","assistant","listener","superlistener" 之一 _/<br />upimeRole: string,<br />/** 用户的 id,和云学堂业务强相关,sdk 用户非必要 \*/<br />unique_id: number \| string<br />/** 用户头像图片的 url,非必要 \*/<br />displayAvatarUrl: string,<br />} | | enableENC | 否 | boolean | true | 是否启用降噪 | | enableRTC3A | 否 | boolean | true | 是否启用 3A。<br />false:关闭回音消除、关闭降噪、关闭增益控制 | | supportShowResourceCenter | 否 | boolean | false | true:工具栏显示 资料中心 按钮,但资料中心的逻辑需要用户自己实现 | | supportSaveBoard | 否 | boolean | false | 是否支持保存板书,依赖于资料中心实现保存和插入板书文件 | | enableLiveNewShareRegion | 否 | boolean | false | 是否允许区域共享 | | enableLiveNewShareInTouch | 否 | boolean | false | 是否支持触屏模式下的新桌面共享(左侧新增按钮窗口来切换显示工具栏)<br />建议开启 | | enableLiveNewShare | 否 | boolean | false | 是否支持新桌面共享<br />开启新桌面共享需要开启 electron 透明窗口,且可能触发 electron 本身存在的长时间透传导致的在应用上鼠标失焦问题 | | enableLiveSign | 否 | boolean | false | 是否支持签到 | | residentCamera | 否 | boolean | false | 常驻摄像头:只对学生或游客生效 | | | | | | | <a id="query"></a> ### 2.1.1、query 属性 **query 属性格式示例**: ``` appId=plaso&appType=liveclassSDK&d_dimension=1280x720&dhost=https%3A%2F%2Fdev.plaso.cn%2F&enableHiliter=true&enableNewClassExam=1&enableVideoMark=true&loginName=t_1&mediaType=video&meetingId=test_1742442362&meetingType=public&signature=A226198904A392579B98987FB4CD5478AB3F5587&upimeTeacherTool=1151&userName=%E8%80%81%E5%B8%881&userType=speaker&validBegin=1742442364&validTime=99999&vendorType=2&videoStream=2 ``` #### 2.1.1.1、组成 queryParams 对象 ```ts interface IQueryParams { appId: string; signature: string; validBegin: number; validTime: number; endTime: number; appType: string; userType: string; meetingType: string; mediaType: string; meetingId: string; loginName: string; userName: string; d_dimension: string; vendorType: number; videoStream: number; enableNewClassExam: number; d_enableReRecording: number; topic?: string; onlineMode?: number; d_enableOMO?: number; d_delayEndTimes?: number; d_delayEnd?: number; d_restrictAssistantPerm?: number; d_enableAvatarFreeScale?: number; d_enableObjectEraser?: number; d_vote?: number; d_sharpness?: number; isNewMT?: number; d_enableDualCamera?: number; } ``` ##### 2.1.1.1.1、必传参数表格说明 | 参数 | 类型 | 说明 | | --- | --- | --- | | appId | string | 在申请接入时,伯索平台给予的 appId | | signature | string | 签名字符串,根据queryParams中除去signature参数的其他参数生成,生成示例参考[根据queryParams对象生成签名字符串](#generate-signature) | | validBegin | number | 请求课堂**开始生效起始时间**的 Unix Epoch 时间戳,单位秒:(时间戳/1000 再取整) | | validTime | number | 请求的**签名在课堂的有效时间段**(断网重连后会重新校验签名),单位秒,建议: 24 _ 60 _ 60 s | | endTime | number | 请求课堂**结束时间**的 Unix Epoch 时间戳,单位秒:(时间戳/1000 再取整) | | appType | string | 应用类型,必填,目前为固定值:liveclassSDK | | userType | string | 用户类型,目前有三个值可选: speaker,assistant,listener; <br />speaker:主讲,有控制其他 listener 是否可写可说话的权限;<br />assistant:助教,也有控制权限<br />listener:学生 | | meetingType | string | 课堂类型,传入值:private。 当选择 private 类型时,每一个进入课堂者,必须提供 loginName,这是唯一标识该用户的 id,相同的 loginName 登录,后进入者会使前一个强制登出 | | mediaType | string | 媒体类型:audio, video<br />audio: 语音实时课堂<br />video:有头像权限的课堂,含语音权限 | | meetingId | string | 课堂 ID,唯一标识该课堂;使用 ASSIIC 字符,不得包含/,,空格等;长度在 40 字节以内的字符串 | | loginName | string | **唯一标识该用户的 id**,不能为空,相同的 loginName 登录,后面一个会使前面一个登出; | | d_dimension | string | 1280x720 定义界面尺寸为 16:9 界面 | | userName | string | 登录的用户名,在列表中显示用 | | vendorType | number | rtc 类型 <br />2:agora | | videoStream | number | 课堂类型,与 mediaType 需要对应上<br />2:视频课堂<br />1:语音课堂 | | enableNewClassExam | number | 新版随堂测选择题:1;<br />新版随堂测填空题:2;<br />新版随堂测选择+填空:3,建议:3 | | d_enableReRecording | number | 主讲、助教都可以重新录制课堂:3 | | | | | | | | | ##### 2.1.1.1.2、可选参数表格说明 | 参数 | 类型 | 默认值 | 建议值 | 说明 | | :-: | :-: | :-: | :-: | :-- | | topic | string | 无 | 非空 | 显示该课堂的名称 | | onlineMode | number | 6 | 无 | 上台学生数,1:最大上台 1 个学生,6:最大上台 6 个学生,12:最大上台 12 个学生。默认:6 | | d_enableOMO | number | 0 | 无 | 是否开启站播模式,1:开启;0:关闭 | | d_delayEndTimes | number | 0 | 无 | 单节课最大延迟下课次数:1234 | | d_delayEnd | number | 0 | 无 | 单次延时时间,单位秒:5*6010 * 6015*6020 * 6030\*60 | | d_restrictAssistantPerm | number | 0 | 无 | 是否开启了:大班课限制助教权限<br />1:开启<br />0:关闭 | | d_enableAvatarFreeScale | number | 0 | 无 | 开启头像任意比例缩放<br />0:关闭 1:开启,默认关闭 (非录制课堂、非无头像录制模式下,裁剪掉的老师/助教头像也会被录到回放中) | | d_enableObjectEraser | number | 0 | 无 | 新板书配置,二进制位存储<br />default: 0;默认关闭对象擦<br />7:手写(对象擦);<br /> | | d_vote | number | 0 | 1 | 0:未开放投票;1:开放投票 | | d_sharpness | number | 10 | 无 | 头像推流清晰度、桌面共享清晰度<br />**仅 onlineMode 为 1 时生效**:<br />10:标清 20:高清 21: 高清流畅 30:超清 31: 超清流畅 | | isNewMT | number | 0 | 1 | 是否支持 移动授课模式;<br />建议传 1 | | d_enableDualCamera | number | 0 | 无 | 是否开启双摄,1:开启,0: 关闭 | | recordType | number | 无 | 无 | 配置 recordAvartor 设置录制对象,参数说明参考[附录 9.1](#record-type) | | recordAvator | string | '' | 无 | 传入老师/助教的`loginName`表示录制对应人的头像 | | recordScreen | string | '' | 无 | 传入'screen'表示录制屏幕(当前仅支持录制老师屏幕)| | | | | | | <a id="generate-signature"></a> #### 2.1.1.2、根据 queryParams 对象生成签名字符串1)**用户把 queryParams 作为参数传给自己的接口,接口返回值必须返回签名字符串:signature** (2)获取 signature 后需要把 signature 加到 queryParams 中作为一个参数 ```ts queryParams.signature = signature; ``` (3)**服务端接口生成 signature 规则**如下: https://open.plaso.cn/doc-6285173?nav=01HEQ5Y5RXKMCPBPF6S8T3VK56 **signKey**:机构申请接入时,伯索平台给予的 key ```ts /*!----------演示签名代码------------- */ // 业务参数,根据接口文档中定义,自行生成填写 const queryParams = { name: 'test' }; //平台分配给机构的key const signKey = 'a_secret'; // 业务参数和签名验证混合后排序 const afterSortParam = Object.keys(queryParams).sort(); const res = []; for (let key of afterSortParam) { res.push(`${key}=${queryParams[key]}`); } // 排序后连接成字符串 const content = res.join('&'); const crypto = require('crypto'); // 使用分配的signKey来加密生成签名串signature const signature = crypto.createHmac('sha1', signKey).update(content).digest('hex').toUpperCase(); ``` #### 2.1.1.3、生成 query 字符串1)获取 完整的 queryParams 后,遍历对象生成 query 字符串 每个参数值用 encodeURIComponent 编码 ```ts // 代码示例:其中 queryParams 对象包含signature function genQuery(queryParams) { const keys = Object.keys(queryParams).sort(); const res = []; for (let key of keys) { res.push(key + '=' + encodeURIComponent(queryParams[key])); } return res.join('&'); } genQuery(queryParams); ``` <a id="prepare-class-params"></a> # 3、备课课堂入参说明 ## 3.1、参数 classOptions ``` 类型:Object ``` ### 3.1.1、必传参数 | 参数 | 类型 | 说明 | | --------- | ------ | ------------------------------------------------------------------------------------ | | loginName | String | **唯一标识该用户的 id**,不能为空,相同的 loginName 登录,后面一个会使前面一个登出; | | userName | String | 登录的用户名,在列表中显示用 | | | | | ### 3.1.2、可选参数 | 参数 | 类型 | 说明 | | --- | --- | --- | | displayAvatarUrl | String | 用户头像地址 | | topic | String | 默认值是中文的 “备课课堂” | | **d_enableObjectEraser** | number | 新板书配置,二进制位存储<br />default: 0;默认关闭对象擦<br />7:手写(对象擦);<br />**注意:该值需要和实时课堂的传值一样** | | | | | **注意:** 1、备课课堂直接通过任务栏关闭不会清空本地记录的板书内容,下次进入后会 板书交互会和上次进入的板书 配置一致(即使 d_enableObjectEraser 参数 值变动了) # 4、打开实时课堂/备课课堂通用参数说明 ## 4.1、参数 electronWinOptions > **即将弃用**: 不推荐传入,SDK内部默认设置了一些窗口参数,为了保证最佳体验,不要传入此参数。 Electron的窗口参数,详情参考 [Electron官方文档](https://www.electronjs.org/zh/docs/latest/api/browser-window#new-browserwindowoptions)。 ```ts type electronWinOptions = Electron.BrowserWindowConstructiorOptions; ``` ## 4.2、参数回调 onClassWindowReadyFn ```ts // 课堂窗口打开渲染成功后的回调,回调参数为 窗口id type onClassWindowReadyFn = (winId: number) => void; ``` ## 4.3、参数回调 onClassWindowLeaveFn ```ts // 课堂窗口关闭后的回调,回调参数为 窗口id type onClassWindowLeaveFn = (winId: number) => void; ``` ## 4.4、参数回调 onClassFinishedFn ```ts // 课堂结束后的回调,回调参数为 课堂的meetingId type onClassFinishedFn = (meetingId: string) => void; ``` ## 4.5、参数回调 onSaveBoardFn **注意:** 1、**filePath 对应的文件资源,用户保存在自己的云端时,需要把 本次保存的备课文件的 相关资源放在同一特定目录下** 2、**每次保存生成的备课文件 都放在一个新的目录下,不同的备课文件不能共用一个目录** 3、**备课保存的资源文件名 不能更改,info.pb 是固定的文件名** ```ts // 保存板书方法,具体的保存逻辑由外部实现,取消保存板书时,callback传false, 不然传true type FileParams = { /** 备课相关资源文件的本地地址*/ filePath: string[]; /** 备课文件 类型*/ fileType: 'png' | 'pb'; }; type onSaveBoardFn = ( params: { fileInfo: FileParams[]; fileName?: string; }, callback: (result: boolean) => void, ) => void; ``` ## 4.6、参数回调 onOpenResourceCenterFn ```ts // 通知外部用户打开自己的资料中心,资料中心的具体ui和逻辑由外部用户自己实现 // 推荐:通过onClassWindowReadyFn回调的winId拿到课堂窗口实例,用户的云盘通过一个BrowserWindow // 和课堂窗口组成父子窗口,云盘是子窗口,并且云盘窗口打开时保持置顶,这样来保证云盘打开时始终可见并且跟随课堂窗口。 type onOpenResourceCenterFn = () => void; ``` ## 4.7、参数回调 onGetExtFileNameFn ```ts // 通过 insertObject 插入的文件传入 参数 info 时,怎么从info中获取文件的可访问地址的逻辑在用户那,所以需要函数从外部用户获取外部用户传入的文件地址 // 其中info会作为args中的第一个参数回传 type onGetExtFileNameFn = (...args: any[]) => Promise<string>; ``` # 5、API参考 ## 5.1、PlasoElectronSdk.initLogConfig **初始化课堂窗口日志位置**,窗口崩溃时会在同级目录下生成 reports 文件夹存储 dump,**在 调用 createLiveClassWindow 前设置** **日志默认位置**: ```js require('path').join(require('electron').app.getPath('userData'), 'P403FileTemp'); // Windows:C:\Users\${userName}\AppData\Roaming\${appName}\P403FileTemp // Mac:/Users/${userName}/Application\ Support/${appName}/P403FileTemp ``` 参数示例: ```ts // 代码示例 const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk'); const logFilePath = 'C:/Users/userName/Desktop/electronDemo/electron12.0.18_x32/resources/app'; PlasoElectronSdk.initLogConfig(logFilePath); ``` ## 5.2、PlasoElectronSdk.getVersion 返回包的版本,格式:x.x.x ```ts type getVersion = () => string; ``` ## 5.3、PlasoElectronSdk.createLiveClassWindow **创建实时课堂窗口** ```ts function createLiveClassWindow(params: CreateClassPamras): void; ``` 参数详见[打开实时课堂/备课课堂方法入参类型定义](#open-sdk-window-params) ## 5.4、PlasoElectronSdk.createPrepareClassWindow **创建备课课堂窗口** ```ts function createLiveClassWindow(params: CreateClassPamras): void; ``` 参数详见[打开实时课堂/备课课堂方法入参类型定义](#open-sdk-window-params) ## 5.5、PlasoElectronSdk.insertObject 用户从自己的资料中心往**实时课堂/备课课堂**插入文件 ```ts // 插入的文件类型暴露在PlasoElectronSdk上,PlasoElectronSdk.FILE_TYPE const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk'); const enum FILE_TYPE { PPT, IMAGE, PDF, /** 这种模式需要用户实际传入的是WORD转成的PDF地址 */ WORD, /** 这种模式需要用户实际传入的是EXCEL转成的PDF地址 */ EXCEL, AUDIO, VIDEO, /** 这种模式传入真实WORD地址 */ DOC, /** 这种模式传入真实EXCEL地址 */ XLS, /** 备课文件 */ PREPARE_LESSONS, }; ``` ```ts /** 插入外部云盘里的文件,文件需要遵循特定的数据结构 */ /** * @typedef {Object} fileDataObj * @property {PlasoElectronSdk.FILE_TYPE} type 插入文件的格式,内容参考 PlasoElectronSdk.FILE_TYPE * @property {any[]} [info] 具体的文件信息数组,除备课外,内容都由用户自己定义 * @property {string} [title] 文件名称,需要带后缀 * @property {string} [url] 文件的可下载地址 */ /** * @param {fileDataObj} fileData 文件数据 */ type insertObject = (fileData) => void; // 使用方式 const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk'); PlasoElectronSdk.insertObject(fileData); ``` ### 5.5.1、插入备课文件 1、 插入 备课文件 的格式如下,其中 fileLocationPath 为 插入的备课文件资源的地址前缀,比如要本地插入一个备课文件(info.pb),其完整地址为 C:\Users\xxx\AppData\Roaming\plaso_sdk\prepareLessonsTemp\draft.swap\info.pb,则此时 fileLocationPath = C:\Users\xxx\AppData\Roaming\plaso_sdk\prepareLessonsTemp\draft.swap ```ts // 备课的fileData格式 const fileData = { type: PlasoElectronSdk.FILE_TYPE.PREPARE_LESSONS, info: ['pb', , , fileLocationPath], }; ``` **注意**: 1、**保存备课文件时,需要把 info.pb 和其他的图片文件放在同一个目录下,这样才可以通过一个 目录地址获取 备课的所有资源** ### 5.5.2、插入图片 1、**title 需要带有文件后缀名** ```ts // 图片的fileData格式,不需要info属性 const fileData = { type: PlasoElectronSdk.FILE_TYPE.IMAGE, title: 'xxxxxx.xxx', url: 'xxxxxx', }; ``` ### 5.5.3、插入 ppt ```ts // ppt的fileData格式,不需要info属性 const fileData = { type: PlasoElectronSdk.FILE_TYPE.PPT, title: 'xxxxxx', url: 'xxxxxx', }; ``` ### 5.5.4、插入 音视频 1、可以设置**url**属性为 公开可访问的音视频文件全路径, 2、或者设置**info**属性为表示文件信息的数组,可以通过 进课堂时传入的 **getExtFileName** 方法 可以获取文件有效路径 ```ts // audio、video 的fileData格式 const fileData = { type: PlasoElectronSdk.FILE_TYPE.AUDIO/.VIDEO, title: 'xxxxxx', url: 'xxxxxx', } 或 const fileData = { type: PlasoElectronSdk.FILE_TYPE.AUDIO/.VIDEO, title: 'xxxxxx', info: [xxxxxx], } ``` ### 5.5.5、插入 pdf、word、execl、doc、xls 1、可以设置 **url**属性 为公开可访问的 pdf、word、execl 文件全路径, 2、或者设置 **info**属性 为表示文件信息的数组,可以通过 进课堂时传入的 **getExtFileName** 方法 可以获取文件有效路径 ```ts // pdf、word、execl 的fileData格式,不需要info属性 const fileData = { type: PlasoElectronSdk.FILE_TYPE.PDF/.WORD/.EXCEL/.DOC/.XLS, title: 'xxxxxx', url: 'xxxxxx', } 或 const fileData = { type: PlasoElectronSdk.FILE_TYPE.PDF/.WORD/.EXCEL/.DOC/.XLS, title: 'xxxxxx', info: [xxxxxx], } ``` # 6、资料中心 step1、进课堂时,对象 **classOptions.supportShowResourceCenter** 需要是 true step2、在课堂内点击资料中心后,会触发进课堂时传入的回调函数 **onOpenResourceCenterFn**,此时用户在 onOpenResourceCenterFn 函数内打开自己的云盘 step3、选择号文件后,通过 **PlasoElectronSdk.insertObject** 方法插入文件,方法入参参考 insertObject 说明 step4、insertObject 方法 入参 有 info 时,此时 会触发进课堂时传入的回调函数 **onGetExtFileNameFn** 来获取文件的线上地址 # 7、历史课堂 1、参考文档: [历史课堂接入方式](https://open.plaso.cn/folder-24752679?nav=01HEQ5Y5RXKMCPBPF6S8T3VK56) 2、课堂里插入需要 调用 回调 onGetExtFileNameFn 方法的文件时,对应的历史课堂 则需要自己包装一层,具体逻辑参考 :**[播放历史课堂-jssdk 集成](https://open.plaso.cn/folder-24752679?nav=01HEQ5Y5RXKMCPBPF6S8T3VK56)** # 8、注意点1)用户的课堂外主窗口销毁时需要销毁课堂窗口 (2)electron 版本>=14.0.0 时:需要在主进程里 启动 remote ```ts try { const electronStore = require('@electron/remote/main'); electronStore.initialize(); // mainWindow 预期的渲染进程窗口 electronStore.enable(mainWindow.webContents); } catch (error) { console.error( 'Module not found', 'Please run `npm install @electron/remote` to enable remote module and update electron version to 22.0.0 or higher', ); } ``` (3)**基于 此包封装新包时**:注意 @electron/remote 这个包的位置需要 和新包处于同级目录,需要把 和该包同级的@electron/remote 移到新包的同级目录处 (4)确保 仅最后的 node_moudles 的顶层有 @electron/remote # 9、附录参数说明 <a id="record-type"></a> ## 9.1、RecordType | 值 | 说明 | | --- | ------------------------------- | | 1 | 无头像录制(仅录制板书) | | 2 | 录老师头像(录制老师头像+板书) | | 3 | 录助教头像(录制助教头像+板书) | | 4 | 录制课堂(录制整个屏幕和头像) | | 5 | 仅录老师头像 |