@plasosdk/plaso-electron-sdk v1.1.7
支持的环境与electron版本
- macOs支持 x64 、arm64
- windows支持 ia32 、 x64
- electron支持 12.0.18~22.3.27
1、接入步骤
1.1、安装
前提:electron 版本 >=14.0.0, 需要install @electron/remote
npm install @electron/remote --global-style --legacy-peer-deps安装plaso-electron-sdk
npm install @plasosdk/plaso-electron-sdk --global-style注意: 不同平台需要单独安装
1.2、使用
1.2.1、npm包位置
将下载的npm包放到 应用本地的 node_modules目录下,一般是electron应用的 resources/app 目录下
1.2.2、主进程
主进程需要require包
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.3、渲染进程
1.2.3.1、打开 实时课堂
(1)调用方法:createLiveClassWindow
(2)入参参考: 2、实时课堂参数说明
1.2.3.2、打开备课课堂
(1)调用方法:createPrepareClassWindow
(2)入参参考:3、备课课堂参数说明
1.2.3.3、确定日志的写入位置
// 代码示例
const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk');
const logFilePath = "C:/Users/userName/Desktop/electronDemo/electron12.0.18_x32/resources/app";
PlasoElectronSdk.initLogConfig(logFilePath);1.2.3.4、创建 课堂/备课 窗口
// 代码示例
const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk');
const classObj = {};
//创建实时课堂
PlasoElectronSdk.createLiveClassWindow(classObj)
// or 创建备课课堂
PlasoElectronSdk.createPrepareClassWindow(classObj)2、实时课堂入参说明
2.1、参数classOptions
类型:Object2.1.1、参数 Table
| 参数 | 是否必传 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
| displayAvatarUrl | 否 | string | 无 | 用户头像地址 |
| classMembers | 否 | object[] | 无 | 1、课对应的班级用户信息2、初始化课堂参与人3、最多支持2000人,需要支持更多学生需要联系伯索平台进行额外申请{/ 唯一标识该用户的id */loginName: string,/ 用户显示的姓名 /name: string,/** 用户角色,"speaker","assistant","listener","superlistener" 之一 /upimeRole: string,/ 用户的id,和云学堂业务强相关,sdk用户非必要 */unique_id: number | string/ 用户头像图片的url,非必要 */displayAvatarUrl: string,} |
| enableENC | 否 | boolean | true | 是否启用降噪 |
| enableRTC3A | 否 | boolean | true | 是否启用3A。false:关闭回音消除、关闭降噪、关闭增益控制 |
| version | 是 | string | 无 | 正式使用时的线上对应的sdk版本,具体的版本需要在对接时确定,格式参考:1.53.901对接时一般不在线上环境测试,所以需要在classOptions里传入对应环境的 dhost、rhost,具体格式参考如下 |
| query | 是 | string | 无 | 进课堂必传字段,具体拼接逻辑见下文 |
| supportShowResourceCenter | 否 | boolean | false | true:显示资料中心,但核心的云盘和获取云盘文件地址的逻辑需要用户自己实现 |
| supportSaveBoard | 否 | boolean | false | 是否支持保存板书 |
| dhost | 否 | string | 无 | https://${environment}.plaso.cn/environment可选值:dev、test、itest、ftest |
| rhost | 否 | string | 无 | https://${environment}.plaso.cn/static/yxtsdk/environment可选值:dev、test、itest、ftest |
| enableLiveNewShareRegion | 否 | boolean | false | 是否允许区域共享 |
| enableLiveNewShareInTouch | 否 | boolean | false | 是否支持触屏模式下的新桌面共享(左侧新增按钮窗口来切换显示工具栏)建议开启 |
| enableLiveNewShare | 否 | boolean | false | 是否支持新桌面共享开启新桌面共享需要开启electron透明窗口,且可能触发electron本身存在的长时间透传导致的在应用上鼠标失焦问题 |
| enableLiveSign | 否 | boolean | false | 是否支持签到 |
| residentCamera | 否 | boolean | false | 常驻摄像头:只对学生或游客生效 |
2.1.1、query 参数 对应值的生成说明
2.1.1.1、组成 featureObj对象
对象的组成参数说明如下表格:
2.1.1.1.1、必传参数表格说明
| 参数 | 类型 | 说明 |
|---|---|---|
| appId | string | 在申请接入时,伯索平台给予的appId |
| validBegin | number | 请求课堂开始生效起始时间的Unix Epoch 时间戳,单位秒:(时间戳/1000再取整) |
| validTime | number | 请求的签名在课堂的有效时间段(断网重连后会重新校验签名),单位秒,建议: 24 60 60 s |
| endTime | number | 请求课堂结束时间的Unix Epoch 时间戳,单位秒:(时间戳/1000再取整) |
| appType | string | 应用类型,必填,目前为固定值:liveclassSDK |
| userType | string | 用户类型,目前有三个值可选: speaker,assistant,listener; speaker:主讲,有控制其他listener是否可写可说话的权限;assistant:助教,也有控制权限listener:学生 |
| meetingType | string | 课堂类型,传入值:private。 当选择private类型时,每一个进入课堂者,必须提供loginName,这是唯一标识该用户的id,相同的loginName登录,后进入者会使前一个强制登出 |
| mediaType | string | 媒体类型:audio, videoaudio: 语音实时课堂video:有头像权限的课堂,含语音权限 |
| meetingId | string | 课堂ID,唯一标识该课堂;使用ASSIIC字符,不得包含/,,空格等;长度在40字节以内的字符串 |
| loginName | string | 唯一标识该用户的id,不能为空,相同的loginName登录,后面一个会使前面一个登出; |
| d_dimension | string | 1280x720 定义界面尺寸为16:9 界面 |
| userName | string | 登录的用户名,在列表中显示用 |
| vendorType | number | rtc类型 2:agora |
| videoStream | number | 课堂类型,与mediaType需要对应上2:视频课堂1:语音课堂 |
| enableNewClassExam | number | 新版随堂测选择题:1;新版随堂测填空题:2;新版随堂测选择+填空:3,建议:3 |
| d_enableReRecording | number | 主讲、助教都可以重新录制课堂:3 |
2.1.1.1.2、可选参数表格说明
| 参数 | 类型 | 默认值 | 建议值 | 说明 |
|---|---|---|---|---|
| topic | string | 无 | 非空 | 显示该课堂的名称 |
| onlineMode | number | 6 | 无 | 上台学生数,默认:6 |
| d_enableOMO | number | 0 | 无 | 是否开启站播模式,1:开启;0:关闭 |
| d_delayEndTimes | number | 0 | 无 | 单节课最大延迟下课次数:1、2、3、4 |
| d_delayEnd | number | 0 | 无 | 单次延时时间,单位秒:560、10 60、1560、20 60、30*60 |
| d_restrictAssistantPerm | number | 0 | 无 | 是否开启了:大班课限制助教权限1:开启0:关闭 |
| d_enableAvatarFreeScale | number | 0 | 无 | 开启头像任意比例缩放0:关闭 1:开启,默认关闭 (非录制课堂、非无头像录制模式下,裁剪掉的老师/助教头像也会被录到回放中) |
| d_enableObjectEraser | number | 0 | 无 | 新板书配置,二进制位存储default: 0;默认关闭对象擦7:手写(对象擦); |
| d_vote | number | 0 | 1 | 0:未开放投票;1:开放投票 |
| d_sharpness | number | 10 | 无 | 头像推流清晰度、桌面共享清晰度仅onlineMode === 1 时生效:10:标清 20:高清 21: 高清流畅 30:超清 31: 超清流畅 |
| isNewMT | number | 0 | 1 | 是否支持 移动授课模式;建议传1 |
| d_enableDualCamera | number | 0 | 无 | 是否开启双摄,1:开启,0: 关闭 |
2.1.1.2、根据featureObj对象生成签名字符串
(1)用户把featureObj作为参数传给自己的接口,接口返回值必须返回签名字符串:signature
(2)获取signature后需要把 signature加到 featureObj 中作为一个参数
featureObj.signature = signature;(3)服务端接口生成 signature 规则如下:
https://open.plaso.cn/doc-6285173?nav=01HEQ5Y5RXKMCPBPF6S8T3VK56
signKey:机构申请接入时,伯索平台给予的key
/*!----------演示签名代码------------- */
// 业务参数,根据接口文档中定义,自行生成填写
const featureObj = {"name":"test"};
//平台分配给机构的key
const signKey = 'a_secret';
// 业务参数和签名验证混合后排序
const afterSortParam = Object.keys(featureObj).sort();
const res = []
for (let key of afterSortParam) {
res.push(`${key}=${featureObj[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)获取 完整的featureObj后,遍历对象生成query 字符串
每个参数值用 encodeURIComponent 编码
// 代码示例:其中featureObj对象包含signature
function genQuery(featureObj) {
const keys = Object.keys(featureObj).sort();
const res = [];
for (let key of keys) {
res.push(key + "=" + encodeURIComponent(featureObj[key]);
}
return res.join("&");
}
genQuery(featureObj)query字符串格式示例:
appId=plaso&appType=liveclassSDK&d_dimension=1280x720&dhost=https%3A%2F%2Fdev.plaso.cn%2F&enableHiliter=true&enableNewClassExam=1&enableVideoMark=true&env=dev&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.2、参数回调 onClassFinishedFn
// 课堂结束后的回调,回调参数为 课堂的meetingId
(meetingId: string)=>void3、备课课堂入参说明
3.1、参数classOptions
类型:Object3.1.1、必传参数
| 参数 | 类型 | 说明 |
|---|---|---|
| loginName | String | 唯一标识该用户的id,不能为空,相同的loginName登录,后面一个会使前面一个登出; |
| username | String | 登录的用户名,在列表中显示用 |
| version | String | 正式使用时的线上对应的sdk版本,具体的版本需要在对接时确定,格式参考:1.53.901对接时一般不在线上环境测试,所以需要在classOptions里传入对应环境的 dhost、rhost,具体格式参考 以下 可选参数中的说明 |
3.1.2、可选参数
| 参数 | 类型 | 说明 |
|---|---|---|
| displayAvatarUrl | String | 用户头像地址 |
| topic | String | 默认值是中文的 “备课课堂” |
| d_enableObjectEraser | number | 新板书配置,二进制位存储default: 0;默认关闭对象擦7:手写(对象擦);注意:该值需要和实时课堂的传值一样 |
| dhost | String | https://${environment}.plaso.cn/environment可选值:dev、test、itest、ftest |
| rhost | String | https://${environment}.plaso.cn/static/yxtsdk/environment可选值:dev、test、itest、ftest |
注意:
1、备课课堂直接通过任务栏关闭不会清空本地记录的板书内容,下次进入后会 板书交互会和上次进入的板书 配置一致(即使 d_enableObjectEraser 参数 值变动了)
4、实时课堂&备课课堂 通用参数说明
4.1、参数 electronWinOptions
electron 的窗口参数,详情参考 electron官方文档
type electronWinOptions = object;4.2、参数回调 onClassWindowReadyFn
// 课堂窗口打开渲染成功后的回调,回调参数为 窗口id
type onClassWindowReadyFn = (winId: number)=>void;4.3、参数回调 onClassWindowLeaveFn
// 课堂窗口关闭后的回调,回调参数为 窗口id
type onClassWindowLeaveFn = (winId: number)=>void;4.4、参数回调 onSaveBoardFn
注意:
1、filePath 对应的文件资源,用户保存在自己的云端时,需要把 本次保存的备课文件的 相关资源放在同一特定目录下
2、每次保存生成的备课文件 都放在一个新的目录下,不同的备课文件不能共用一个目录
3、备课保存的资源文件名 不能更改,info.pb 是固定的文件名
// 保存板书方法,具体的保存逻辑由外部实现,取消保存板书时,callback传false, 不然传true
type FileParams = {
/** 备课相关资源文件的本地地址*/
filePath: string[],
/** 备课文件 类型*/
fileType: 'png' | 'pb' | string
}
type onSaveBoardFn = (
params: {
fileInfo: FileParams[],
fileName?: string
},
callback: (result: boolean) => void
) => void;fileInfo 格式如下:

4.5、参数回调 onOpenResourceCenterFn
// 通知外部用户打开自己的资料中心,资料中心的具体ui和逻辑由外部用户自己实现
type onOpenResourceCenterFn = () => void;4.6、参数回调 onGetExtFileNameFn
// 通过 insertObject 插入的文件传入 参数 info 时,怎么从info中获取文件的可访问地址的逻辑在用户那,所以需要函数从外部用户获取外部用户传入的文件地址
type onGetExtFileNameFn = (info: any[])=>Promise<string>5、对外的交互方法
5.1、initLogConfig
初始化课堂窗口日志位置,窗口崩溃时会在同级目录下生成reports 文件夹存储dump,在 调用createLiveClassWindow 前设置
日志默认位置:
windows:C:\Users\${userName}\AppData\Roaming\${appName}\P403FileTemp
path.join(remote.app.getPath('userData'), '/P403FileTemp/')参数示例:
// 代码示例
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、getVersion
返回包的版本,格式:x.x.x
type getVersion = ()=>string;5.3、createLiveClassWindow
创建实时课堂窗口,入参参考 见 “2、实时课堂入参说明”
/**
* @typedef {Object} classOptionsType
* @property {boolean} [debug] - 是否开启课堂窗口debug模式
* @property {string} query - 进课堂的必备query
* @property {string} [version] - 格式参考:1.53.901
*/
/**
* @typedef {Object} FileParams
* @property {string[]} filePath - 备课文件本地地址
* @property {'png' | 'pb' | string} fileType
*/
/**
* @typedef {Object} classWindowType
* @property {classOptionsType} classOptions 进课堂参数对象
* @property {Object} [electronWinOptions] 自定义electron的窗口参数
* @property {(winId: number)=>void} [onClassWindowReadyFn] 课堂窗口打开渲染成功后的回调
* @property {(winId: number)=>void} [onClassWindowLeaveFn] 课堂窗口关闭后的回调
* @property {(meetingId: string)=>void} [onClassFinishedFn] 课堂结束后的回调
* @property {(
* params: {
* fileInfo: FileParams[],
* fileName?: string
* },
* callback: (result: boolean) => void
* ) => void} [onSaveBoardFn] 保存板书,具体的保存逻辑由外部实现,取消保存板书时,callback传false, 不然传true
* @property {()=>void} [onOpenResourceCenterFn] 通知外部用户打开自己的资料中心,资料中心的具体ui和逻辑由外部用户自己实现
*
*/
/**
* @param {classWindowType} classWindowProps
* @returns
*/
function createClassWindow(classWindowProps) {/**
* @typedef {Object} classOptionsType
* @property {boolean} [debug] - 是否开启课堂窗口debug模式
* @property {string} query - 进课堂的必备query,其中部分参数需要签名
*/
/**
* @typedef {Object} liveClassWindowType
* @property {classOptionsType} classOptions 进课堂参数对象
* @property {Object} [electronWinOptions] 自定义electron的窗口参数
* @property {(winId: number)=>void} [onClassWindowReadyCb] 课堂窗口打开渲染成功后的回调
* @property {()=>void} [onClassWindowLeaveCb] 课堂窗口关闭后的回调
* @property {()=>void} [onClassFinishedCb] 课堂结束后的回调
*/
/**
* @param {liveClassWindowType} liveClassWindowProps
* @returns
*/
function createLiveClassWindow({
classOptions,
electronWinOptions,
onClassWindowReadyCb,
onClassWindowLeaveCb,
onClassFinishedCb,
}){
......
}5.4、createPrepareClassWindow
创建备课课堂窗口,入参参考 见 “3、备课课堂入参说明”
参数详情 参考 createLiveClassWindow方法的说明5.5、insertObject
用户从自己的云盘 往 实时课堂/备课课堂 插入文件
/** 插入的文件类型 */
const FILE_TYPE = {
IMAGE: 2,
PDF: 3,
WORD: 4,
EXCEL: 5,
AUDIO: 6,
VIDEO: 7,
DOC: 14,
XLS: 15,
// ppt
NPPT:17,
// 备课文件
PREPARE_LESSONS: 22,
};/** 插入外部云盘里的文件,文件需要遵循特定的数据结构 */
/**
* @typedef {Object} fileDataObj
* @property {number} type 插入文件的格式,内容参考 FILE_TYPE
* @property {any[]} [info] 具体的文件信息数组,除备课外,内容都由用户自己定义
* @property {string} [title] 文件名称,需要带后缀
* @property {string} [url] 文件的可下载地址
*/
/**
* @param {string | number} winId 课堂id
* @param {fileDataObj} fileData 文件数据
*/
type insertObject = (webContentId, fileData) => void;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
// 备课的fileData格式
const fileData = {
type: 22,
info: ['pb', , , fileLocationPath]
}注意:
1、保存备课文件时,需要把 info.pb 和其他的图片文件放在同一个目录下,这样才可以通过一个 目录地址获取 备课的所有资源
5.5.2、插入图片
1、title 需要带有文件后缀名
// 图片的fileData格式,不需要info属性
const fileData = {
type: 2,
title: 'xxxxxx.xxx',
url: 'xxxxxx',
}5.5.3、插入ppt
// ppt的fileData格式,不需要info属性
const fileData = {
type: 17,
title: 'xxxxxx',
url: 'xxxxxx',
}5.5.4、插入 音视频
1、可以设置url属性为 公开可访问的音视频文件全路径,
2、或者设置info属性为表示文件信息的数组,可以通过 进课堂时传入的 getExtFileName 方法 可以获取文件有效路径
// audio、video 的fileData格式
const fileData = {
type: 6 或 7,
title: 'xxxxxx',
url: 'xxxxxx',
}
或
const fileData = {
type: 6 或 7,
title: 'xxxxxx',
info: [xxxxxx],
}5.5.5、插入 pdf、word、execl、doc、xls
1、可以设置 url属性 为公开可访问的 pdf、word、execl 文件全路径,
2、或者设置 info属性 为表示文件信息的数组,可以通过 进课堂时传入的 getExtFileName 方法 可以获取文件有效路径
// pdf、word、execl 的fileData格式,不需要info属性
const fileData = {
type: 3 或 4 或 5 或 14 或 15,
title: 'xxxxxx',
url: 'xxxxxx',
}
或
const fileData = {
type: 3 或 4 或 5 或 14 或 15,
title: 'xxxxxx',
info: [xxxxxx],
}6、资料中心
step1、进课堂时,对象 classOptions.supportShowResourceCenter 需要是 true
step2、在课堂内点击资料中心后,会触发进课堂时传入的回调函数 onOpenResourceCenterFn,此时用户在 onOpenResourceCenterFn函数内打开自己的云盘
step3、选择号文件后,通过 PlasoElectronSdk.insertObject 方法插入文件,方法入参参考 insertObject说明
step4、insertObject 方法 入参 有info 时,此时 会触发进课堂时传入的回调函数 onGetExtFileNameFn 来获取文件的线上地址
7、历史课堂
1、参考文档: 历史课堂接入方式
2、课堂里插入需要 调用 回调 onGetExtFileNameFn 方法的文件时,对应的历史课堂 则需要自己包装一层,具体逻辑参考 :播放历史课堂-jssdk集成
8、注意点
(1)用户的课堂外主窗口销毁时需要销毁课堂窗口
(2)electron 版本>=14.0.0 时:需要在主进程里 启动 remote
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 months ago
9 months ago
9 months ago
9 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago