fcr-core 3.10.2 → 3.11.0-rc.2
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/lib/imports.d.ts +7 -1
- package/lib/imports.js +27 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +14 -2
- package/lib/room-control/helpers/constants.d.ts +8 -0
- package/lib/room-control/helpers/constants.js +8 -0
- package/lib/room-control/index.js +145 -1
- package/lib/room-control/infinity-room-control/index.js +3 -4
- package/lib/room-control/mainroom-control/index.js +3 -4
- package/lib/room-control/privilege-control/index.js +22 -3
- package/lib/room-control/privilege-control/type.d.ts +20 -0
- package/lib/room-control/privilege-control/type.js +11 -1
- package/lib/room-control/type.d.ts +44 -0
- package/lib/room-control/user-control/index.js +32 -0
- package/lib/room-control/user-control/type.d.ts +24 -0
- package/lib/room-control/whiteboard-control-v2/base/index.js +9 -12
- package/lib/room-control/whiteboard-control-v2/base/main-window.d.ts +6 -0
- package/lib/room-control/whiteboard-control-v2/base/main-window.js +13 -3
- package/lib/room-control/whiteboard-control-v2/type.d.ts +5 -0
- package/lib/service/api.d.ts +15 -1
- package/lib/service/api.js +48 -0
- package/lib/utilities/parameters.js +17 -4
- package/lib-es/imports.js +6 -0
- package/lib-es/index.js +4 -0
- package/lib-es/media-control/desktop.js +1 -0
- package/lib-es/room-control/helpers/constants.js +8 -0
- package/lib-es/room-control/index.js +146 -2
- package/lib-es/room-control/infinity-room-control/index.js +3 -4
- package/lib-es/room-control/mainroom-control/index.js +3 -4
- package/lib-es/room-control/privilege-control/index.js +23 -4
- package/lib-es/room-control/privilege-control/type.js +10 -0
- package/lib-es/room-control/user-control/index.js +32 -0
- package/lib-es/room-control/whiteboard-control-v2/base/index.js +9 -12
- package/lib-es/room-control/whiteboard-control-v2/base/main-window.js +13 -3
- package/lib-es/service/api.js +48 -0
- package/lib-es/utilities/parameters.js +17 -4
- package/package.json +10 -8
package/lib/imports.d.ts
CHANGED
|
@@ -27,7 +27,13 @@ export { sleep, jsonstring, randomString } from 'agora-foundation/lib/utilities/
|
|
|
27
27
|
export { z, ZodError, anySchema, booleanSchema, numberSchema, stringSchema, fcrRenderViewSchema, unknownSchema, objectSchema, createRecordSchemaWithKey, createUnionSchema, createArraySchema, } from 'agora-foundation/lib/utilities/schema';
|
|
28
28
|
export { validateParams } from 'agora-foundation/lib/decorator/validate';
|
|
29
29
|
export { Mutex } from 'agora-foundation/lib/worker/mutex';
|
|
30
|
-
export type { AgoraRtcNetworkStats, AgoraRtcDeviceInfo, AgoraRtcDisplayInfo, AgoraRtcWindowInfo, AgoraRtePerformanceInfo, AgoraRteScenePropertiesDeletedEvent, AgoraRteStreamEncryptionConfig, AgoraRteStreamJoinConfig, AgoraRteDualVideoStreamConfig, AgoraRteMessage, AgoraRteScenePropertiesUpdatedEvent, AgoraRteRenderView, AgoraRteScene, } from 'agora-rte-sdk';
|
|
30
|
+
export type { AgoraRtcNetworkStats, AgoraRtcDeviceInfo, AgoraRtcDisplayInfo, AgoraRtcWindowInfo, AgoraRtePerformanceInfo, AgoraRteScenePropertiesDeletedEvent, AgoraRteStreamEncryptionConfig, AgoraRteStreamJoinConfig, AgoraRteDualVideoStreamConfig, AgoraRteMessage, AgoraRteScenePropertiesUpdatedEvent, AgoraRteRenderView, AgoraRteScene, AgoraRteClientRecordingConfig, AgoraRteClientRecordingObserver, AgoraRteRecorderInfo, } from 'agora-rte-sdk';
|
|
31
|
+
export { AgoraRteRecorderState, AgoraRteRecorderReasonCode } from 'agora-rte-sdk';
|
|
32
|
+
export type { AgoraRteClientRecordingConfig as FcrClientRecordingConfig } from 'agora-rte-sdk';
|
|
33
|
+
export type { AgoraRteClientRecordingObserver as FcrClientRecordingObserver } from 'agora-rte-sdk';
|
|
34
|
+
export type { AgoraRteRecorderInfo as FcrRecorderInfo } from 'agora-rte-sdk';
|
|
35
|
+
export { AgoraRteRecorderState as FcrRecorderState } from 'agora-rte-sdk';
|
|
36
|
+
export { AgoraRteRecorderReasonCode as FcrRecorderReasonCode } from 'agora-rte-sdk';
|
|
31
37
|
export type { AgoraRtmClient } from 'agora-rte-sdk/lib/core/rtm/client';
|
|
32
38
|
export type { AgoraRteEngineObserver } from 'agora-rte-sdk/lib/core/engine/type';
|
|
33
39
|
export type { AgoraRteNetworkQualityEvent } from 'agora-rte-sdk/lib/core/scene/type';
|
package/lib/imports.js
CHANGED
|
@@ -150,6 +150,18 @@ Object.defineProperty(exports, "AgoraRteMediaStreamType", {
|
|
|
150
150
|
return _type.AgoraRteMediaStreamType;
|
|
151
151
|
}
|
|
152
152
|
});
|
|
153
|
+
Object.defineProperty(exports, "AgoraRteRecorderReasonCode", {
|
|
154
|
+
enumerable: true,
|
|
155
|
+
get: function () {
|
|
156
|
+
return _agoraRteSdk.AgoraRteRecorderReasonCode;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
Object.defineProperty(exports, "AgoraRteRecorderState", {
|
|
160
|
+
enumerable: true,
|
|
161
|
+
get: function () {
|
|
162
|
+
return _agoraRteSdk.AgoraRteRecorderState;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
153
165
|
Object.defineProperty(exports, "AgoraRteRegion", {
|
|
154
166
|
enumerable: true,
|
|
155
167
|
get: function () {
|
|
@@ -294,6 +306,18 @@ Object.defineProperty(exports, "FcrRTMProvider_2_2", {
|
|
|
294
306
|
return _forgeRtm.RTMProvider_2_2;
|
|
295
307
|
}
|
|
296
308
|
});
|
|
309
|
+
Object.defineProperty(exports, "FcrRecorderReasonCode", {
|
|
310
|
+
enumerable: true,
|
|
311
|
+
get: function () {
|
|
312
|
+
return _agoraRteSdk.AgoraRteRecorderReasonCode;
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
Object.defineProperty(exports, "FcrRecorderState", {
|
|
316
|
+
enumerable: true,
|
|
317
|
+
get: function () {
|
|
318
|
+
return _agoraRteSdk.AgoraRteRecorderState;
|
|
319
|
+
}
|
|
320
|
+
});
|
|
297
321
|
Object.defineProperty(exports, "FcrRoom", {
|
|
298
322
|
enumerable: true,
|
|
299
323
|
get: function () {
|
|
@@ -587,9 +611,9 @@ var _misc = require("agora-foundation/lib/utilities/misc");
|
|
|
587
611
|
var _schema = require("agora-foundation/lib/utilities/schema");
|
|
588
612
|
var _validate = require("agora-foundation/lib/decorator/validate");
|
|
589
613
|
var _mutex = require("agora-foundation/lib/worker/mutex");
|
|
614
|
+
var _agoraRteSdk = require("agora-rte-sdk");
|
|
590
615
|
var _error = require("agora-rte-sdk/lib/core/utilities/error");
|
|
591
616
|
var _agoraError = require("agora-foundation/lib/utilities/error/agora-error");
|
|
592
|
-
var _agoraRteSdk = require("agora-rte-sdk");
|
|
593
617
|
var _type = require("agora-rte-sdk/lib/core/scene/type");
|
|
594
618
|
var _type2 = require("agora-rte-sdk/lib/core/rtc/type");
|
|
595
619
|
var _type3 = require("agora-rte-sdk/lib/type");
|
|
@@ -619,4 +643,6 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
619
643
|
|
|
620
644
|
// Agora RTE exports
|
|
621
645
|
|
|
646
|
+
// Fcr-prefixed re-exports for edu-core layer
|
|
647
|
+
|
|
622
648
|
const localStorage = exports.localStorage = window.localStorage;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export type { FcrDesktopMediaControl, FcrDesktopMediaObserver, FcrMobileMediaControl, FcrMobileMediaObserver, FcrMonitorControl, FcrMonitorObserver, FcrBaseRoomControl, FcrRoomObserver, FcrUserControl, FcrUserObserver, FcrStreamControl, FcrStreamObserver, FcrPrivilegeControl, FcrPermission, FcrBoardMainWindow, FcrBoardMainWindowObserver, FcrColor, } from './type';
|
|
2
|
+
export type { FcrClientRecordingConfig } from './imports';
|
|
3
|
+
export { FcrRecorderState, FcrRecorderReasonCode } from './imports';
|
|
2
4
|
export { FcrStreamLatencyLevel, FcrPermissionAction, FcrPrivilegeUserRole, FcrUserRole, FcrStreamState, FcrRegion, FcrStreamType, FcrUserUpdatedReason, FcrRoomConnectorType, FcrVideoSourceType, FcrAudioSourceType, FcrMediaSourceState, FcrVideoRenderMode, FcrVideoStreamType, FcrCapability, FcrAiDenoiseLevel, FcrStreamPrivilegeOperation, FcrStreamPrivilegeVideoSourceType, FcrStreamPrivilegeAudioSourceType, FcrConnectionState, registerPlugin, FcrBoardToolType, FcrBoardShape, FcrVideoEncoderConfig, FcrDualVideoStreamConfig, } from './type';
|
|
3
5
|
export { FcrCoreEngineImpl as FcrCoreEngine } from './engine';
|
|
4
6
|
export { FcrCoreEngineConfig } from './struct';
|
package/lib/index.js
CHANGED
|
@@ -87,6 +87,18 @@ Object.defineProperty(exports, "FcrPrivilegeUserRole", {
|
|
|
87
87
|
return _type.FcrPrivilegeUserRole;
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
|
+
Object.defineProperty(exports, "FcrRecorderReasonCode", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return _imports.FcrRecorderReasonCode;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, "FcrRecorderState", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () {
|
|
99
|
+
return _imports.FcrRecorderState;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
90
102
|
Object.defineProperty(exports, "FcrRegion", {
|
|
91
103
|
enumerable: true,
|
|
92
104
|
get: function () {
|
|
@@ -183,8 +195,8 @@ Object.defineProperty(exports, "registerPlugin", {
|
|
|
183
195
|
return _type.registerPlugin;
|
|
184
196
|
}
|
|
185
197
|
});
|
|
198
|
+
var _imports = require("./imports");
|
|
186
199
|
var _type = require("./type");
|
|
187
200
|
var _engine = require("./engine");
|
|
188
201
|
var _struct = require("./struct");
|
|
189
|
-
var _schema = require("./schema");
|
|
190
|
-
var _imports = require("./imports");
|
|
202
|
+
var _schema = require("./schema");
|
|
@@ -44,6 +44,14 @@ export declare const ROOM_MESSAGE_COMMANDS: {
|
|
|
44
44
|
readonly LIVE_STREAMING_UPDATE: 700;
|
|
45
45
|
/** 用户被踢出命令 */
|
|
46
46
|
readonly USER_KICK_OUT: 5;
|
|
47
|
+
/** 用户widget属性更新命令(widget属性变更的通用cause.cmd) */
|
|
48
|
+
readonly USER_WIDGET_PROPERTIES_UPDATE: 10;
|
|
49
|
+
/** 客户端录制权限变更(角色级, cause.cmd=3260) */
|
|
50
|
+
readonly CLIENT_RECORDING_PERMISSION: 3260;
|
|
51
|
+
/** 客户端录制状态变更 cause.data.widgetCause.cmd=3261 (通过widget属性下发) */
|
|
52
|
+
readonly CLIENT_RECORDING_STATE: 3261;
|
|
53
|
+
/** 用户权限变更(用户级,含客户端录制) */
|
|
54
|
+
readonly USER_PERMISSION_UPDATE: 3121;
|
|
47
55
|
/** 房间会话请求命令 */
|
|
48
56
|
readonly ROOM_SESSION_REQUEST: 1001;
|
|
49
57
|
/** 房间会话接受命令 */
|
|
@@ -53,6 +53,14 @@ const ROOM_MESSAGE_COMMANDS = exports.ROOM_MESSAGE_COMMANDS = {
|
|
|
53
53
|
LIVE_STREAMING_UPDATE: 700,
|
|
54
54
|
/** 用户被踢出命令 */
|
|
55
55
|
USER_KICK_OUT: 5,
|
|
56
|
+
/** 用户widget属性更新命令(widget属性变更的通用cause.cmd) */
|
|
57
|
+
USER_WIDGET_PROPERTIES_UPDATE: 10,
|
|
58
|
+
/** 客户端录制权限变更(角色级, cause.cmd=3260) */
|
|
59
|
+
CLIENT_RECORDING_PERMISSION: 3260,
|
|
60
|
+
/** 客户端录制状态变更 cause.data.widgetCause.cmd=3261 (通过widget属性下发) */
|
|
61
|
+
CLIENT_RECORDING_STATE: 3261,
|
|
62
|
+
/** 用户权限变更(用户级,含客户端录制) */
|
|
63
|
+
USER_PERMISSION_UPDATE: 3121,
|
|
56
64
|
/** 房间会话请求命令 */
|
|
57
65
|
ROOM_SESSION_REQUEST: 1001,
|
|
58
66
|
/** 房间会话接受命令 */
|
|
@@ -24,7 +24,9 @@ require("core-js/modules/es.array.includes.js");
|
|
|
24
24
|
require("core-js/modules/es.array.push.js");
|
|
25
25
|
require("core-js/modules/es.json.stringify.js");
|
|
26
26
|
require("core-js/modules/esnext.iterator.constructor.js");
|
|
27
|
+
require("core-js/modules/esnext.iterator.find.js");
|
|
27
28
|
require("core-js/modules/esnext.iterator.for-each.js");
|
|
29
|
+
require("core-js/modules/esnext.iterator.some.js");
|
|
28
30
|
var _imports = require("../imports");
|
|
29
31
|
var _type = require("../type");
|
|
30
32
|
var _type2 = require("./type");
|
|
@@ -68,7 +70,7 @@ function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side
|
|
|
68
70
|
*/
|
|
69
71
|
class FcrBaseRoomControlImpl {
|
|
70
72
|
static {
|
|
71
|
-
[_initProto] = _applyDecs(this, [[_imports.trace, 2, "getSyncTimestamp"], [_imports.trace, 2, "getRoomInfo"], [_imports.trace, 2, "getRoomSchedule"], [_imports.trace, 2, "getLocalExDataSyncTypeList"], [_joinDecs, 2, "join"], [_imports.trace, 2, "leave"], [_imports.trace, 2, "release"], [_imports.trace, 2, "start"], [_imports.trace, 2, "end"], [_imports.trace, 2, "close"], [_imports.trace, 2, "getRoomState"], [_imports.trace, 2, "getRoomProperties"], [_imports.trace, 2, "getRoomPropertiesByKeyPath"], [_updateRoomPropertiesDecs, 2, "updateRoomProperties"], [_updateIncrementRoomPropertiesDecs, 2, "updateIncrementRoomProperties"], [_deleteRoomPropertiesDecs, 2, "deleteRoomProperties"], [_startCloudRecordingDecs, 2, "startCloudRecording"], [_imports.trace, 2, "pauseCloudRecording"], [_imports.trace, 2, "resumeCloudRecording"], [_imports.trace, 2, "stopCloudRecording"], [_imports.trace, 2, "getLiveStreamingState"], [_imports.trace, 2, "getLiveStreamingConfig"], [_startLiveStreamingDecs, 2, "startLiveStreaming"], [_updateLiveStreamingLayoutDecs, 2, "updateLiveStreamingLayout"], [_imports.trace, 2, "stopLiveStreaming"], [_imports.trace, 2, "getCloudRecordingState"], [_sendRoomMessageDecs, 2, "sendRoomMessage"]], []).e;
|
|
73
|
+
[_initProto] = _applyDecs(this, [[_imports.trace, 2, "getSyncTimestamp"], [_imports.trace, 2, "getRoomInfo"], [_imports.trace, 2, "getRoomSchedule"], [_imports.trace, 2, "getLocalExDataSyncTypeList"], [_joinDecs, 2, "join"], [_imports.trace, 2, "leave"], [_imports.trace, 2, "release"], [_imports.trace, 2, "start"], [_imports.trace, 2, "end"], [_imports.trace, 2, "close"], [_imports.trace, 2, "getRoomState"], [_imports.trace, 2, "getRoomProperties"], [_imports.trace, 2, "getRoomPropertiesByKeyPath"], [_updateRoomPropertiesDecs, 2, "updateRoomProperties"], [_updateIncrementRoomPropertiesDecs, 2, "updateIncrementRoomProperties"], [_deleteRoomPropertiesDecs, 2, "deleteRoomProperties"], [_startCloudRecordingDecs, 2, "startCloudRecording"], [_imports.trace, 2, "pauseCloudRecording"], [_imports.trace, 2, "resumeCloudRecording"], [_imports.trace, 2, "stopCloudRecording"], [_imports.trace, 2, "startClientRecording"], [_imports.trace, 2, "resumeClientRecording"], [_imports.trace, 2, "stopClientRecording"], [_imports.trace, 2, "getLiveStreamingState"], [_imports.trace, 2, "getLiveStreamingConfig"], [_startLiveStreamingDecs, 2, "startLiveStreaming"], [_updateLiveStreamingLayoutDecs, 2, "updateLiveStreamingLayout"], [_imports.trace, 2, "stopLiveStreaming"], [_imports.trace, 2, "hasActiveClientRecording"], [_imports.trace, 2, "getCloudRecordingState"], [_sendRoomMessageDecs, 2, "sendRoomMessage"]], []).e;
|
|
72
74
|
}
|
|
73
75
|
//@internal
|
|
74
76
|
[(_joinDecs = (0, _imports.trace)(['options']), _updateRoomPropertiesDecs = (0, _imports.trace)(['properties', 'cause']), _updateIncrementRoomPropertiesDecs = (0, _imports.trace)(['increments', 'cause']), _deleteRoomPropertiesDecs = (0, _imports.trace)(['properties', 'cause']), _startCloudRecordingDecs = (0, _imports.trace)(['config']), _startLiveStreamingDecs = (0, _imports.trace)(['data']), _updateLiveStreamingLayoutDecs = (0, _imports.trace)(['layoutType']), _sendRoomMessageDecs = (0, _imports.trace)(['payload', 'guaranteedDelivery']), "logger")] = (_initProto(this), (0, _logger.createLogger)({
|
|
@@ -78,6 +80,8 @@ class FcrBaseRoomControlImpl {
|
|
|
78
80
|
_joinRoomSuccess = false;
|
|
79
81
|
_joining = false;
|
|
80
82
|
_joinState = _helpers.ROOM_CONTROL_CONSTANTS.JOIN_STATE.CANCELED;
|
|
83
|
+
_isClientRecordingOwner = false;
|
|
84
|
+
_isStartingClientRecording = false;
|
|
81
85
|
constructor(_engine, _scene, _api, _config, _roomType, _chatConnection, _sharedCache, _chatRoomControl) {
|
|
82
86
|
this._engine = _engine;
|
|
83
87
|
this._scene = _scene;
|
|
@@ -226,8 +230,45 @@ class FcrBaseRoomControlImpl {
|
|
|
226
230
|
this._joinState = _helpers.ROOM_CONTROL_CONSTANTS.JOIN_STATE.CANCELED;
|
|
227
231
|
this._cleanup();
|
|
228
232
|
}
|
|
233
|
+
// Handle user-level local recording permission change (cmd=3121)
|
|
234
|
+
if (event.cause?.cmd === _helpers.ROOM_MESSAGE_COMMANDS.USER_PERMISSION_UPDATE && event.modifiedUser.userId === this._scene.localUser.getLocalUserId()) {
|
|
235
|
+
const causeData = event.cause?.data;
|
|
236
|
+
if (causeData?.removePermissions?.includes('record:startClientRecording')) {
|
|
237
|
+
if (this.isLocalClientRecordingActive()) {
|
|
238
|
+
this.stopClientRecording().catch(e => {
|
|
239
|
+
this.logger.error(`auto-stop client recording failed: ${e.message}`);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// 初始化客户端录制观察者
|
|
248
|
+
this._clientRecordingObserver = {
|
|
249
|
+
onRecorderStateChanged: (_channelId, _uid, state, reason) => {
|
|
250
|
+
this.logger.info(`onRecorderStateChanged: state=${state}, reason=${reason}, sceneId=${this._scene.sceneId}`);
|
|
251
|
+
this._observable.notifyObservers('onClientRecordingStateChanged', this._scene.sceneId, state, reason);
|
|
229
252
|
}
|
|
230
253
|
};
|
|
254
|
+
|
|
255
|
+
// 客户端录制观察者由子类(FcrMainRoomControlImpl)注册,基类不注册
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* 注册客户端录制观察者。由主房间子类在构造时调用。
|
|
260
|
+
*/
|
|
261
|
+
_registerClientRecordingObserver() {
|
|
262
|
+
this._engine.getMediaControl().addClientRecordingObserver(this._clientRecordingObserver);
|
|
263
|
+
this._isClientRecordingOwner = true;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* 移除客户端录制观察者。由 _cleanup 调用时需要判断是否已注册。
|
|
268
|
+
*/
|
|
269
|
+
_unregisterClientRecordingObserver() {
|
|
270
|
+
this._engine.getMediaControl().removeClientRecordingObserver(this._clientRecordingObserver);
|
|
271
|
+
this._isClientRecordingOwner = false;
|
|
231
272
|
}
|
|
232
273
|
|
|
233
274
|
/**
|
|
@@ -574,6 +615,89 @@ class FcrBaseRoomControlImpl {
|
|
|
574
615
|
await (0, _error.handleRequestError)(() => this._api.stopCloudRecording(this._scene.sceneId), _imports.ErrorModuleCode.FCR_ROOM, 'stop cloud recording failed');
|
|
575
616
|
return _type.FcrReturnCode.SUCCESS;
|
|
576
617
|
}
|
|
618
|
+
async startClientRecording(config) {
|
|
619
|
+
// 防止并发调用
|
|
620
|
+
if (this._isStartingClientRecording) {
|
|
621
|
+
this.logger.warn('startClientRecording: already starting, ignoring duplicate call');
|
|
622
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
623
|
+
}
|
|
624
|
+
const localUserId = this._scene.localUser.getLocalUserId();
|
|
625
|
+
|
|
626
|
+
// 标记正在启动本地录制,避免在 API 调用后、SDK 录制开始前的时间窗口内触发错误的提示
|
|
627
|
+
this._isStartingClientRecording = true;
|
|
628
|
+
let serverRecordingStarted = false;
|
|
629
|
+
try {
|
|
630
|
+
await (0, _error.handleRequestError)(() => this._api.startClientRecording(this._scene.sceneId, localUserId), _imports.ErrorModuleCode.FCR_ROOM, 'start client recording failed');
|
|
631
|
+
serverRecordingStarted = true;
|
|
632
|
+
|
|
633
|
+
// 使用 mediaControl 来启动本地录制
|
|
634
|
+
const mediaControl = this._engine.getMediaControl();
|
|
635
|
+
const isScreenShareActive = mediaControl.isScreenShareActive();
|
|
636
|
+
const currentScreenShareSourceId = mediaControl.getCurrentScreenShareSourceId();
|
|
637
|
+
|
|
638
|
+
// 获取本地用户的主流 streamId 作为录制 uid(streamId 是数字,userUuid 可能是十六进制字符串)
|
|
639
|
+
const localStreams = this._scene.getStreamsByUserId(localUserId);
|
|
640
|
+
const mainStream = localStreams.find(s => s.videoSourceType === _imports.AgoraRteVideoSourceType.CAMERA) || localStreams[0];
|
|
641
|
+
if (!mainStream) {
|
|
642
|
+
throw new Error(`No stream found for local user: ${localUserId}`);
|
|
643
|
+
}
|
|
644
|
+
const uid = Number(mainStream.streamId);
|
|
645
|
+
await mediaControl.startClientRecording(this._scene.sceneId, uid, config, isScreenShareActive, currentScreenShareSourceId);
|
|
646
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
647
|
+
} catch (e) {
|
|
648
|
+
// API 调用成功但 SDK 启动失败时,回滚服务端状态
|
|
649
|
+
if (serverRecordingStarted) {
|
|
650
|
+
this.logger.error(`startClientRecording SDK failed, rolling back server state: ${e.message}`);
|
|
651
|
+
this._api.stopClientRecording(this._scene.sceneId, localUserId).catch(rollbackErr => {
|
|
652
|
+
this.logger.error(`startClientRecording rollback failed: ${rollbackErr.message}`);
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
throw e;
|
|
656
|
+
} finally {
|
|
657
|
+
this._isStartingClientRecording = false;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
async resumeClientRecording() {
|
|
661
|
+
const localUserId = this._scene.localUser.getLocalUserId();
|
|
662
|
+
await (0, _error.handleRequestError)(() => this._api.resumeClientRecording(this._scene.sceneId, localUserId), _imports.ErrorModuleCode.FCR_ROOM, 'resume client recording failed');
|
|
663
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
664
|
+
}
|
|
665
|
+
async stopClientRecording() {
|
|
666
|
+
const localUserId = this._scene.localUser.getLocalUserId();
|
|
667
|
+
|
|
668
|
+
// Step 1: 使用 mediaControl 的 stopClientRecording(即使失败也继续通知服务端)
|
|
669
|
+
const mediaControl = this._engine.getMediaControl();
|
|
670
|
+
try {
|
|
671
|
+
await mediaControl.stopClientRecording();
|
|
672
|
+
} catch (e) {
|
|
673
|
+
this.logger.error(`mediaControl.stopClientRecording failed: ${e.message}`);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// Step 2: 无论 SDK 停止是否成功,都通知服务器停止录制
|
|
677
|
+
await (0, _error.handleRequestError)(() => this._api.stopClientRecording(this._scene.sceneId, localUserId), _imports.ErrorModuleCode.FCR_ROOM, 'stop client recording failed');
|
|
678
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
679
|
+
}
|
|
680
|
+
isLocalClientRecordingActive() {
|
|
681
|
+
// 如果正在启动本地录制,也返回 true,避免在启动过程中触发错误的"其他人开启录制"提示
|
|
682
|
+
const mediaControl = this._engine.getMediaControl();
|
|
683
|
+
return this._isStartingClientRecording || mediaControl.isClientRecordingActive();
|
|
684
|
+
}
|
|
685
|
+
isClientRecordingOwnsCapture() {
|
|
686
|
+
const mediaControl = this._engine.getMediaControl();
|
|
687
|
+
return mediaControl.isClientRecordingOwnsCapture();
|
|
688
|
+
}
|
|
689
|
+
async resumeClientRecordingOwnCapture() {
|
|
690
|
+
const mediaControl = this._engine.getMediaControl();
|
|
691
|
+
await mediaControl.resumeClientRecordingOwnCapture();
|
|
692
|
+
}
|
|
693
|
+
async waitForScreenCaptureStopped() {
|
|
694
|
+
const mediaControl = this._engine.getMediaControl();
|
|
695
|
+
await mediaControl.waitForScreenCaptureStopped();
|
|
696
|
+
}
|
|
697
|
+
releaseClientRecordingOwnCapture() {
|
|
698
|
+
const mediaControl = this._engine.getMediaControl();
|
|
699
|
+
mediaControl.releaseClientRecordingOwnCapture();
|
|
700
|
+
}
|
|
577
701
|
getLiveStreamingState() {
|
|
578
702
|
let liveStreamingState = this._scene.getScenePropertiesByKeyPath('live.state');
|
|
579
703
|
if (liveStreamingState === _helpers.LIVE_STREAMING_STATE_VALUES.STARTED) {
|
|
@@ -613,6 +737,11 @@ class FcrBaseRoomControlImpl {
|
|
|
613
737
|
await this._liveStreamingAction(() => this._api.stopLiveStreaming(this._scene.sceneId), 'stop live streaming failed');
|
|
614
738
|
return _type.FcrReturnCode.SUCCESS;
|
|
615
739
|
}
|
|
740
|
+
hasActiveClientRecording() {
|
|
741
|
+
const userControl = this.getUserControl();
|
|
742
|
+
const users = userControl.getUserList();
|
|
743
|
+
return users.some(user => userControl.getUserClientRecordingState(user.userId));
|
|
744
|
+
}
|
|
616
745
|
getCloudRecordingState() {
|
|
617
746
|
const {
|
|
618
747
|
state,
|
|
@@ -641,6 +770,21 @@ class FcrBaseRoomControlImpl {
|
|
|
641
770
|
async _cleanup() {
|
|
642
771
|
this._scene.removeObserver(this._sceneObserver);
|
|
643
772
|
this._engine.removeObserver(this._engineObserver);
|
|
773
|
+
|
|
774
|
+
// 只有注册过录制观察者的 room control 才拥有录制生命周期,
|
|
775
|
+
// 其他房间(如等候室)的 cleanup 不应停止共享 mediaControl 上的录制。
|
|
776
|
+
if (this._isClientRecordingOwner) {
|
|
777
|
+
this._unregisterClientRecordingObserver();
|
|
778
|
+
try {
|
|
779
|
+
const mediaControl = this._engine.getMediaControl();
|
|
780
|
+
if (mediaControl.isClientRecordingActive()) {
|
|
781
|
+
await mediaControl.stopClientRecording();
|
|
782
|
+
this.logger.info('_cleanup: stopped client recording');
|
|
783
|
+
}
|
|
784
|
+
} catch (e) {
|
|
785
|
+
this.logger.error(`_cleanup: failed to stop client recording: ${e.message}`);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
644
788
|
this._sharedCache.getRoomCache(this._scene.sceneId).clear();
|
|
645
789
|
try {
|
|
646
790
|
return await Promise.all([this._chatRoomControl?.leave(), this.sharingControl?.getBoardControl().close(), this.sharingControl?.getAnnotationControl().close(), this._scene.leave()]);
|
|
@@ -60,6 +60,7 @@ class FcrInfinityRoomControlImpl extends _.FcrBaseRoomControlImpl {
|
|
|
60
60
|
this._interpreterControl = new _interpreterControl.FcrInterpreterControlImpl(api, scene, config, engine, chatConnection, sharedCache);
|
|
61
61
|
this._addLogObserver();
|
|
62
62
|
(0, _boardInitInfoHelper.addBoardInitInfoObserver)(this._scene, this._api, this.logger);
|
|
63
|
+
this._registerClientRecordingObserver();
|
|
63
64
|
this.logger.info(`initialized, room id: ${this._scene.sceneId}`);
|
|
64
65
|
}
|
|
65
66
|
getAnnouncement() {
|
|
@@ -114,13 +115,11 @@ class FcrInfinityRoomControlImpl extends _.FcrBaseRoomControlImpl {
|
|
|
114
115
|
_onLocalUserPermissionInfoDeleted(roomId, event) {
|
|
115
116
|
if ((0, _utils.hasBoardWritePermission)(event.permissionInfo)) {
|
|
116
117
|
this.logger.info(`remove board write permission`);
|
|
117
|
-
|
|
118
|
-
// this.getSharingControl().getBoardControl().getMainWindow()?.setWritable(false);
|
|
118
|
+
this.getSharingControl().getBoardControl().getMainWindow()?.setWritable(false);
|
|
119
119
|
}
|
|
120
120
|
if ((0, _utils.hasAnnotationWritePermission)(event.permissionInfo)) {
|
|
121
121
|
this.logger.info(`remove annotation write permission`);
|
|
122
|
-
|
|
123
|
-
// this.getSharingControl().getAnnotationControl().getMainWindow()?.setWritable(false);
|
|
122
|
+
this.getSharingControl().getAnnotationControl().getMainWindow()?.setWritable(false);
|
|
124
123
|
}
|
|
125
124
|
}
|
|
126
125
|
_addLogObserver() {
|
|
@@ -71,6 +71,7 @@ class FcrMainRoomControlImpl extends _.FcrBaseRoomControlImpl {
|
|
|
71
71
|
this._interpreterControl = new _interpreterControl.FcrInterpreterControlImpl(api, scene, config, engine, chatConnection, sharedCache);
|
|
72
72
|
this._addLogObserver();
|
|
73
73
|
(0, _boardInitInfoHelper.addBoardInitInfoObserver)(this._scene, this._api, this.logger);
|
|
74
|
+
this._registerClientRecordingObserver();
|
|
74
75
|
this.logger.info(`initialized, room id: ${this._scene.sceneId}`);
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -138,13 +139,11 @@ class FcrMainRoomControlImpl extends _.FcrBaseRoomControlImpl {
|
|
|
138
139
|
_onLocalUserPermissionInfoDeleted(roomId, event) {
|
|
139
140
|
if ((0, _utils2.hasBoardWritePermission)(event.permissionInfo)) {
|
|
140
141
|
this.logger.info(`remove board write permission`);
|
|
141
|
-
|
|
142
|
-
// this.getSharingControl().getBoardControl().getMainWindow()?.setWritable(false);
|
|
142
|
+
this.getSharingControl().getBoardControl().getMainWindow()?.setWritable(false);
|
|
143
143
|
}
|
|
144
144
|
if ((0, _utils2.hasAnnotationWritePermission)(event.permissionInfo)) {
|
|
145
145
|
this.logger.info(`remove annotation write permission`);
|
|
146
|
-
|
|
147
|
-
// this.getSharingControl().getAnnotationControl().getMainWindow()?.setWritable(false);
|
|
146
|
+
this.getSharingControl().getAnnotationControl().getMainWindow()?.setWritable(false);
|
|
148
147
|
}
|
|
149
148
|
}
|
|
150
149
|
_checkIfUpdateAnnotationMainWindow() {
|
|
@@ -34,7 +34,7 @@ var _user = require("../../utilities/user");
|
|
|
34
34
|
var _validateParams = _interopRequireDefault(require("../../utilities/validate-params"));
|
|
35
35
|
var _helper = require("./helper");
|
|
36
36
|
var _type2 = require("./type");
|
|
37
|
-
let _initProto, _allowWriteAnnotationDecs, _getSecurityInfoDecs, _getLocalUserPermissionInfoDecs, _enableLockedRoomDecs, _allowShareAndWriteDecs, _allowWriteBoardDecs, _allowWriteBoardByUserIdsDecs, _allowSendChatDecs, _allowStartAudioDecs, _allowStartVideoDecs, _allowJoinWithMutedAudioDecs, _allowJoinWithMutedVideoDecs, _allowWatermarkDecs, _allowChangeUserNameDecs, _allowStartCaptionDecs, _allowStartTranscribingDecs, _allowUpdateSttSourceLanguageDecs, _allowJoinWithPromptSoundDecs, _getRemoteUserPermissionEnableDecs, _allowViewUserCountDecs, _allowHandsUpDecs, _allowSendChatByUserRoleDecs, _allowSendChatByUserIdDecs;
|
|
37
|
+
let _initProto, _allowWriteAnnotationDecs, _getSecurityInfoDecs, _getLocalUserPermissionInfoDecs, _enableLockedRoomDecs, _allowShareAndWriteDecs, _allowWriteBoardDecs, _allowWriteBoardByUserIdsDecs, _allowSendChatDecs, _allowStartAudioDecs, _allowStartVideoDecs, _allowJoinWithMutedAudioDecs, _allowJoinWithMutedVideoDecs, _allowWatermarkDecs, _allowChangeUserNameDecs, _allowStartCaptionDecs, _allowStartTranscribingDecs, _allowUpdateSttSourceLanguageDecs, _allowJoinWithPromptSoundDecs, _allowClientRecordingDecs, _allowClientRecordingByUserIdDecs, _getRemoteUserPermissionEnableDecs, _allowViewUserCountDecs, _allowHandsUpDecs, _allowSendChatByUserRoleDecs, _allowSendChatByUserIdDecs;
|
|
38
38
|
function _applyDecs(e, t, r, n, o, a) { function i(e, t, r) { return function (n, o) { return r && r(n), e[t].call(n, o); }; } function c(e, t) { for (var r = 0; r < e.length; r++) e[r].call(t); return t; } function s(e, t, r, n) { if ("function" != typeof e && (n || void 0 !== e)) throw new TypeError(t + " must " + (r || "be") + " a function" + (n ? "" : " or undefined")); return e; } function applyDec(e, t, r, n, o, a, c, u, l, f, p, d, h) { function m(e) { if (!h(e)) throw new TypeError("Attempted to access private element on non-instance"); } var y, v = t[0], g = t[3], b = !u; if (!b) { r || Array.isArray(v) || (v = [v]); var w = {}, S = [], A = 3 === o ? "get" : 4 === o || d ? "set" : "value"; f ? (p || d ? w = { get: _setFunctionName(function () { return g(this); }, n, "get"), set: function (e) { t[4](this, e); } } : w[A] = g, p || _setFunctionName(w[A], n, 2 === o ? "" : A)) : p || (w = Object.getOwnPropertyDescriptor(e, n)); } for (var P = e, j = v.length - 1; j >= 0; j -= r ? 2 : 1) { var D = v[j], E = r ? v[j - 1] : void 0, I = {}, O = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: n, metadata: a, addInitializer: function (e, t) { if (e.v) throw Error("attempted to call addInitializer after decoration was finished"); s(t, "An initializer", "be", !0), c.push(t); }.bind(null, I) }; try { if (b) (y = s(D.call(E, P, O), "class decorators", "return")) && (P = y);else { var k, F; O.static = l, O.private = f, f ? 2 === o ? k = function (e) { return m(e), w.value; } : (o < 4 && (k = i(w, "get", m)), 3 !== o && (F = i(w, "set", m))) : (k = function (e) { return e[n]; }, (o < 2 || 4 === o) && (F = function (e, t) { e[n] = t; })); var N = O.access = { has: f ? h.bind() : function (e) { return n in e; } }; if (k && (N.get = k), F && (N.set = F), P = D.call(E, d ? { get: w.get, set: w.set } : w[A], O), d) { if ("object" == typeof P && P) (y = s(P.get, "accessor.get")) && (w.get = y), (y = s(P.set, "accessor.set")) && (w.set = y), (y = s(P.init, "accessor.init")) && S.push(y);else if (void 0 !== P) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); } else s(P, (p ? "field" : "method") + " decorators", "return") && (p ? S.push(P) : w[A] = P); } } finally { I.v = !0; } } return (p || d) && u.push(function (e, t) { for (var r = S.length - 1; r >= 0; r--) t = S[r].call(e, t); return t; }), p || b || (f ? d ? u.push(i(w, "get"), i(w, "set")) : u.push(2 === o ? w[A] : i.call.bind(w[A])) : Object.defineProperty(e, n, w)), P; } function u(e, t) { return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), { configurable: !0, enumerable: !0, value: t }); } if (arguments.length >= 6) var l = a[Symbol.metadata || Symbol.for("Symbol.metadata")]; var f = Object.create(null == l ? null : l), p = function (e, t, r, n) { var o, a, i = [], s = function (t) { return _checkInRHS(t) === e; }, u = new Map(); function l(e) { e && i.push(c.bind(null, e)); } for (var f = 0; f < t.length; f++) { var p = t[f]; if (Array.isArray(p)) { var d = p[1], h = p[2], m = p.length > 3, y = 16 & d, v = !!(8 & d), g = 0 == (d &= 7), b = h + "/" + v; if (!g && !m) { var w = u.get(b); if (!0 === w || 3 === w && 4 !== d || 4 === w && 3 !== d) throw Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + h); u.set(b, !(d > 2) || d); } applyDec(v ? e : e.prototype, p, y, m ? "#" + h : _toPropertyKey(h), d, n, v ? a = a || [] : o = o || [], i, v, m, g, 1 === d, v && m ? s : r); } } return l(o), l(a), i; }(e, t, o, f); return r.length || u(e, f), { e: p, get c() { var t = []; return r.length && [u(applyDec(e, [r], n, e.name, 5, f, t), f), c.bind(null, t, e)]; } }; }
|
|
39
39
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
40
40
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
@@ -45,10 +45,10 @@ function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side
|
|
|
45
45
|
*/
|
|
46
46
|
class FcrPrivilegeControlImpl {
|
|
47
47
|
static {
|
|
48
|
-
[_initProto] = _applyDecs(this, [[_allowWriteAnnotationDecs, 2, "allowWriteAnnotation"], [_getSecurityInfoDecs, 2, "getSecurityInfo"], [_getLocalUserPermissionInfoDecs, 2, "getLocalUserPermissionInfo"], [_enableLockedRoomDecs, 2, "enableLockedRoom"], [_allowShareAndWriteDecs, 2, "allowShareAndWrite"], [_allowWriteBoardDecs, 2, "allowWriteBoard"], [_allowWriteBoardByUserIdsDecs, 2, "allowWriteBoardByUserIds"], [_allowSendChatDecs, 2, "allowSendChat"], [_allowStartAudioDecs, 2, "allowStartAudio"], [_allowStartVideoDecs, 2, "allowStartVideo"], [_allowJoinWithMutedAudioDecs, 2, "allowJoinWithMutedAudio"], [_allowJoinWithMutedVideoDecs, 2, "allowJoinWithMutedVideo"], [_allowWatermarkDecs, 2, "allowWatermark"], [_allowChangeUserNameDecs, 2, "allowChangeUserName"], [_allowStartCaptionDecs, 2, "allowStartCaption"], [_allowStartTranscribingDecs, 2, "allowStartTranscribing"], [_allowUpdateSttSourceLanguageDecs, 2, "allowUpdateSttSourceLanguage"], [_allowJoinWithPromptSoundDecs, 2, "allowJoinWithPromptSound"], [_getRemoteUserPermissionEnableDecs, 2, "getRemoteUserPermissionEnable"], [_allowViewUserCountDecs, 2, "allowViewUserCount"], [_allowHandsUpDecs, 2, "allowHandsUp"], [_allowSendChatByUserRoleDecs, 2, "allowSendChatByUserRole"], [_allowSendChatByUserIdDecs, 2, "allowSendChatByUserId"], [_imports.trace, 2, "release"]], []).e;
|
|
48
|
+
[_initProto] = _applyDecs(this, [[_allowWriteAnnotationDecs, 2, "allowWriteAnnotation"], [_getSecurityInfoDecs, 2, "getSecurityInfo"], [_getLocalUserPermissionInfoDecs, 2, "getLocalUserPermissionInfo"], [_enableLockedRoomDecs, 2, "enableLockedRoom"], [_allowShareAndWriteDecs, 2, "allowShareAndWrite"], [_allowWriteBoardDecs, 2, "allowWriteBoard"], [_allowWriteBoardByUserIdsDecs, 2, "allowWriteBoardByUserIds"], [_allowSendChatDecs, 2, "allowSendChat"], [_allowStartAudioDecs, 2, "allowStartAudio"], [_allowStartVideoDecs, 2, "allowStartVideo"], [_allowJoinWithMutedAudioDecs, 2, "allowJoinWithMutedAudio"], [_allowJoinWithMutedVideoDecs, 2, "allowJoinWithMutedVideo"], [_allowWatermarkDecs, 2, "allowWatermark"], [_allowChangeUserNameDecs, 2, "allowChangeUserName"], [_allowStartCaptionDecs, 2, "allowStartCaption"], [_allowStartTranscribingDecs, 2, "allowStartTranscribing"], [_allowUpdateSttSourceLanguageDecs, 2, "allowUpdateSttSourceLanguage"], [_allowJoinWithPromptSoundDecs, 2, "allowJoinWithPromptSound"], [_allowClientRecordingDecs, 2, "allowClientRecording"], [_allowClientRecordingByUserIdDecs, 2, "allowClientRecordingByUserId"], [_getRemoteUserPermissionEnableDecs, 2, "getRemoteUserPermissionEnable"], [_allowViewUserCountDecs, 2, "allowViewUserCount"], [_allowHandsUpDecs, 2, "allowHandsUp"], [_allowSendChatByUserRoleDecs, 2, "allowSendChatByUserRole"], [_allowSendChatByUserIdDecs, 2, "allowSendChatByUserId"], [_imports.trace, 2, "release"]], []).e;
|
|
49
49
|
}
|
|
50
50
|
//@internal
|
|
51
|
-
[(_allowWriteAnnotationDecs = (0, _imports.trace)(['enable', 'targetRoles']), _getSecurityInfoDecs = [(0, _imports.trace)(['action']), (0, _validateParams.default)(_schema.fcrSecurityActionSchema)], _getLocalUserPermissionInfoDecs = [(0, _imports.trace)(['action']), (0, _validateParams.default)(_schema.fcrPermissionActionSchema)], _enableLockedRoomDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowShareAndWriteDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowWriteBoardDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowWriteBoardByUserIdsDecs = [(0, _imports.trace)(['enable', 'targetUserIds']), (0, _validateParams.default)(_schema.booleanSchema, _schema.stringArraySchema)], _allowSendChatDecs = [(0, _imports.trace)(['enable', 'targetRoles', 'payload']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema, _schema.fcrSecuritySendChatPayloadSchema)], _allowStartAudioDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowStartVideoDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowJoinWithMutedAudioDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowJoinWithMutedVideoDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowWatermarkDecs = [(0, _imports.trace)(['enable', 'targetRoles', 'lineType']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema, _schema.fcrLineTypeSchema.optional())], _allowChangeUserNameDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowStartCaptionDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowStartTranscribingDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowUpdateSttSourceLanguageDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowJoinWithPromptSoundDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _getRemoteUserPermissionEnableDecs = (0, _imports.trace)(['userId', 'type']), _allowViewUserCountDecs = (0, _imports.trace)(['enable', 'targetRoles']), _allowHandsUpDecs = (0, _imports.trace)(['enable', 'targetRoles']), _allowSendChatByUserRoleDecs = (0, _imports.trace)(['config', 'targetRoles']), _allowSendChatByUserIdDecs = (0, _imports.trace)(['enable', 'userId']), "logger")] = (_initProto(this), (0, _logger.createLogger)({
|
|
51
|
+
[(_allowWriteAnnotationDecs = (0, _imports.trace)(['enable', 'targetRoles']), _getSecurityInfoDecs = [(0, _imports.trace)(['action']), (0, _validateParams.default)(_schema.fcrSecurityActionSchema)], _getLocalUserPermissionInfoDecs = [(0, _imports.trace)(['action']), (0, _validateParams.default)(_schema.fcrPermissionActionSchema)], _enableLockedRoomDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowShareAndWriteDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowWriteBoardDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowWriteBoardByUserIdsDecs = [(0, _imports.trace)(['enable', 'targetUserIds']), (0, _validateParams.default)(_schema.booleanSchema, _schema.stringArraySchema)], _allowSendChatDecs = [(0, _imports.trace)(['enable', 'targetRoles', 'payload']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema, _schema.fcrSecuritySendChatPayloadSchema)], _allowStartAudioDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowStartVideoDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowJoinWithMutedAudioDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowJoinWithMutedVideoDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowWatermarkDecs = [(0, _imports.trace)(['enable', 'targetRoles', 'lineType']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema, _schema.fcrLineTypeSchema.optional())], _allowChangeUserNameDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowStartCaptionDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowStartTranscribingDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowUpdateSttSourceLanguageDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowJoinWithPromptSoundDecs = [(0, _imports.trace)(['enable', 'targetRoles']), (0, _validateParams.default)(_schema.booleanSchema, _schema.fcrPrivilegeUserRoleArraySchema)], _allowClientRecordingDecs = (0, _imports.trace)(['permissionType']), _allowClientRecordingByUserIdDecs = (0, _imports.trace)(['userId', 'enable']), _getRemoteUserPermissionEnableDecs = (0, _imports.trace)(['userId', 'type']), _allowViewUserCountDecs = (0, _imports.trace)(['enable', 'targetRoles']), _allowHandsUpDecs = (0, _imports.trace)(['enable', 'targetRoles']), _allowSendChatByUserRoleDecs = (0, _imports.trace)(['config', 'targetRoles']), _allowSendChatByUserIdDecs = (0, _imports.trace)(['enable', 'userId']), "logger")] = (_initProto(this), (0, _logger.createLogger)({
|
|
52
52
|
prefix: 'FcrPrivilegeControlImpl'
|
|
53
53
|
}));
|
|
54
54
|
_observable = new _imports.AgoraObservable();
|
|
@@ -260,6 +260,25 @@ class FcrPrivilegeControlImpl {
|
|
|
260
260
|
}), _imports.ErrorModuleCode.FCR_ROOM_PRIVILEGE, 'allow join with prompt sound failed');
|
|
261
261
|
return _type.FcrReturnCode.SUCCESS;
|
|
262
262
|
}
|
|
263
|
+
async allowClientRecording(permissionType) {
|
|
264
|
+
const enable = permissionType === _type2.FcrClientRecordingPermissionType.HostOnly ? 0 : 1;
|
|
265
|
+
const targetRoles = permissionType === _type2.FcrClientRecordingPermissionType.AllMembers ? [_type2.FcrPrivilegeUserRoleToStringMap[_type2.FcrPrivilegeUserRole.PARTICIPANT]] : undefined;
|
|
266
|
+
await (0, _error.handleRequestError)(() => this._api.allowClientRecording({
|
|
267
|
+
roomId: this._scene.sceneId,
|
|
268
|
+
permissionType,
|
|
269
|
+
enable,
|
|
270
|
+
targetRoles
|
|
271
|
+
}), _imports.ErrorModuleCode.FCR_ROOM_PRIVILEGE, 'allow client recording failed');
|
|
272
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
273
|
+
}
|
|
274
|
+
async allowClientRecordingByUserId(userId, enable) {
|
|
275
|
+
await (0, _error.handleRequestError)(() => this._api.allowClientRecordingByUserId({
|
|
276
|
+
roomId: this._scene.sceneId,
|
|
277
|
+
toUserUuids: [userId],
|
|
278
|
+
enable
|
|
279
|
+
}), _imports.ErrorModuleCode.FCR_ROOM_PRIVILEGE, 'allow client recording by user id failed');
|
|
280
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
281
|
+
}
|
|
263
282
|
getRemoteUserPermissionEnable(userId, type) {
|
|
264
283
|
if (userId === this._scene.localUser.getLocalUserId()) {
|
|
265
284
|
return false;
|
|
@@ -133,6 +133,17 @@ export interface FcrPrivilegeControl {
|
|
|
133
133
|
* @param targetRoles
|
|
134
134
|
*/
|
|
135
135
|
allowJoinWithPromptSound(enable: boolean, targetRoles: FcrPrivilegeUserRole[]): Promise<number>;
|
|
136
|
+
/**
|
|
137
|
+
* Sets client recording permission type (role-level).
|
|
138
|
+
* @param permissionType Permission type
|
|
139
|
+
*/
|
|
140
|
+
allowClientRecording(permissionType: FcrClientRecordingPermissionType): Promise<number>;
|
|
141
|
+
/**
|
|
142
|
+
* Allows or disallows a specific user to do client recording.
|
|
143
|
+
* @param userId Target user ID
|
|
144
|
+
* @param enable true to allow, false to disallow
|
|
145
|
+
*/
|
|
146
|
+
allowClientRecordingByUserId(userId: string, enable: boolean): Promise<number>;
|
|
136
147
|
/**
|
|
137
148
|
* Gets the remote user's permission enable.
|
|
138
149
|
* @param userId
|
|
@@ -358,6 +369,9 @@ export declare enum FcrPermissionAction {
|
|
|
358
369
|
RecordStopCloudRecording = "record:stopCloudRecording",
|
|
359
370
|
RecordPauseCloudRecording = "record:pauseCloudRecording",
|
|
360
371
|
RecordResumeCloudRecording = "record:resumeCloudRecording",
|
|
372
|
+
RecordStartClientRecording = "record:startClientRecording",
|
|
373
|
+
RecordStopClientRecording = "record:stopClientRecording",
|
|
374
|
+
RecordSetClientRecordingPermission = "record:setClientRecordingPermission",
|
|
361
375
|
CallCallIn = "call:callIn",
|
|
362
376
|
CallHangUp = "call:hangUp",
|
|
363
377
|
CallInvite = "call:invite",
|
|
@@ -429,6 +443,7 @@ export declare enum FcrSecurityAction {
|
|
|
429
443
|
SttStartCaption = "caption",
|
|
430
444
|
SttStartTranscribe = "transcribe",
|
|
431
445
|
JoinWithPromptSound = "joinWithPromptSound",
|
|
446
|
+
ClientRecording = "clientRecording",
|
|
432
447
|
HandsUp = "handsUp",
|
|
433
448
|
ViewUserCount = "viewUserCount"
|
|
434
449
|
}
|
|
@@ -436,6 +451,11 @@ export declare enum FcrWatermarkPermissionState {
|
|
|
436
451
|
ON = 1,
|
|
437
452
|
OFF = 0
|
|
438
453
|
}
|
|
454
|
+
export declare enum FcrClientRecordingPermissionType {
|
|
455
|
+
HostOnly = 1,
|
|
456
|
+
AllMembers = 2,
|
|
457
|
+
SpecifiedMembers = 3
|
|
458
|
+
}
|
|
439
459
|
export declare enum FcrRemotePermissionType {
|
|
440
460
|
SendChatToAll = 1,
|
|
441
461
|
SendChatToCoParticipant = 2,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.FcrWatermarkPermissionState = exports.FcrTargetUserTypeToStringMap = exports.FcrTargetUserType = exports.FcrSecurityAction = exports.FcrRoleFilter = exports.FcrRemotePermissionType = exports.FcrPrivilegeUserStringToRoleMap = exports.FcrPrivilegeUserRoleToStringMap = exports.FcrPrivilegeUserRole = exports.FcrPermissionAction = exports.FcrOperatePermissionType = exports.FcrExDataSyncType = exports.FcrChatPermissionType = void 0;
|
|
6
|
+
exports.FcrWatermarkPermissionState = exports.FcrTargetUserTypeToStringMap = exports.FcrTargetUserType = exports.FcrSecurityAction = exports.FcrRoleFilter = exports.FcrRemotePermissionType = exports.FcrPrivilegeUserStringToRoleMap = exports.FcrPrivilegeUserRoleToStringMap = exports.FcrPrivilegeUserRole = exports.FcrPermissionAction = exports.FcrOperatePermissionType = exports.FcrExDataSyncType = exports.FcrClientRecordingPermissionType = exports.FcrChatPermissionType = void 0;
|
|
7
7
|
let FcrTargetUserType = exports.FcrTargetUserType = /*#__PURE__*/function (FcrTargetUserType) {
|
|
8
8
|
FcrTargetUserType[FcrTargetUserType["SELF"] = 1] = "SELF";
|
|
9
9
|
FcrTargetUserType[FcrTargetUserType["HOST"] = 2] = "HOST";
|
|
@@ -118,6 +118,9 @@ let FcrPermissionAction = exports.FcrPermissionAction = /*#__PURE__*/function (F
|
|
|
118
118
|
FcrPermissionAction["RecordStopCloudRecording"] = "record:stopCloudRecording";
|
|
119
119
|
FcrPermissionAction["RecordPauseCloudRecording"] = "record:pauseCloudRecording";
|
|
120
120
|
FcrPermissionAction["RecordResumeCloudRecording"] = "record:resumeCloudRecording";
|
|
121
|
+
FcrPermissionAction["RecordStartClientRecording"] = "record:startClientRecording";
|
|
122
|
+
FcrPermissionAction["RecordStopClientRecording"] = "record:stopClientRecording";
|
|
123
|
+
FcrPermissionAction["RecordSetClientRecordingPermission"] = "record:setClientRecordingPermission";
|
|
121
124
|
FcrPermissionAction["CallCallIn"] = "call:callIn";
|
|
122
125
|
FcrPermissionAction["CallHangUp"] = "call:hangUp";
|
|
123
126
|
FcrPermissionAction["CallInvite"] = "call:invite";
|
|
@@ -183,6 +186,7 @@ let FcrSecurityAction = exports.FcrSecurityAction = /*#__PURE__*/function (FcrSe
|
|
|
183
186
|
FcrSecurityAction["SttStartCaption"] = "caption";
|
|
184
187
|
FcrSecurityAction["SttStartTranscribe"] = "transcribe";
|
|
185
188
|
FcrSecurityAction["JoinWithPromptSound"] = "joinWithPromptSound";
|
|
189
|
+
FcrSecurityAction["ClientRecording"] = "clientRecording";
|
|
186
190
|
FcrSecurityAction["HandsUp"] = "handsUp";
|
|
187
191
|
FcrSecurityAction["ViewUserCount"] = "viewUserCount";
|
|
188
192
|
return FcrSecurityAction;
|
|
@@ -192,6 +196,12 @@ let FcrWatermarkPermissionState = exports.FcrWatermarkPermissionState = /*#__PUR
|
|
|
192
196
|
FcrWatermarkPermissionState[FcrWatermarkPermissionState["OFF"] = 0] = "OFF";
|
|
193
197
|
return FcrWatermarkPermissionState;
|
|
194
198
|
}({});
|
|
199
|
+
let FcrClientRecordingPermissionType = exports.FcrClientRecordingPermissionType = /*#__PURE__*/function (FcrClientRecordingPermissionType) {
|
|
200
|
+
FcrClientRecordingPermissionType[FcrClientRecordingPermissionType["HostOnly"] = 1] = "HostOnly";
|
|
201
|
+
FcrClientRecordingPermissionType[FcrClientRecordingPermissionType["AllMembers"] = 2] = "AllMembers";
|
|
202
|
+
FcrClientRecordingPermissionType[FcrClientRecordingPermissionType["SpecifiedMembers"] = 3] = "SpecifiedMembers";
|
|
203
|
+
return FcrClientRecordingPermissionType;
|
|
204
|
+
}({});
|
|
195
205
|
let FcrRemotePermissionType = exports.FcrRemotePermissionType = /*#__PURE__*/function (FcrRemotePermissionType) {
|
|
196
206
|
FcrRemotePermissionType[FcrRemotePermissionType["SendChatToAll"] = 1] = "SendChatToAll";
|
|
197
207
|
FcrRemotePermissionType[FcrRemotePermissionType["SendChatToCoParticipant"] = 2] = "SendChatToCoParticipant";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FcrError } from '..';
|
|
2
|
+
import { FcrClientRecordingConfig, FcrRecorderState, FcrRecorderReasonCode } from '../imports';
|
|
2
3
|
import { FcrRoomJoinOptionsSchema } from '../schema';
|
|
3
4
|
import { FcrCloudRecordingConfig, FcrLiveStreamingConfig, FcrLiveStreamingLayoutType, FcrLiveStreamingState, FcrMessage, FcrNetworkQualityEvent, FcrNetworkStats, FcrRecordingState, FcrRoomInfo, FcrRoomJoinSnapshotOptions, FcrRoomPropertiesDeletedEvent, FcrRoomPropertiesUpdatedEvent, FcrRoomRouteSwitchEvent, FcrRoomSchedule, FcrRoomState } from '../type';
|
|
4
5
|
import { FcrChatRoomControl } from './chatroom-control/type';
|
|
@@ -168,6 +169,42 @@ export interface FcrBaseRoomControl {
|
|
|
168
169
|
* Gets the state of the cloud recording.
|
|
169
170
|
*/
|
|
170
171
|
getCloudRecordingState(): FcrRecordingState;
|
|
172
|
+
/**
|
|
173
|
+
* Starts the client recording.
|
|
174
|
+
* @param config Optional recording configuration (screenSourceId, reuseScreenShare, storagePath, etc.)
|
|
175
|
+
*/
|
|
176
|
+
startClientRecording(config?: FcrClientRecordingConfig): Promise<number>;
|
|
177
|
+
/**
|
|
178
|
+
* Stops the client recording.
|
|
179
|
+
*/
|
|
180
|
+
stopClientRecording(): Promise<number>;
|
|
181
|
+
/**
|
|
182
|
+
* Check whether client recording is currently active.
|
|
183
|
+
* Screen share should call this before stopping capture — if true, keep capture alive.
|
|
184
|
+
*/
|
|
185
|
+
isLocalClientRecordingActive(): boolean;
|
|
186
|
+
/**
|
|
187
|
+
* Check whether client recording owns its own screen capture.
|
|
188
|
+
*/
|
|
189
|
+
isClientRecordingOwnsCapture(): boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Resume recording's own window capture after it was released.
|
|
192
|
+
*/
|
|
193
|
+
resumeClientRecordingOwnCapture(): Promise<void>;
|
|
194
|
+
/**
|
|
195
|
+
* Wait for the SDK's screen capture stopped callback.
|
|
196
|
+
* Must be called BEFORE stopScreenCapture to register the promise.
|
|
197
|
+
*/
|
|
198
|
+
waitForScreenCaptureStopped(): Promise<void>;
|
|
199
|
+
/**
|
|
200
|
+
* Release the recording's own screen/window capture without stopping the recording.
|
|
201
|
+
* Called before starting screen share to free the capture resource.
|
|
202
|
+
*/
|
|
203
|
+
releaseClientRecordingOwnCapture(): void;
|
|
204
|
+
/**
|
|
205
|
+
* Checks whether any user in the room is currently doing client recording.
|
|
206
|
+
*/
|
|
207
|
+
hasActiveClientRecording(): boolean;
|
|
171
208
|
/**
|
|
172
209
|
* Sends a message to the room.
|
|
173
210
|
* @param payload
|
|
@@ -303,6 +340,13 @@ export type FcrRoomObserver = {
|
|
|
303
340
|
* @param type
|
|
304
341
|
*/
|
|
305
342
|
onLocalExDataSyncTypeRemoved?(roomId: string, syncTypeInfo: FcrExDataSyncType): void;
|
|
343
|
+
/**
|
|
344
|
+
* Callback to receive the client recording state changed event.
|
|
345
|
+
* @param roomId The room ID
|
|
346
|
+
* @param state The recorder state
|
|
347
|
+
* @param reason The reason for the state change
|
|
348
|
+
*/
|
|
349
|
+
onClientRecordingStateChanged?(roomId: string, state: FcrRecorderState, reason: FcrRecorderReasonCode): void;
|
|
306
350
|
};
|
|
307
351
|
export type FcrWaitingRoomObserver = FcrRoomObserver & {};
|
|
308
352
|
export type FcrJoinBeforeHostWaitingRoomObserver = FcrRoomObserver & {};
|