@plasosdk/plaso-electron-sdk 1.3.5 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +271 -274
- package/index.html +58 -8
- package/js/macro.js +4 -4
- package/js/render.js +9 -6
- package/package.json +1 -1
- package/scripts/downloadPrebuild.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,3 +5,9 @@
|
|
|
5
5
|
## [1.3.5](https://www.npmjs.com/package/@plasosdk/plaso-electron-sdk/v/1.3.5)(2025-08-21)
|
|
6
6
|
|
|
7
7
|
### 1. 移除了未使用的rtmpplayer和plasoffmpeg依赖
|
|
8
|
+
|
|
9
|
+
## [1.3.6](https://www.npmjs.com/package/@plasosdk/plaso-electron-sdk/v/1.3.6)(2025-08-29)
|
|
10
|
+
|
|
11
|
+
### 1. 音视频课堂增加常驻的禁麦提示
|
|
12
|
+
|
|
13
|
+
### 2. 优化本地麦克风音量波纹显示
|
package/README.md
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Plaso SDK for Electron
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- Windows 支持 x86、x64架构
|
|
3
|
+
## 🖥 环境支持
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
- 🌈 支持 MacOS x86-64 和 arm64
|
|
6
|
+
- ⚙️ 支持 Windows ia32 和 x64
|
|
7
|
+
- [Electron](https://www.electronjs.org/): 14.0.0~22.3.27
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
| MacOS | Windows | Electron |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| x86 \| arm64 | ia32 \| x64 | 14.0.0~22.3.27
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
## 安装
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
**安装 @electron/remote**
|
|
15
16
|
|
|
16
17
|
```shell
|
|
17
18
|
npm install @electron/remote --global-style --legacy-peer-deps
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
**安装 plaso-electron-sdk**
|
|
21
22
|
|
|
22
23
|
```shell
|
|
23
24
|
npm install @plasosdk/plaso-electron-sdk --global-style
|
|
@@ -26,69 +27,95 @@ npm install @plasosdk/plaso-electron-sdk --global-style
|
|
|
26
27
|
**<font color=red>注意: 不同平台需要单独安装,尤其是MacOS,请分别在Intel芯片和Apple芯片的电脑上安装</font>**
|
|
27
28
|
|
|
28
29
|
## electron-builder打包特别说明
|
|
29
|
-
|
|
30
|
+
|
|
31
|
+
### extraResources配置
|
|
32
|
+
|
|
33
|
+
> ⚠️ 注意:该配置在 1.3.7 版本有所调整。如果你正在从 < 1.3.7 升级到 >= 1.3.7,请参照下列说明进行调整。
|
|
34
|
+
|
|
35
|
+
agora-electron-sdk-v4包是在安装plaso-electron-sdk时通过脚本动态安装的,不在dependencies依赖树中,electron-builder打包时不会包含它。为了保留它,需要配置[extraResources](https://www.electron.build/configuration#extraresources)来单独拷贝一份,把它包含进来。
|
|
36
|
+
|
|
30
37
|
```json
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
{
|
|
39
|
+
"extraResources": [
|
|
40
|
+
{
|
|
41
|
+
"from": "node_modules/@plasosdk/plaso-electron-sdk/node_modules/agora-electron-sdk-v4",
|
|
42
|
+
"to": "app/node_modules/@plasosdk/plaso-electron-sdk/node_modules/agora-electron-sdk-v4",
|
|
43
|
+
"filter": [
|
|
44
|
+
"**/*"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"from": "node_modules/@plasosdk/plaso-electron-sdk/node_modules/agora-electron-sdk-v4/node_modules",
|
|
49
|
+
"to": "app/node_modules/@plasosdk/plaso-electron-sdk/node_modules/agora-electron-sdk-v4/node_modules",
|
|
50
|
+
"filter": [
|
|
51
|
+
"**/*"
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
43
56
|
```
|
|
57
|
+
|
|
44
58
|
同时,由于这个包是通过extraResources进行拷贝的,需要在签名脚本中额外配置这个包的路径。
|
|
45
59
|
|
|
46
|
-
|
|
60
|
+
### 关闭asar
|
|
61
|
+
|
|
62
|
+
需要关闭asar,否则SDK会无法加载到node_modules。关闭方式详见electron-buider[官方文档](https://www.electron.build/configuration#asar)。
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"asar": false, // 关闭asar
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### MacOS赋予文件执行权限
|
|
71
|
+
|
|
72
|
+
打MacOS的包时有几个需要额外进行授权的可执行文件。建议通过额外的脚本来执行。
|
|
73
|
+
|
|
74
|
+
下面的可执行文件是在安装@plasosdk/plaso-electron-sdk时动态下载的,因此授权的脚本需要保证是在文件下载之后。
|
|
75
|
+
|
|
47
76
|
```shell
|
|
48
77
|
// 截图会用到
|
|
49
|
-
chmod +x node_modules/@plasosdk/plaso-electron-sdk/lib/flameshot
|
|
78
|
+
chmod +x node_modules/@plasosdk/plaso-electron-sdk/lib/flameshot.app
|
|
50
79
|
|
|
51
80
|
// 桌面共享会用到
|
|
52
81
|
chmod +x node_modules/@plasosdk/plaso-electron-sdk/lib/PlasoALD/PlasoALD.scpt
|
|
53
82
|
```
|
|
54
83
|
|
|
55
|
-
|
|
84
|
+
### 验证
|
|
85
|
+
|
|
86
|
+
MacOS打包完毕后,建议安装打好的包,验证上述操作是否成功。核对清单:
|
|
56
87
|
- 检查包内容中node_modules里面的agora-electron-sdk-v4包中是否包含node_modules,包含则说明打包正确。
|
|
57
88
|
- 上课测试截图功能是否正常,截图正常说明授权正确。
|
|
58
89
|
- 上课测试桌面共享功能,使用屏幕共享,并在浏览器里面播放一段视频,结束课堂后检查回放中能否听到桌面共享那一段播放的视频的声音,能听到说明授权正确。
|
|
59
90
|
|
|
60
|
-
##
|
|
91
|
+
## 使用
|
|
61
92
|
|
|
62
|
-
###
|
|
93
|
+
### 在主进程中使用
|
|
63
94
|
|
|
64
95
|
需要在主进程加载 `@plasosdk/plaso-electron-sdk` 依赖包
|
|
65
96
|
|
|
66
97
|
```ts
|
|
67
|
-
require('@plasosdk/plaso-electron-sdk');
|
|
68
|
-
|
|
69
98
|
// electron 版本>=14.0.0 时:需要在主进程里 初始化、启动 remote
|
|
70
|
-
const electronVersion = process.versions['electron'];
|
|
71
|
-
if (electronVersion && versionComp(electronVersion, '14.0.0') >= 0) {
|
|
72
|
-
const electronStore = require('@electron/remote/main');
|
|
73
|
-
electronStore.initialize();
|
|
74
|
-
// mainWindow: 主进程打开的渲染进程窗口
|
|
75
|
-
electronStore.enable(mainWindow.webContents);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// 通过 initRemoteMain方法 传入 remoteMain
|
|
79
99
|
const remoteMain = require('@electron/remote/main');
|
|
100
|
+
remoteMain.initialize();
|
|
101
|
+
remoteMain.enable(mainWindow.webContents); // mainWindow: 主进程通过loadURL加载的那个渲染进程窗口
|
|
102
|
+
|
|
103
|
+
// plaso-electron-sdk中依赖@electron/remote,需要通过 initRemoteMain方法 传入 remoteMain
|
|
80
104
|
const { initRemoteMain } = require('@plasosdk/plaso-electron-sdk');
|
|
81
105
|
initRemoteMain(remoteMain);
|
|
82
106
|
```
|
|
83
107
|
|
|
84
|
-
###
|
|
108
|
+
### 在渲染进程中使用
|
|
85
109
|
|
|
86
110
|
<a id="open-sdk-window-params"></a>
|
|
87
111
|
|
|
88
112
|
**打开实时课堂/备课课堂方法入参类型定义**
|
|
89
113
|
```ts
|
|
90
|
-
interface
|
|
91
|
-
|
|
114
|
+
interface CreateClassWindowPamras {
|
|
115
|
+
/**
|
|
116
|
+
* 属性说明详见下方classOptions,打开实时课堂时为ILiveClassOptions,备课课堂为IPrepareClassOptions
|
|
117
|
+
*/
|
|
118
|
+
classOptions: ILiveClassOptions | IPrepareClassOptions;
|
|
92
119
|
electronWinOptions?: Electron.BrowserWindowConstructorOptions;
|
|
93
120
|
onClassWindowReadyFn?: (winId: number) => void
|
|
94
121
|
onClassWindowLeaveFn?: (winId: number) => void
|
|
@@ -105,242 +132,222 @@ interface CreateClassPamras {
|
|
|
105
132
|
}
|
|
106
133
|
```
|
|
107
134
|
|
|
108
|
-
####
|
|
109
|
-
|
|
110
|
-
```ts
|
|
111
|
-
// 代码示例
|
|
112
|
-
const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk');
|
|
113
|
-
const createLiveClassParams: CreateClassPamras = { classOptions: { query } };
|
|
114
|
-
PlasoElectronSdk.createLiveClassWindow(createLiveClassParams);
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
入参详见[实时课堂参数说明](#live-class-params)
|
|
135
|
+
#### 打开实时课堂
|
|
118
136
|
|
|
119
|
-
|
|
137
|
+
SDK打开一个新的`BrowserWindow`来加载实时课堂UI界面,示例代码如下:
|
|
120
138
|
|
|
121
139
|
```ts
|
|
122
|
-
// 代码示例
|
|
123
140
|
const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk');
|
|
124
|
-
const
|
|
125
|
-
PlasoElectronSdk.
|
|
141
|
+
const createLiveClassWindowParams: CreateClassWindowPamras = { classOptions: { query } };
|
|
142
|
+
PlasoElectronSdk.createLiveClassWindow(createLiveClassWindowParams);
|
|
126
143
|
```
|
|
127
144
|
|
|
128
|
-
|
|
145
|
+
##### createLiveClassWindow参数说明
|
|
129
146
|
|
|
147
|
+
###### classOptions
|
|
130
148
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
149
|
+
```ts
|
|
150
|
+
interface ILiveClassOptions {
|
|
151
|
+
/** 进入课堂必须的签名字符串 */
|
|
152
|
+
query: string;
|
|
153
|
+
/** 当前进入课堂用户的头像,取值为https全地址 */
|
|
154
|
+
displayAvatarUrl?: string;
|
|
155
|
+
/** 课堂中的成员,会在成员列表中呈现 */
|
|
156
|
+
classMembers?: UserInfo[];
|
|
157
|
+
/** 是否启用降噪 */
|
|
158
|
+
enableENC?: boolean;
|
|
159
|
+
/** 是否启用3A */
|
|
160
|
+
enableRTC3A?: boolean;
|
|
161
|
+
/** 是否启用新桌面共享 */
|
|
162
|
+
enableLiveNewShare?: boolean;
|
|
163
|
+
/** 是否启用触屏设备上的新桌面共享 */
|
|
164
|
+
enableLiveNewShareInTouch?: boolean;
|
|
165
|
+
/** 是否启用部分屏幕区域共享 */
|
|
166
|
+
enableLiveNewShareRegion?: boolean;
|
|
167
|
+
/** 是否启用签到 */
|
|
168
|
+
enableLiveSign?: boolean;
|
|
169
|
+
/** 是否启用资料中心(云盘) */
|
|
170
|
+
supportShowResourceCenter?: boolean;
|
|
171
|
+
/** 是否支持保存板书 */
|
|
172
|
+
supportSaveBoard?: boolean;
|
|
173
|
+
/** 是否启用摄像头常驻 */
|
|
174
|
+
residentCamera?: boolean;
|
|
175
|
+
}
|
|
135
176
|
|
|
136
|
-
|
|
137
|
-
|
|
177
|
+
interface UserInfo {
|
|
178
|
+
/** 用户名,唯一标识 */
|
|
179
|
+
loginName: string;
|
|
180
|
+
/** 用户昵称 */
|
|
181
|
+
name: string;
|
|
182
|
+
/** 用户角色 */
|
|
183
|
+
upimeRole: 'speaker' | 'assistant' | 'listener';
|
|
184
|
+
/** 用户头像 */
|
|
185
|
+
displayAvatarUrl?: string;
|
|
186
|
+
}
|
|
138
187
|
```
|
|
139
188
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
|
|
|
148
|
-
|
|
|
149
|
-
|
|
|
150
|
-
|
|
|
151
|
-
|
|
|
152
|
-
|
|
|
153
|
-
|
|
|
154
|
-
| enableLiveSign | 否 | boolean | false | 是否支持签到 |
|
|
155
|
-
| residentCamera | 否 | boolean | false | 常驻摄像头:只对学生或游客生效 |
|
|
156
|
-
| | | | | |
|
|
189
|
+
| <span style="white-space: nowrap;">参数名称</span> | <span style="white-space: nowrap;">是否必填</span> | <span style="white-space: nowrap;">类型</span> | <span style="white-space: nowrap;">参数描述</span> |
|
|
190
|
+
| --- | --- | --- | --- |
|
|
191
|
+
| query | 是 | string | 带签名的字符串,具体拼接逻辑见下文[query属性说明](#query) |
|
|
192
|
+
| displayAvatarUrl | 否 | string | 用户头像地址。不传默认使用用户昵称作为头像。 |
|
|
193
|
+
| classMembers | 否 | UserInfo[] | 成员列表中显示的人员,最多支持 2000 人。**人员超过2000人需要联系伯索平台进行额外申请**。 |
|
|
194
|
+
| enableRTC3A | 否 | boolean | 是否启用3A:回音消除、噪声抑制、自动增益控制。默认启用。 |
|
|
195
|
+
| enableENC | 否 | boolean | 是否启用降噪控制,开启后设置界面可以设置`基础降噪`或`增强降噪`。默认启用。 |
|
|
196
|
+
| enableLiveNewShare | 否 | boolean | 是否启用新桌面共享。启用后共享`屏幕`/`部分屏幕区域`时会对课堂窗口做透明化处理,需要选中工具栏上的`交互模式`工具来交互桌面应用,可能会触发`Electron`长时间透传鼠标事件导致的透传异常问题,谨慎使用。默认不启用。 |
|
|
197
|
+
| enableLiveNewShareInTouch | 否 | boolean | 是否在触屏设备上启用新桌面共享,启用后通过切换`演示模式`和`互动模式`来交互桌面应用和课堂中的工具。默认不启用。 |
|
|
198
|
+
| enableLiveNewShareRegion | 否 | boolean | 是否启用`部分屏幕区域`共享。 |
|
|
199
|
+
| enableLiveSign | 否 | boolean | 是否启用签到,启用后工具箱中显示`签到`按钮。默认不启用。 |
|
|
200
|
+
| supportShowResourceCenter | 否 | boolean | 是否启用`资料中心(云盘)`,启用后在工具栏显示`资料中心(云盘)`按钮,此按钮需要配合`onOpenResourceCenterFn`回调一起使用。默认不启用。 |
|
|
201
|
+
| supportSaveBoard | 否 | boolean | 是否启用保存板书,启用后工具箱中显示`保存当页板书`按钮,需要配合云盘使用。默认不启用。 |
|
|
202
|
+
| residentCamera | 否 | boolean | 是否启用常驻摄像头:只对学生或游客生效。启用后学生进入课堂后摄像头常驻开启,没有开启摄像头权限时也会开启。默认不启用。 |
|
|
157
203
|
|
|
158
204
|
<a id="query"></a>
|
|
159
|
-
|
|
205
|
+
**query属性说明**
|
|
160
206
|
|
|
161
|
-
|
|
207
|
+
query本质上是根据`IQueryParams`对象中的字段生成带签名的字符串,query示例如下:
|
|
162
208
|
|
|
163
|
-
```
|
|
164
|
-
appId=plaso&appType=liveclassSDK&d_dimension=1280x720&
|
|
209
|
+
```ts
|
|
210
|
+
const query = 'appId=plaso&appType=liveclassSDK&d_dimension=1280x720&enableNewClassExam=1&loginName=t_1&mediaType=video&meetingId=test_1742442362&meetingType=public&signature=A226198904A392579B98987FB4CD5478AB3F5587&userName=%E8%80%81%E5%B8%881&userType=speaker&validBegin=1742442364&validTime=99999'
|
|
165
211
|
```
|
|
166
212
|
|
|
167
|
-
#### 2.1.1.1、组成 queryParams 对象
|
|
168
|
-
|
|
169
213
|
```ts
|
|
170
214
|
interface IQueryParams {
|
|
171
215
|
appId: string;
|
|
172
|
-
signature: string;
|
|
173
216
|
validBegin: number;
|
|
174
217
|
validTime: number;
|
|
175
|
-
endTime: number;
|
|
176
|
-
appType: string;
|
|
177
|
-
userType: string;
|
|
178
|
-
meetingType: string;
|
|
179
218
|
mediaType: string;
|
|
219
|
+
meetingType: string;
|
|
180
220
|
meetingId: string;
|
|
221
|
+
userType: string;
|
|
181
222
|
loginName: string;
|
|
182
223
|
userName: string;
|
|
183
224
|
d_dimension: string;
|
|
184
|
-
vendorType: number;
|
|
185
|
-
videoStream: number;
|
|
186
|
-
enableNewClassExam: number;
|
|
187
|
-
d_enableReRecording: number;
|
|
188
225
|
|
|
189
226
|
topic?: string;
|
|
227
|
+
endTime?: number;
|
|
190
228
|
onlineMode?: number;
|
|
191
|
-
d_enableOMO?: number;
|
|
192
229
|
d_delayEndTimes?: number;
|
|
193
230
|
d_delayEnd?: number;
|
|
194
|
-
d_restrictAssistantPerm?: number;
|
|
195
231
|
d_enableAvatarFreeScale?: number;
|
|
196
232
|
d_enableObjectEraser?: number;
|
|
197
233
|
d_vote?: number;
|
|
198
234
|
d_sharpness?: number;
|
|
199
235
|
isNewMT?: number;
|
|
200
|
-
|
|
236
|
+
enableNewClassExam?: number;
|
|
237
|
+
d_enableReRecording?: number;
|
|
238
|
+
d_restrictAssistantPerm?: number;
|
|
201
239
|
}
|
|
202
240
|
```
|
|
203
241
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
|
207
|
-
|
|
|
208
|
-
|
|
|
209
|
-
|
|
|
210
|
-
|
|
|
211
|
-
|
|
|
212
|
-
|
|
|
213
|
-
|
|
|
214
|
-
|
|
|
215
|
-
|
|
|
216
|
-
|
|
|
217
|
-
|
|
|
218
|
-
|
|
|
219
|
-
|
|
|
220
|
-
|
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
|
|
|
224
|
-
|
|
|
225
|
-
|
|
|
226
|
-
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
| d_enableAvatarFreeScale | number | 0 | 无 | 开启头像任意比例缩放<br />0:关闭 1:开启,默认关闭 (非录制课堂、非无头像录制模式下,裁剪掉的老师/助教头像也会被录到回放中) |
|
|
239
|
-
| d_enableObjectEraser | number | 0 | 无 | 新板书配置,二进制位存储<br />default: 0;默认关闭对象擦<br />7:手写(对象擦);<br /> |
|
|
240
|
-
| d_vote | number | 0 | 1 | 0:未开放投票;1:开放投票 |
|
|
241
|
-
| d_sharpness | number | 10 | 无 | 头像推流清晰度、桌面共享清晰度<br />**仅 onlineMode 为 1 时生效**:<br />10:标清 20:高清 21: 高清流畅 30:超清 31: 超清流畅 |
|
|
242
|
-
| isNewMT | number | 0 | 1 | 是否支持 移动授课模式;<br />建议传 1 |
|
|
243
|
-
| d_enableDualCamera | number | 0 | 无 | 是否开启双摄,1:开启,0: 关闭 |
|
|
244
|
-
| recordType | number | 无 | 无 | 配置 recordAvartor 设置录制对象,参数说明参考[附录 9.1](#record-type) |
|
|
245
|
-
| recordAvator | string | '' | 无 | 传入老师/助教的`loginName`表示录制对应人的头像 |
|
|
246
|
-
| recordScreen | string | '' | 无 | 传入'screen'表示录制屏幕(当前仅支持录制老师屏幕)|
|
|
247
|
-
| | | | | |
|
|
248
|
-
|
|
249
|
-
<a id="generate-signature"></a>
|
|
250
|
-
#### 2.1.1.2、根据 queryParams 对象生成签名字符串
|
|
251
|
-
|
|
252
|
-
(1)**用户把 queryParams 作为参数传给自己的接口,接口返回值必须返回签名字符串:signature**
|
|
253
|
-
|
|
254
|
-
(2)获取 signature 后需要把 signature 加到 queryParams 中作为一个参数
|
|
242
|
+
| <span style="white-space: nowrap;">字段名称</span> | <span style="white-space: nowrap;">是否必填</span> | <span style="white-space: nowrap;">类型</span> | <span style="white-space: nowrap;">字段描述</span> |
|
|
243
|
+
| --- | --- | --- |--- |
|
|
244
|
+
| appId | 是 | string | 在申请接入时,伯索平台给予的 appId |
|
|
245
|
+
| validBegin | 是 | number | 签名query生效的起始时间,Unix Epoch 时间戳,单位为秒 |
|
|
246
|
+
| validTime | 是 | number | 签名query的有效期,从`validBegin`开始计算,单位为秒 |
|
|
247
|
+
| mediaType | 是 | string | 媒体类型,取值:<ul><li>audio: 音频课堂</li><li>video: 视频课堂</li></ul>
|
|
248
|
+
| meetingType | 是 | string | 课堂类型,固定值为`public` |
|
|
249
|
+
| meetingId | 是 | string | 课堂ID,唯一标识该课堂;使用ASSIIC字符,不得包含/,\,空格等;长度在40字节以内的字符串。 |
|
|
250
|
+
| userType | 是 | string | 用户角色类型,取值:<ul><li>speaker: 课堂的主讲者,有控制其他listener是否可板书/发言的权限。课堂中只能有一个主讲</li><li>assistant:助教,辅助主讲授课的角色,在课堂中的权限与主讲基本一致。课堂中可以有多个助教</li><li>listener:听众,可以理解为学生</li></ul> |
|
|
251
|
+
| loginName | 是 | string | 唯一标识该用户的id,不能为空,相同的loginName进入课堂时,后面进入的会使前面进入的登出 |
|
|
252
|
+
| userName | 是 | string | 用户昵称,头像缺省时会显示 |
|
|
253
|
+
| d_dimension | 是 | string | 固定值为`1280x720`,定义界面尺寸为16:9界面 |
|
|
254
|
+
| topic | 否 | string | 课堂名称,在标题栏上显示 |
|
|
255
|
+
| endTime | 否 | number | 课堂结束时间,格式为 Unix Epoch 时间戳,单位为秒 |
|
|
256
|
+
| onlineMode | 否 | number | 当mediaType为`video`时生效,表示最大能开启的`listener`的摄像头的个数,取值:<ul><li>1</li><li>6</li><li>12</li></ul>默认值为6 |
|
|
257
|
+
| d_delayEndTimes | 否 | number | 单节课最大延时下课次数,取值:<ul><li>1</li><li>2</li><li>3</li><li>4</li></ul>默认没有延时 |
|
|
258
|
+
| d_delayEnd | 否 | number | 单次延时时间,单位为秒,取值:<ul><li>5 * 60</li><li>10 * 60</li><li>20 * 60</li><li>30 * 60</li></ul>默认20分钟 |
|
|
259
|
+
| d_enableAvatarFreeScale | 否 | number | 是否开启头像任意比例缩放,仅上课中各端同步,录制头像时历史课堂不支持课堂调整的任意比例,取值:<ul><li>0:关闭</li><li>1:开启</li></ul>默认关闭 |
|
|
260
|
+
| d_enableObjectEraser | 否 | number | 是否启用新版板书,新版板书的橡皮擦支持对象擦除,传入大于0的值启用新版板书。取值:<ul><li>0: 不启用,橡皮功能为点擦</li><li>1: 支持对象擦除手写</li><li>3: 支持对象擦除手写+文本</li><li>5: 支持对象擦除手写+图形</li><li>7: 支持对象擦除手写+文本+图形</li></ul>默认不启用 |
|
|
261
|
+
| d_vote | 否 | number | 是否启用投票工具。取值:<ul><li>0:关闭</li><li>1:开启</li></ul>默认关闭 |
|
|
262
|
+
| d_sharpness | 否 | number | 当mediaType为`video`时生效,表示摄像头画面的清晰度。取值:<ul><li>10: 360p</li><li>20: 720p</li><li>30: 1080p</li></ul>默认值为10 |
|
|
263
|
+
| isNewMT | 否 | number | 是否支持移动授课模式,建议传1 |
|
|
264
|
+
| recordAvator | 否 | string | 传入老师或助教的`loginName`表示录制对应人的头像,传入`recordScreen`时SDK会忽略此参数 |
|
|
265
|
+
| recordScreen | 否 | string | 传入`screen`表示录制屏幕(当前仅支持录制老师屏幕)|
|
|
266
|
+
| enableNewClassExam | 否 | number | 是否启用新版随堂测,取值:<ul><li>0: 不启用</li><li>1: 启用选择题</li><li>2: 启用填空题</li><li>3: 启用选择题+填空题</li></ul>默认不启用,建议传3 |
|
|
267
|
+
| d_enableReRecording | 否 | number | 是否允许老师/助教重新录制,取值:<ul><li>0: 不允许老师和助教重新录制</li><li>1: 仅允许老师重新录制</li><li>2: 仅允许助教重新录制</li><li>3: 允许老师和助教重新录制</li></ul>默认值为3 |
|
|
268
|
+
| d_restrictAssistantPerm | 否 | number | 是否启用限制助教权限,取值:<ul><li>0: 不启用</li><li>1: 启用</li></ul>默认不启用 |
|
|
269
|
+
|
|
270
|
+
**根据 queryParams 对象生成签名字符串**
|
|
271
|
+
> 注意:为了安全和各端签名统一,建议将签名的计算放在服务端,前端通过接口获取带签名的query
|
|
272
|
+
|
|
273
|
+
将queryParams传入签名函数生成签名,签名示例参考:[签名示例](https://open.plaso.cn/doc-6285173?nav=01HEQ5Y5RXKMCPBPF6S8T3VK56)
|
|
274
|
+
|
|
275
|
+
获取`signature`后将`signature`加到`queryParams`中作为一个字段。
|
|
255
276
|
|
|
256
277
|
```ts
|
|
257
278
|
queryParams.signature = signature;
|
|
258
279
|
```
|
|
259
280
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
https://open.plaso.cn/doc-6285173?nav=01HEQ5Y5RXKMCPBPF6S8T3VK56
|
|
263
|
-
|
|
264
|
-
**signKey**:机构申请接入时,伯索平台给予的 key
|
|
281
|
+
获取完整的`queryParams`后,遍历`queryParams`生成`query`字符串,每个字段的值用`encodeURIComponent`编码。完整流程示例如下:
|
|
265
282
|
|
|
266
283
|
```ts
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
// 业务参数,根据接口文档中定义,自行生成填写
|
|
270
|
-
const queryParams = { name: 'test' };
|
|
271
|
-
|
|
272
|
-
//平台分配给机构的key
|
|
273
|
-
const signKey = 'a_secret';
|
|
274
|
-
|
|
275
|
-
// 业务参数和签名验证混合后排序
|
|
276
|
-
const afterSortParam = Object.keys(queryParams).sort();
|
|
277
|
-
|
|
278
|
-
const res = [];
|
|
279
|
-
for (let key of afterSortParam) {
|
|
280
|
-
res.push(`${key}=${queryParams[key]}`);
|
|
284
|
+
function genSignature(params) {
|
|
285
|
+
return 'xxx';
|
|
281
286
|
}
|
|
282
287
|
|
|
283
|
-
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
const crypto = require('crypto');
|
|
287
|
-
|
|
288
|
-
// 使用分配的signKey来加密生成签名串signature
|
|
289
|
-
const signature = crypto.createHmac('sha1', signKey).update(content).digest('hex').toUpperCase();
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
#### 2.1.1.3、生成 query 字符串
|
|
293
|
-
|
|
294
|
-
(1)获取 完整的 queryParams 后,遍历对象生成 query 字符串
|
|
295
|
-
|
|
296
|
-
每个参数值用 encodeURIComponent 编码
|
|
297
|
-
|
|
298
|
-
```ts
|
|
299
|
-
// 代码示例:其中 queryParams 对象包含signature
|
|
300
|
-
function genQuery(queryParams) {
|
|
301
|
-
const keys = Object.keys(queryParams).sort();
|
|
288
|
+
function genQuery(params) {
|
|
289
|
+
const keys = Object.keys(params).sort();
|
|
302
290
|
const res = [];
|
|
303
|
-
for (
|
|
304
|
-
res.push(key + '=' + encodeURIComponent(
|
|
291
|
+
for (const key of keys) {
|
|
292
|
+
res.push(key + '=' + encodeURIComponent(params[key]));
|
|
305
293
|
}
|
|
306
294
|
return res.join('&');
|
|
307
295
|
}
|
|
308
|
-
genQuery(queryParams);
|
|
309
|
-
```
|
|
310
296
|
|
|
311
|
-
|
|
312
|
-
|
|
297
|
+
const queryParams = {
|
|
298
|
+
appId: 'xxx';
|
|
299
|
+
validBegin: 175645206;
|
|
300
|
+
validTime: 3600;
|
|
301
|
+
mediaType: 'video';
|
|
302
|
+
meetingType: 'public';
|
|
303
|
+
meetingId: 1234;
|
|
304
|
+
userType: 'speaker';
|
|
305
|
+
loginName: 'hello';
|
|
306
|
+
userName: 'world';
|
|
307
|
+
d_dimension: '1280x720';
|
|
308
|
+
};
|
|
313
309
|
|
|
314
|
-
|
|
310
|
+
const signature = genSignature(queryParams);
|
|
311
|
+
queryParams.signature = signature;
|
|
315
312
|
|
|
316
|
-
|
|
317
|
-
类型:Object
|
|
313
|
+
const query = genQuery(queryParams);
|
|
318
314
|
```
|
|
319
315
|
|
|
320
|
-
|
|
316
|
+
#### 打开备课课堂
|
|
321
317
|
|
|
322
|
-
|
|
323
|
-
| --------- | ------ | ------------------------------------------------------------------------------------ |
|
|
324
|
-
| loginName | String | **唯一标识该用户的 id**,不能为空,相同的 loginName 登录,后面一个会使前面一个登出; |
|
|
325
|
-
| userName | String | 登录的用户名,在列表中显示用 |
|
|
326
|
-
| | | |
|
|
318
|
+
SDK打开一个新的`BrowserWindow`来加载备课课堂UI界面,示例代码如下:
|
|
327
319
|
|
|
328
|
-
|
|
320
|
+
```ts
|
|
321
|
+
const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk');
|
|
322
|
+
const createPrepareClassWindowParams: CreateClassWindowPamras = { classOptions: { loginName: 'hello', userName: 'world' } };
|
|
323
|
+
PlasoElectronSdk.createPrepareClassWindow(createPrepareClassWindowParams);
|
|
324
|
+
```
|
|
329
325
|
|
|
330
|
-
|
|
331
|
-
| --- | --- | --- |
|
|
332
|
-
| displayAvatarUrl | String | 用户头像地址 |
|
|
333
|
-
| topic | String | 默认值是中文的 “备课课堂” |
|
|
334
|
-
| **d_enableObjectEraser** | number | 新板书配置,二进制位存储<br />default: 0;默认关闭对象擦<br />7:手写(对象擦);<br />**注意:该值需要和实时课堂的传值一样** |
|
|
335
|
-
| | | |
|
|
326
|
+
##### createPrepareClassWindow参数说明
|
|
336
327
|
|
|
337
|
-
|
|
328
|
+
###### classOptions
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
interface IPrepareClassOptions {
|
|
332
|
+
loginName: string;
|
|
333
|
+
userName: string;
|
|
334
|
+
|
|
335
|
+
displayAvatarUrl?: string;
|
|
336
|
+
topic?: string;
|
|
337
|
+
d_enableObjectEraser?: number;
|
|
338
|
+
}
|
|
339
|
+
```
|
|
338
340
|
|
|
339
|
-
|
|
341
|
+
| <span style="white-space: nowrap;">参数名称</span> | <span style="white-space: nowrap;">是否必填</span> | <span style="white-space: nowrap;">类型</span> | <span style="white-space: nowrap;">参数描述</span> |
|
|
342
|
+
| --- | --- | --- | --- |
|
|
343
|
+
| loginName | 是 | string | 唯一标识该用户的id,不能为空,相同的loginName进入课堂时,后面进入的会使前面进入的登出 |
|
|
344
|
+
| userName | 是 | string | 用户昵称,头像缺省时会显示 |
|
|
345
|
+
| displayAvatarUrl | 否 | string | 用户头像地址。不传默认使用用户昵称作为头像。 |
|
|
346
|
+
| d_enableObjectEraser | 否 | number | 是否启用新版板书,新版板书的橡皮擦支持对象擦除,传入大于0的值启用新版板书。取值:<ul><li>0: 不启用,橡皮功能为点擦</li><li>1: 支持对象擦除手写</li><li>3: 支持对象擦除手写+文本</li><li>5: 支持对象擦除手写+图形</li><li>7: 支持对象擦除手写+文本+图形</li></ul>默认不启用 |
|
|
340
347
|
|
|
341
|
-
|
|
348
|
+
#### 打开实时课堂/备课课堂通用参数说明
|
|
342
349
|
|
|
343
|
-
|
|
350
|
+
##### electronWinOptions
|
|
344
351
|
|
|
345
352
|
> **即将弃用**: 不推荐传入,SDK内部默认设置了一些窗口参数,为了保证最佳体验,不要传入此参数。
|
|
346
353
|
|
|
@@ -350,29 +357,28 @@ Electron的窗口参数,详情参考 [Electron官方文档](https://www.electr
|
|
|
350
357
|
type electronWinOptions = Electron.BrowserWindowConstructiorOptions;
|
|
351
358
|
```
|
|
352
359
|
|
|
353
|
-
|
|
360
|
+
##### onClassWindowReadyFn
|
|
354
361
|
|
|
355
362
|
```ts
|
|
356
363
|
// 课堂窗口打开渲染成功后的回调,回调参数为 窗口id
|
|
357
364
|
type onClassWindowReadyFn = (winId: number) => void;
|
|
358
365
|
```
|
|
359
366
|
|
|
360
|
-
|
|
367
|
+
##### onClassWindowLeaveFn
|
|
361
368
|
|
|
362
369
|
```ts
|
|
363
370
|
// 课堂窗口关闭后的回调,回调参数为 窗口id
|
|
364
371
|
type onClassWindowLeaveFn = (winId: number) => void;
|
|
365
372
|
```
|
|
366
373
|
|
|
367
|
-
|
|
374
|
+
##### onClassFinishedFn
|
|
368
375
|
|
|
369
376
|
```ts
|
|
370
377
|
// 课堂结束后的回调,回调参数为 课堂的meetingId
|
|
371
378
|
type onClassFinishedFn = (meetingId: string) => void;
|
|
372
|
-
|
|
373
379
|
```
|
|
374
380
|
|
|
375
|
-
|
|
381
|
+
##### onSaveBoardFn
|
|
376
382
|
|
|
377
383
|
**注意:**
|
|
378
384
|
|
|
@@ -401,7 +407,7 @@ type onSaveBoardFn = (
|
|
|
401
407
|
) => void;
|
|
402
408
|
```
|
|
403
409
|
|
|
404
|
-
|
|
410
|
+
##### onOpenResourceCenterFn
|
|
405
411
|
|
|
406
412
|
```ts
|
|
407
413
|
// 通知外部用户打开自己的资料中心,资料中心的具体ui和逻辑由外部用户自己实现
|
|
@@ -410,7 +416,7 @@ type onSaveBoardFn = (
|
|
|
410
416
|
type onOpenResourceCenterFn = () => void;
|
|
411
417
|
```
|
|
412
418
|
|
|
413
|
-
|
|
419
|
+
##### onGetExtFileNameFn
|
|
414
420
|
|
|
415
421
|
```ts
|
|
416
422
|
// 通过 insertObject 插入的文件传入 参数 info 时,怎么从info中获取文件的可访问地址的逻辑在用户那,所以需要函数从外部用户获取外部用户传入的文件地址
|
|
@@ -419,31 +425,51 @@ type onOpenResourceCenterFn = () => void;
|
|
|
419
425
|
type onGetExtFileNameFn = (...args: any[]) => Promise<string>;
|
|
420
426
|
```
|
|
421
427
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
## 5.1、PlasoElectronSdk.initLogConfig
|
|
428
|
+
#### API参考
|
|
425
429
|
|
|
426
|
-
|
|
430
|
+
##### PlasoElectronSdk.initLogConfig
|
|
427
431
|
|
|
428
|
-
|
|
432
|
+
该方法用于设置SDK日志位置,SDK崩溃时会在同级目录下生成`reports`文件夹存储 dump,在调用`createLiveClassWindow`前设置,不调用SDK会在默认位置写入日志,默认位置如下:
|
|
429
433
|
|
|
430
434
|
```js
|
|
435
|
+
// 获取日志路径的代码如下
|
|
431
436
|
require('path').join(require('electron').app.getPath('userData'), 'P403FileTemp');
|
|
432
437
|
|
|
433
438
|
// Windows:C:\Users\${userName}\AppData\Roaming\${appName}\P403FileTemp
|
|
434
439
|
// Mac:/Users/${userName}/Application\ Support/${appName}/P403FileTemp
|
|
435
440
|
```
|
|
436
441
|
|
|
437
|
-
|
|
442
|
+
参考示例:
|
|
438
443
|
|
|
439
444
|
```ts
|
|
440
445
|
// 代码示例
|
|
441
446
|
const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk');
|
|
442
|
-
const
|
|
443
|
-
PlasoElectronSdk.initLogConfig(
|
|
447
|
+
const logDir = 'C:/Users/userName/Desktop/electronDemo/electron12.0.18_x32/resources/app';
|
|
448
|
+
PlasoElectronSdk.initLogConfig(logDir);
|
|
444
449
|
```
|
|
445
450
|
|
|
446
|
-
|
|
451
|
+
> 重要:用户需要对日志目录做定期清理和及时上传日志到自己的服务器或OSS。推荐在退出SDK后做一次清理和上传,建议清理创建时间超过7天的日志即可。
|
|
452
|
+
清理日志代码示例如下:
|
|
453
|
+
```ts
|
|
454
|
+
function clearExpireLog() {
|
|
455
|
+
// logDir为日志目录,即initLogConfig方法设置的路径或者SDK默认路径
|
|
456
|
+
const fs = require('fs');
|
|
457
|
+
const path = require('path');
|
|
458
|
+
const logFile = fs
|
|
459
|
+
.readdirSync(logDir)
|
|
460
|
+
.filter((fileName) => /\.(log|dmp)/.test(path.extname(fileName)));
|
|
461
|
+
logFile.forEach((fileName) => {
|
|
462
|
+
const fileInfo = fs.statSync(path.join(logDir, fileName));
|
|
463
|
+
const fileDate = new Date(fileInfo.birthtime).setHours(0, 0, 0, 0).valueOf();
|
|
464
|
+
const currentDate = new Date().setHours(0, 0, 0, 0);
|
|
465
|
+
if (currentDate - fileDate > 7 * 24 * 60 * 60 * 1000) {
|
|
466
|
+
fs.unlinkSync(path.join(logDir, fileName));
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
##### PlasoElectronSdk.getVersion
|
|
447
473
|
|
|
448
474
|
返回包的版本,格式:x.x.x
|
|
449
475
|
|
|
@@ -451,26 +477,26 @@ PlasoElectronSdk.initLogConfig(logFilePath);
|
|
|
451
477
|
type getVersion = () => string;
|
|
452
478
|
```
|
|
453
479
|
|
|
454
|
-
|
|
480
|
+
##### PlasoElectronSdk.createLiveClassWindow
|
|
455
481
|
|
|
456
482
|
**创建实时课堂窗口**
|
|
457
483
|
|
|
458
484
|
```ts
|
|
459
|
-
function createLiveClassWindow(params:
|
|
485
|
+
function createLiveClassWindow(params: CreateClassWindowPamras): void;
|
|
460
486
|
```
|
|
461
487
|
参数详见[打开实时课堂/备课课堂方法入参类型定义](#open-sdk-window-params)
|
|
462
488
|
|
|
463
|
-
|
|
489
|
+
##### PlasoElectronSdk.createPrepareClassWindow
|
|
464
490
|
|
|
465
491
|
**创建备课课堂窗口**
|
|
466
492
|
```ts
|
|
467
|
-
function createLiveClassWindow(params:
|
|
493
|
+
function createLiveClassWindow(params: CreateClassWindowPamras): void;
|
|
468
494
|
```
|
|
469
495
|
参数详见[打开实时课堂/备课课堂方法入参类型定义](#open-sdk-window-params)
|
|
470
496
|
|
|
471
497
|
<a id="insert-object"></a>
|
|
472
498
|
|
|
473
|
-
|
|
499
|
+
##### PlasoElectronSdk.insertObject
|
|
474
500
|
|
|
475
501
|
用户从自己的资料中心往**实时课堂/备课课堂**插入文件
|
|
476
502
|
|
|
@@ -532,7 +558,7 @@ const PlasoElectronSdk = window.require('@plasosdk/plaso-electron-sdk');
|
|
|
532
558
|
PlasoElectronSdk.insertObject(fileData);
|
|
533
559
|
```
|
|
534
560
|
|
|
535
|
-
|
|
561
|
+
###### 插入备课文件
|
|
536
562
|
|
|
537
563
|
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
|
|
538
564
|
|
|
@@ -549,7 +575,7 @@ const fileDataWithInfo = {
|
|
|
549
575
|
|
|
550
576
|
1、**保存备课文件时,需要把 info.pb 和其他的图片文件放在同一个目录下,这样才可以通过一个 目录地址获取 备课的所有资源**
|
|
551
577
|
|
|
552
|
-
|
|
578
|
+
###### 插入图片
|
|
553
579
|
|
|
554
580
|
```ts
|
|
555
581
|
// 图片可以通过url或info插入,当插入gif时,title需要带上.gif后缀
|
|
@@ -567,7 +593,7 @@ const fileDataWithInfo = {
|
|
|
567
593
|
};
|
|
568
594
|
```
|
|
569
595
|
|
|
570
|
-
|
|
596
|
+
###### 插入PPT
|
|
571
597
|
|
|
572
598
|
```ts
|
|
573
599
|
// PPT仅支持url插入
|
|
@@ -579,7 +605,7 @@ const fileDataWithUrl = {
|
|
|
579
605
|
};
|
|
580
606
|
```
|
|
581
607
|
|
|
582
|
-
|
|
608
|
+
###### 插入音视频
|
|
583
609
|
|
|
584
610
|
```ts
|
|
585
611
|
// 音视频可以通过url或info插入
|
|
@@ -598,7 +624,7 @@ const fileDataWithInfo = {
|
|
|
598
624
|
}
|
|
599
625
|
```
|
|
600
626
|
|
|
601
|
-
|
|
627
|
+
###### 插入PDF
|
|
602
628
|
```ts
|
|
603
629
|
// PDF可以通过url或info插入
|
|
604
630
|
|
|
@@ -616,7 +642,7 @@ const fileDataWithInfo = {
|
|
|
616
642
|
```
|
|
617
643
|
|
|
618
644
|
|
|
619
|
-
|
|
645
|
+
###### 插入WORD/EXCEL/DOC/XLS
|
|
620
646
|
|
|
621
647
|
```ts
|
|
622
648
|
// WORD/EXCEL/DOC/XLS仅支持url插入
|
|
@@ -628,7 +654,7 @@ const fileDataWithUrl = {
|
|
|
628
654
|
}
|
|
629
655
|
```
|
|
630
656
|
|
|
631
|
-
|
|
657
|
+
## 资料中心
|
|
632
658
|
|
|
633
659
|
step1、进课堂时,对象 **classOptions.supportShowResourceCenter** 需要是 true
|
|
634
660
|
|
|
@@ -638,45 +664,16 @@ step3、选择文件后,通过 **PlasoElectronSdk.insertObject** 方法插入
|
|
|
638
664
|
|
|
639
665
|
step4、insertObject 方法 入参 有 info 时,此时 会触发进课堂时传入的回调函数 **onGetExtFileNameFn** 来获取文件的全地址
|
|
640
666
|
|
|
641
|
-
|
|
667
|
+
## 播放历史课堂
|
|
642
668
|
|
|
643
669
|
1、参考文档: **[播放器SDK-Web播放器](https://open.plaso.cn/doc-6285192)**
|
|
644
670
|
|
|
645
671
|
2、当课堂中insertObject使用了`info`属性时,SDK内部需要外部传入`getExtFileName`,因此历史课堂需要使用jssdk的接入方式, 详见:**[Web播放器-jssdk接入](https://open.plaso.cn/doc-6285192#jssdk%E6%8E%A5%E5%85%A5)**
|
|
646
672
|
|
|
647
|
-
|
|
673
|
+
## 注意点
|
|
648
674
|
|
|
649
675
|
(1)用户的课堂外主窗口销毁时需要销毁课堂窗口
|
|
650
676
|
|
|
651
|
-
(2
|
|
652
|
-
|
|
653
|
-
```ts
|
|
654
|
-
try {
|
|
655
|
-
const electronRemote = require('@electron/remote/main');
|
|
656
|
-
electronRemote.initialize();
|
|
657
|
-
// mainWindow为app启动的渲染进程窗口
|
|
658
|
-
electronRemote.enable(mainWindow.webContents);
|
|
659
|
-
} catch (error) {
|
|
660
|
-
console.error(
|
|
661
|
-
'Module not found',
|
|
662
|
-
'Please run `npm install @electron/remote` to enable remote module and update electron version to 22.0.0 or higher',
|
|
663
|
-
);
|
|
664
|
-
}
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
(3)**基于 此包封装新包时**:注意 @electron/remote 这个包的位置需要 和新包处于同级目录,需要把 和该包同级的@electron/remote 移到新包的同级目录处
|
|
668
|
-
|
|
669
|
-
(4)确保 仅最后的 node_moudles 的顶层有 @electron/remote
|
|
670
|
-
|
|
671
|
-
# 9、附录参数说明
|
|
672
|
-
|
|
673
|
-
<a id="record-type"></a>
|
|
674
|
-
## 9.1、RecordType
|
|
677
|
+
(2)**基于 此包封装新包时**:注意 @electron/remote 这个包的位置需要 和新包处于同级目录,需要把 和该包同级的@electron/remote 移到新包的同级目录处
|
|
675
678
|
|
|
676
|
-
|
|
677
|
-
| --- | ------------------------------- |
|
|
678
|
-
| 1 | 无头像录制(仅录制板书) |
|
|
679
|
-
| 2 | 录老师头像(录制老师头像+板书) |
|
|
680
|
-
| 3 | 录助教头像(录制助教头像+板书) |
|
|
681
|
-
| 4 | 录制课堂(录制整个屏幕和头像) |
|
|
682
|
-
| 5 | 仅录老师头像 |
|
|
679
|
+
(3)确保 仅最后的 node_moudles 的顶层有 @electron/remote
|
package/index.html
CHANGED
|
@@ -137,14 +137,63 @@
|
|
|
137
137
|
document.head.appendChild(ele);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
let hasInit = false;
|
|
141
|
+
function init(appinfo) {
|
|
142
|
+
if (hasInit) {
|
|
143
|
+
return;
|
|
144
|
+
} else {
|
|
145
|
+
hasInit = true;
|
|
146
|
+
}
|
|
140
147
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (
|
|
144
|
-
|
|
148
|
+
// from url
|
|
149
|
+
var query;
|
|
150
|
+
if (window.location.search) {
|
|
151
|
+
query = window.location.search.substring(1).split("&");
|
|
152
|
+
for (var i = 0, l = query.length; i < l; i++) {
|
|
153
|
+
var temp = query[i].split('=');
|
|
154
|
+
if (temp.length == 2) {
|
|
155
|
+
globalAppInfo[temp[0]] = decodeURIComponent(temp[1]);
|
|
156
|
+
} else if (
|
|
157
|
+
typeof globalAppInfo[temp[0]] === 'string' &&
|
|
158
|
+
globalAppInfo[temp[0]].length > 0 &&
|
|
159
|
+
!isNaN(Number(globalAppInfo[temp[0]])) &&
|
|
160
|
+
Number(globalAppInfo[temp[0]]) !== undefined &&
|
|
161
|
+
!globalAppInfo[temp[0]]?.includes?.('.')
|
|
162
|
+
) {
|
|
163
|
+
globalAppInfo[temp[0]] = Number(globalAppInfo[temp[0]]);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// from ipc
|
|
169
|
+
if (appinfo) {
|
|
170
|
+
globalAppInfo = Object.assign({}, globalAppInfo, appinfo)
|
|
145
171
|
}
|
|
146
|
-
globalAppInfo.needFullScreen = false;
|
|
147
172
|
|
|
173
|
+
// properties init
|
|
174
|
+
if (globalAppInfo.rhost == undefined && location.protocol.indexOf('http') == 0) {
|
|
175
|
+
globalAppInfo.rhost = './';
|
|
176
|
+
if (!globalAppInfo.dhost) {
|
|
177
|
+
if (globalAppInfo.env) {
|
|
178
|
+
if (globalAppInfo.env === 'local') {
|
|
179
|
+
globalAppInfo.dhost = location.origin;
|
|
180
|
+
} else {
|
|
181
|
+
globalAppInfo.dhost = `${location.protocol}//${globalAppInfo.env}.plaso.cn/`;
|
|
182
|
+
}
|
|
183
|
+
} else if (location.origin.indexOf('plaso.cn') > -1) {
|
|
184
|
+
globalAppInfo.dhost = location.origin.replace('wwwr', 'www');
|
|
185
|
+
globalAppInfo.env = location.host.split('.')[0];
|
|
186
|
+
} else if (location.origin.indexOf('127.0.0.1') > -1 || location.origin.indexOf('192.168') > -1) {
|
|
187
|
+
globalAppInfo.env = 'dev';
|
|
188
|
+
globalAppInfo.dhost = `${location.protocol}//${globalAppInfo.env}.plaso.cn/`;
|
|
189
|
+
} else {
|
|
190
|
+
globalAppInfo.dhost = `${location.protocol}//www.plaso.cn/`;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (!globalAppInfo.env) globalAppInfo.env = 'www';
|
|
195
|
+
globalAppInfo.markString = globalAppInfo.markString ?? '';
|
|
196
|
+
globalAppInfo.needFullScreen = false;
|
|
148
197
|
if (globalAppInfo.rhost && globalAppInfo.rhost.substring(globalAppInfo.rhost.length - 1) != '/') {
|
|
149
198
|
globalAppInfo.rhost += "/";
|
|
150
199
|
}
|
|
@@ -152,6 +201,7 @@
|
|
|
152
201
|
globalAppInfo.dhost += "/";
|
|
153
202
|
}
|
|
154
203
|
|
|
204
|
+
// load all.js
|
|
155
205
|
path = globalAppInfo.initjs || "js/all.js";
|
|
156
206
|
include(path);
|
|
157
207
|
}
|
|
@@ -166,14 +216,14 @@
|
|
|
166
216
|
if (key === 'openerId') openerId = Number(value);
|
|
167
217
|
});
|
|
168
218
|
|
|
169
|
-
ipcRenderer.on(CLASS_WINDOW_MESG_TYPE.
|
|
170
|
-
if (
|
|
219
|
+
ipcRenderer.on(CLASS_WINDOW_MESG_TYPE.INIT_GLOBAL_APPINFO, (_, appinfo) => {
|
|
220
|
+
if (appinfo) init(appinfo);
|
|
171
221
|
});
|
|
172
222
|
|
|
173
223
|
if(openerId){
|
|
174
224
|
const remote = getElectronRemote();
|
|
175
225
|
const webContents = remote.getCurrentWebContents();
|
|
176
|
-
ipcRenderer.sendTo(openerId, CLASS_WINDOW_MESG_TYPE.
|
|
226
|
+
ipcRenderer.sendTo(openerId, CLASS_WINDOW_MESG_TYPE.HTML_READY, {webContentId: webContents.id});
|
|
177
227
|
}
|
|
178
228
|
|
|
179
229
|
}
|
package/js/macro.js
CHANGED
|
@@ -24,10 +24,10 @@ const CLASS_WINDOW_MESG_TYPE = {
|
|
|
24
24
|
LIVE_WINDOW_READY: 'liveWindowReady',
|
|
25
25
|
/** 课堂结束 */
|
|
26
26
|
ON_CLASS_FINISHED: 'onClassFinished',
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
|
|
27
|
+
/** 初始化 globalAppInfo */
|
|
28
|
+
INIT_GLOBAL_APPINFO: 'init_global_appinfo',
|
|
29
|
+
/** html ready */
|
|
30
|
+
HTML_READY: 'html_ready',
|
|
31
31
|
/** 保存白板文件 */
|
|
32
32
|
SAVE_BOARD: 'save_board',
|
|
33
33
|
/** 响应保存白板文件 */
|
package/js/render.js
CHANGED
|
@@ -108,7 +108,7 @@ function createClassWindow(classWindowProps) {
|
|
|
108
108
|
rhost = `https://${env}.plaso.cn/static/yxtelectronsdk/`;
|
|
109
109
|
dhost = `https://${env}.plaso.cn/`;
|
|
110
110
|
} else {
|
|
111
|
-
rhost = `https://wwwr.plaso.cn/static/sdk/styleupime/${classOptions.version ?? '1.
|
|
111
|
+
rhost = `https://wwwr.plaso.cn/static/sdk/styleupime/${classOptions.version ?? '1.59.201'}/`;
|
|
112
112
|
dhost = 'https://www.plaso.cn/';
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -143,6 +143,10 @@ function createClassWindow(classWindowProps) {
|
|
|
143
143
|
fullScreenable,
|
|
144
144
|
};
|
|
145
145
|
|
|
146
|
+
if (classOptionsObj.userType === 'monitor') {
|
|
147
|
+
classOptionsObj.monitor = true;
|
|
148
|
+
}
|
|
149
|
+
|
|
146
150
|
/**----------------------------------------------------electron 窗口相关设置-----------------------------------*/
|
|
147
151
|
|
|
148
152
|
const bounds = win.getBounds();
|
|
@@ -221,12 +225,12 @@ function createClassWindow(classWindowProps) {
|
|
|
221
225
|
logger.info(`课堂已结束,id:${currentWinId}, meetingId is ${meetingId}`);
|
|
222
226
|
if (onClassFinishedFn && currentWinId) onClassFinishedFn(meetingId);
|
|
223
227
|
};
|
|
224
|
-
const
|
|
228
|
+
const onHtmlReady = (event, value) => {
|
|
225
229
|
currentWebContentsId = value?.webContentId;
|
|
226
230
|
logger.info(`课堂窗口 html ready,web contents id:${currentWebContentsId}`);
|
|
227
231
|
|
|
228
232
|
if (currentWebContentsId) {
|
|
229
|
-
ipcRenderer.sendTo(currentWebContentsId, CLASS_WINDOW_MESG_TYPE.
|
|
233
|
+
ipcRenderer.sendTo(currentWebContentsId, CLASS_WINDOW_MESG_TYPE.INIT_GLOBAL_APPINFO, classOptionsObj);
|
|
230
234
|
}
|
|
231
235
|
};
|
|
232
236
|
const onSaveBoard = (event, value) => {
|
|
@@ -256,7 +260,7 @@ function createClassWindow(classWindowProps) {
|
|
|
256
260
|
|
|
257
261
|
ipcRenderer.on(CLASS_WINDOW_MESG_TYPE.LIVE_WINDOW_READY, onClassWindowReady);
|
|
258
262
|
ipcRenderer.on(CLASS_WINDOW_MESG_TYPE.ON_CLASS_FINISHED, onClassFinished);
|
|
259
|
-
ipcRenderer.on(CLASS_WINDOW_MESG_TYPE.
|
|
263
|
+
ipcRenderer.on(CLASS_WINDOW_MESG_TYPE.HTML_READY, onHtmlReady);
|
|
260
264
|
ipcRenderer.on(CLASS_WINDOW_MESG_TYPE.SAVE_BOARD, onSaveBoard);
|
|
261
265
|
ipcRenderer.on(CLASS_WINDOW_MESG_TYPE.OPEN_RESOURCE_CENTER, onOpenResourceCenter);
|
|
262
266
|
ipcRenderer.on(CLASS_WINDOW_MESG_TYPE.GET_EXT_FILE_NAME, onGetExtFileName);
|
|
@@ -289,7 +293,7 @@ function createClassWindow(classWindowProps) {
|
|
|
289
293
|
currentWebContentsId = null;
|
|
290
294
|
ipcRenderer.removeListener(CLASS_WINDOW_MESG_TYPE.LIVE_WINDOW_READY, onClassWindowReady);
|
|
291
295
|
ipcRenderer.removeListener(CLASS_WINDOW_MESG_TYPE.ON_CLASS_FINISHED, onClassFinished);
|
|
292
|
-
ipcRenderer.removeListener(CLASS_WINDOW_MESG_TYPE.
|
|
296
|
+
ipcRenderer.removeListener(CLASS_WINDOW_MESG_TYPE.HTML_READY, onHtmlReady);
|
|
293
297
|
ipcRenderer.removeListener(CLASS_WINDOW_MESG_TYPE.SAVE_BOARD, onSaveBoard);
|
|
294
298
|
ipcRenderer.removeListener(CLASS_WINDOW_MESG_TYPE.OPEN_RESOURCE_CENTER, onOpenResourceCenter);
|
|
295
299
|
ipcRenderer.removeListener(CLASS_WINDOW_MESG_TYPE.GET_EXT_FILE_NAME, onGetExtFileName);
|
|
@@ -322,7 +326,6 @@ function createLiveClassWindow(liveClassWindowProps) {
|
|
|
322
326
|
classOptions: {
|
|
323
327
|
...liveClassWindowProps.classOptions,
|
|
324
328
|
appType: 'liveclassSDK',
|
|
325
|
-
meetingType: 'private',
|
|
326
329
|
classType: LESSON_TYPE.LIVECLASS,
|
|
327
330
|
},
|
|
328
331
|
};
|
package/package.json
CHANGED
|
@@ -94,10 +94,10 @@ const npmInstall = () => {
|
|
|
94
94
|
installCb(agora_electron_sdk_v4, installAgora, error, stdout, stderr);
|
|
95
95
|
if (!error?.message) {
|
|
96
96
|
const oldAgoraV4Path = path.join(__dirname, '../node_modules', 'agora-electron-sdk');
|
|
97
|
-
const newAgoraV4Path = path.join(__dirname, '
|
|
97
|
+
const newAgoraV4Path = path.join(__dirname, '../node_modules', 'agora-electron-sdk-v4');
|
|
98
98
|
fs.move(oldAgoraV4Path, newAgoraV4Path, { overwrite: true }, (err) => {
|
|
99
99
|
if (!err) {
|
|
100
|
-
logger.info('
|
|
100
|
+
logger.info('命名agora_electron_sdk_v4成功');
|
|
101
101
|
}
|
|
102
102
|
});
|
|
103
103
|
}
|