zbzt-live-sdk 0.0.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/.babelrc +8 -0
- package/.editorconfig +13 -0
- package/.eslintrc.js +29 -0
- package/CHANGELOG.md +16 -0
- package/README.md +32 -0
- package/dist/zbzt-live-sdk.cjs.js +51 -0
- package/dist/zbzt-live-sdk.esm.js +51 -0
- package/dist/zbzt-live-sdk.umd.js +52 -0
- package/dist/zbzt-live-sdk.umd.js.map +1 -0
- package/example/app.js +133 -0
- package/example/bootstrap-3.4.1/css/bootstrap-theme.css +587 -0
- package/example/bootstrap-3.4.1/css/bootstrap-theme.css.map +1 -0
- package/example/bootstrap-3.4.1/css/bootstrap-theme.min.css +6 -0
- package/example/bootstrap-3.4.1/css/bootstrap-theme.min.css.map +1 -0
- package/example/bootstrap-3.4.1/css/bootstrap.css +6834 -0
- package/example/bootstrap-3.4.1/css/bootstrap.css.map +1 -0
- package/example/bootstrap-3.4.1/css/bootstrap.min.css +6 -0
- package/example/bootstrap-3.4.1/css/bootstrap.min.css.map +1 -0
- package/example/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot +0 -0
- package/example/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg +288 -0
- package/example/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf +0 -0
- package/example/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff +0 -0
- package/example/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 +0 -0
- package/example/bootstrap-3.4.1/js/bootstrap.js +2580 -0
- package/example/bootstrap-3.4.1/js/bootstrap.min.js +6 -0
- package/example/bootstrap-3.4.1/js/npm.js +13 -0
- package/example/css/style.css +18 -0
- package/example/index.html +59 -0
- package/example/js/jquery-3.7.1.min.js +2 -0
- package/example/js/utils.js +25 -0
- package/example/js/variables.js +14 -0
- package/example/js/zegoApi.js +229 -0
- package/example/style.css +25 -0
- package/example/test.html +100 -0
- package/package.json +60 -0
- package/release.js +33 -0
- package/rollup-plugin-http.js +49 -0
- package/src/channel/getSendMsgParams.js +66 -0
- package/src/channel/index.js +135 -0
- package/src/channel/pomelo/index.js +182 -0
- package/src/channel/pomelo/latestQueue.js +150 -0
- package/src/channel/pomelo/polemo.js +730 -0
- package/src/channel/pomelo/util.js +54 -0
- package/src/channel/sdk-cb.js +73 -0
- package/src/channel/stream-msg.js +97 -0
- package/src/channel/zbzt/index.js +74 -0
- package/src/channel/zbzt/interactWithChannel.js +4 -0
- package/src/channel/zbzt/interactWithChannelControl.js +1568 -0
- package/src/channel/zbzt/interactWithChannelEntry.js +318 -0
- package/src/config/config.js +226 -0
- package/src/default/base.js +71 -0
- package/src/default/extend.js +36 -0
- package/src/default/index.js +10 -0
- package/src/live/base.js +43 -0
- package/src/live/call-method.js +10 -0
- package/src/live/extend.js +53 -0
- package/src/live/index.js +10 -0
- package/src/network/api.js +56 -0
- package/src/network/commonFetch.js +66 -0
- package/src/network/dataReport.js +448 -0
- package/src/notice.js +418 -0
- package/src/tool/base.js +74 -0
- package/src/tool/call-method.js +10 -0
- package/src/tool/extend.js +42 -0
- package/src/tool/index.js +10 -0
- package/src/util/bridge.js +87 -0
- package/src/util/bridge1.js +46 -0
- package/src/util/dict.js +51 -0
- package/src/util/sessionStorage.js +29 -0
- package/src/util/sha256.js +483 -0
- package/src/util/util.js +329 -0
- package/src/zbzt-av-sdk/default-sdk.js +192 -0
- package/src/zbzt-av-sdk/device.js +86 -0
- package/src/zbzt-av-sdk/rtc-sdk.js +2854 -0
- package/src/zbzt-av-sdk/talrtc-sdk.js +2620 -0
- package/src/zbzt-av-sdk/trtc-sdk.js +1802 -0
- package/src/zbzt-av-sdk/zbzt-av-sdk.js +2121 -0
- package/src/zbzt-av-sdk/zego-sdk.js +1718 -0
- package/src/zbzt-av-sdk/zego-sdk.js.bak +3133 -0
- package/src/zbzt-live-sdk.js +1484 -0
|
@@ -0,0 +1,3133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @File: Zego 音视频 SDK
|
|
3
|
+
* @Author: xuyuanrui
|
|
4
|
+
* @Email: raywhbxyr@163.com
|
|
5
|
+
* @Date: 2018-08-08 10:14:41
|
|
6
|
+
**/
|
|
7
|
+
import { dabanDataReport } from '../network/api.js';
|
|
8
|
+
import dataReport from '../network/dataReport.js';
|
|
9
|
+
import {
|
|
10
|
+
getS,
|
|
11
|
+
setS,
|
|
12
|
+
compareS
|
|
13
|
+
} from '../util/sessionStorage.js';
|
|
14
|
+
import defaultApi from '../default/index.js';
|
|
15
|
+
import util from '../util/util.js';
|
|
16
|
+
import NOTICE from '../notice.js';
|
|
17
|
+
import toolApi from '../tool/index.js';
|
|
18
|
+
import { deviceListReport } from './device.js';
|
|
19
|
+
import zbztsdk from '../zbzt-live-sdk.js';
|
|
20
|
+
|
|
21
|
+
// 扩展标识
|
|
22
|
+
const extensionId = 'zego_ext';
|
|
23
|
+
// 端提供的 API 入口
|
|
24
|
+
const EM = window.EM;
|
|
25
|
+
// 维护的一份当前正在使用的音频设备的 deviceId 的列表
|
|
26
|
+
let usingAudioDeviceId = {
|
|
27
|
+
speaker: '',
|
|
28
|
+
microphone: ''
|
|
29
|
+
};
|
|
30
|
+
// 维护的一份拉流的 streamId 与本地预览通道的映射表
|
|
31
|
+
let streamIdToPreviewId = {};
|
|
32
|
+
let previewIdToStreamId = {};
|
|
33
|
+
// const streamIdToBlobUrl = {};
|
|
34
|
+
// 拉流的播放通道初始化从 0 开始依次递增至44(共45路流),-1 为推流的本地视频预览
|
|
35
|
+
// const uiChnIndexs = new Array(50).fill(0).map((a, b) => b + 1).reverse();
|
|
36
|
+
const uiChnIndexs = new Array(48).fill(0).map((a, b) => b).reverse();
|
|
37
|
+
// 初始化是否完成的标志,0 为未完成,1 为完成
|
|
38
|
+
let isInitFinished = 0;
|
|
39
|
+
// 设备检测初始化是否完成的标志,0 为未完成,1 为完成
|
|
40
|
+
let isDeviceCheckInitFinished = 0;
|
|
41
|
+
// 进入房间是否成功
|
|
42
|
+
let hasLoginChannel = 0;
|
|
43
|
+
// 是否已经推流
|
|
44
|
+
let hasPushFlow = 0;
|
|
45
|
+
// 是否logoutChannel成功
|
|
46
|
+
let isAVEngineStopped = 0;
|
|
47
|
+
// 上层透传的回调函数缓存
|
|
48
|
+
// let zegoCallback = null;
|
|
49
|
+
// 是否执行过 Zego 的 AddListener 的标志
|
|
50
|
+
let hasAddListener = false;
|
|
51
|
+
// 是否处于网络错误状态中的标志
|
|
52
|
+
let hasNetWrong = false;
|
|
53
|
+
// rtc小班课=0;rtc大班课=1
|
|
54
|
+
const classType = 0;
|
|
55
|
+
// 监听id
|
|
56
|
+
let EMListenerId = 0;
|
|
57
|
+
|
|
58
|
+
//静音推流时,音量值是否上抛上层标志 false=没有声音不往上层通知/true=有声音有上层通知
|
|
59
|
+
let isNoticeMicVolumeZego = false;
|
|
60
|
+
|
|
61
|
+
// 心跳
|
|
62
|
+
let heartBeatDataReportObj = {};
|
|
63
|
+
let heartBeatDataReportTimer = null;
|
|
64
|
+
let isFirstHeartBeatReport = false;
|
|
65
|
+
let streamIdRtcPlayerInfo = {};
|
|
66
|
+
let streamIdRtcPlayerInfo1 = {};
|
|
67
|
+
let currStreamIdRtcPlayerInfo;
|
|
68
|
+
|
|
69
|
+
//记录底层推流回调的值
|
|
70
|
+
let dataZegoCapture = {};
|
|
71
|
+
|
|
72
|
+
//记录当前角色
|
|
73
|
+
let currentRole = '';
|
|
74
|
+
//记录当前课态类型:小组课=0/小班课=1
|
|
75
|
+
let currentClassMode = null;
|
|
76
|
+
//记录当前rtmp推流sdk类型
|
|
77
|
+
let currentGroupSdkType = '';
|
|
78
|
+
//主流ID
|
|
79
|
+
let localStreamId = '';
|
|
80
|
+
//屏幕流ID
|
|
81
|
+
let screenStreamId = '';
|
|
82
|
+
/**
|
|
83
|
+
* @function 调用端提供的回调方法
|
|
84
|
+
* @param name:String 回调方法名
|
|
85
|
+
* @param args 回调参数
|
|
86
|
+
* @return Promise | void
|
|
87
|
+
*/
|
|
88
|
+
const callMethod = (name, args) => {
|
|
89
|
+
// EM 是寄宿于端的,浏览器中并不存在,为防止报错需要先进行能力检测
|
|
90
|
+
if (EM) {
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
let noneCamera = (name === 'SetVideoDevice' && !args.pszDeviceID);
|
|
93
|
+
let noneMicrophone = (name === 'SetAudioDevice' && args.deviceType === 0 && !args.pszDeviceID);
|
|
94
|
+
let noneSpeaker = (name === 'SetAudioDevice' && args.deviceType === 1 && !args.pszDeviceID);
|
|
95
|
+
if (noneCamera || noneMicrophone || noneSpeaker) {
|
|
96
|
+
return resolve();
|
|
97
|
+
}
|
|
98
|
+
EM.CallMethod(
|
|
99
|
+
extensionId,
|
|
100
|
+
name,
|
|
101
|
+
JSON.stringify({ ...args, classType }),
|
|
102
|
+
(code, msg) => {
|
|
103
|
+
defaultApi.writeLog(`${name} Code: ${code} Message: ${msg} Params: ${JSON.stringify({ ...args, classType })}`);
|
|
104
|
+
resolve({
|
|
105
|
+
code,
|
|
106
|
+
msg
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @function 加载 Zego 扩展
|
|
116
|
+
* @param extensionVersion:String 扩展版本号,必选
|
|
117
|
+
* @return Promise | void
|
|
118
|
+
*/
|
|
119
|
+
export const loadZego = (extensionVersion) => {
|
|
120
|
+
// EM 是寄宿于端的,浏览器中并不存在,为防止报错需要先进行能力检测
|
|
121
|
+
if (EM) {
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
if (getS('zegoVersion')) {
|
|
124
|
+
if (compareS('zegoVersion', extensionVersion)) {
|
|
125
|
+
return resolve();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
EM.Load(
|
|
129
|
+
extensionId,
|
|
130
|
+
extensionVersion,
|
|
131
|
+
false,
|
|
132
|
+
(code, msg) => {
|
|
133
|
+
defaultApi.writeLog(`loadZego Code: ${code}\nMessage: ${msg}`);
|
|
134
|
+
if (code === 0) {
|
|
135
|
+
setS('zegoVersion', extensionVersion);
|
|
136
|
+
}
|
|
137
|
+
resolve();
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @function 卸载 Zego 扩展
|
|
146
|
+
* @return Promise | void
|
|
147
|
+
*/
|
|
148
|
+
export const unloadZego = () => {
|
|
149
|
+
// EM 是寄宿于端的,浏览器中并不存在,为防止报错需要先进行能力检测
|
|
150
|
+
if (EM) {
|
|
151
|
+
return new Promise((resolve, reject) => {
|
|
152
|
+
EM.UnLoad(
|
|
153
|
+
extensionId,
|
|
154
|
+
(code, msg) => {
|
|
155
|
+
defaultApi.writeLog(`unloadZego Code: ${code}\nMessage: ${msg}`);
|
|
156
|
+
resolve();
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @function 添加扩展监听机制
|
|
165
|
+
* @param userId:Number 用户 id,必选
|
|
166
|
+
* @param userName:String 用户名,必选
|
|
167
|
+
* @param roomId:String 频道(房间) id,必选
|
|
168
|
+
* @param nNetType:Number 网络类型,可选,默认为 1
|
|
169
|
+
* @return void
|
|
170
|
+
*/
|
|
171
|
+
const addListener = (userId, userName, confId, nNetType, devices, role) => {
|
|
172
|
+
// EM 是寄宿于端的,浏览器中并不存在,为防止报错需要先进行能力检测
|
|
173
|
+
if (EM && !hasAddListener) {
|
|
174
|
+
hasAddListener = true;
|
|
175
|
+
EM.AddListener(extensionId, (event, data) => {
|
|
176
|
+
if (data && data.indexOf(extensionId) > -1) {
|
|
177
|
+
try {
|
|
178
|
+
EMListenerId = JSON.parse(data)[extensionId];
|
|
179
|
+
defaultApi.writeLog(`ZEGO::addListener-- EMListenerId: ${EMListenerId}`);
|
|
180
|
+
} catch (error) { }
|
|
181
|
+
}
|
|
182
|
+
if (!event || !data) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
let _data = JSON.parse(data);
|
|
186
|
+
// if (_data && _data.classType === 1) {
|
|
187
|
+
// return false;
|
|
188
|
+
// }
|
|
189
|
+
switch (event) {
|
|
190
|
+
case 'OnInitSDK':
|
|
191
|
+
// 只有 OnInitSDK 事件成功返回后才可以执行后续操作,比如 loginChannel
|
|
192
|
+
var status = JSON.parse(data).nError;
|
|
193
|
+
var nclassType = JSON.parse(data).nClassType;
|
|
194
|
+
defaultApi.writeLog(`ZEGO::addListener-- OnInitSDK: ${status}--${nclassType}`);
|
|
195
|
+
if (status === 0 && nclassType == 0) {
|
|
196
|
+
if (userId === 'deviceCheckerInit') {
|
|
197
|
+
deviceCheckerInitSDK();
|
|
198
|
+
} else {
|
|
199
|
+
afterInitSDK(userId, userName, confId, nNetType, devices, role);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
break;
|
|
203
|
+
case 'OnLoginChannel':
|
|
204
|
+
var status = JSON.parse(data).uiErrorCode;
|
|
205
|
+
defaultApi.writeLog(`ZEGO::addListener-- OnLoginChannel: ${status}`);
|
|
206
|
+
if (status === 0) {
|
|
207
|
+
hasLoginChannel = 1;
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
case 'OnPublishStateUpdate':
|
|
211
|
+
let res = JSON.parse(data);
|
|
212
|
+
let keys = Object.keys(res);
|
|
213
|
+
if (keys.indexOf('eState') > -1) {
|
|
214
|
+
switch (res.eState) {
|
|
215
|
+
case 0:
|
|
216
|
+
hasPushFlow = 1;
|
|
217
|
+
window.zegoHasPushFlow = 1;
|
|
218
|
+
try {
|
|
219
|
+
let ReportArgs = {};
|
|
220
|
+
if (_data.pszStreamID.split('_').length == 5) {
|
|
221
|
+
ReportArgs.publish_rtc_streamid = _data.pszStreamID;
|
|
222
|
+
}
|
|
223
|
+
dataReport.publishResult({
|
|
224
|
+
code: '0',
|
|
225
|
+
...ReportArgs
|
|
226
|
+
// publish_streamid: window.zbztAVSDK_init_params.zego.streamId,
|
|
227
|
+
});
|
|
228
|
+
NOTICE.pushFlowSuccess({ code: 0, publish_streamid: _data.pszStreamID });
|
|
229
|
+
} catch (e) { };
|
|
230
|
+
if (window.zbztAVSDK_init_params.zego.isTurnPush) {
|
|
231
|
+
singleRecord('start');
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
case 1:
|
|
235
|
+
hasPushFlow = 0;
|
|
236
|
+
window.zegoHasPushFlow = 0;
|
|
237
|
+
break;
|
|
238
|
+
// 推流重试
|
|
239
|
+
case 6:
|
|
240
|
+
case 7:
|
|
241
|
+
case 105:
|
|
242
|
+
// pushFlowExceptionHandler();
|
|
243
|
+
try {
|
|
244
|
+
dataReport.publishResult({
|
|
245
|
+
code: res.eState,
|
|
246
|
+
// publish_streamid: window.zbztAVSDK_init_params.zego.streamId,
|
|
247
|
+
});
|
|
248
|
+
} catch (e) { };
|
|
249
|
+
break;
|
|
250
|
+
case 10:
|
|
251
|
+
if (!hasNetWrong) {
|
|
252
|
+
hasNetWrong = true;
|
|
253
|
+
defaultApi.writeLog('error', 'Network error');
|
|
254
|
+
NOTICE.networkError({
|
|
255
|
+
message: 'Network error'
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
dataReport.publishResult({
|
|
260
|
+
code: res.eState,
|
|
261
|
+
// publish_streamid: window.zbztAVSDK_init_params.zego.streamId,
|
|
262
|
+
});
|
|
263
|
+
} catch (e) { };
|
|
264
|
+
// pushFlowExceptionHandler();
|
|
265
|
+
break;
|
|
266
|
+
default:
|
|
267
|
+
try {
|
|
268
|
+
dataReport.publishResult({
|
|
269
|
+
code: res.eState,
|
|
270
|
+
// publish_streamid: window.zbztAVSDK_init_params.zego.streamId,
|
|
271
|
+
});
|
|
272
|
+
} catch (e) { };
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
case 'OnPublishQualityUpdate':
|
|
278
|
+
if (_data.hasOwnProperty('pq') && (_data.pszStreamID).split('_').length != 5) {
|
|
279
|
+
// 主辅两路质量回调,丢包延时只上抛一次,过滤掉辅路数据
|
|
280
|
+
_data.opt = 'quality';
|
|
281
|
+
_data.type = 'mediaupqos';
|
|
282
|
+
if (typeof _data.pq.kbps === 'number' && typeof _data.pq.fps === 'number') {
|
|
283
|
+
NOTICE.pushQuality({
|
|
284
|
+
video: {
|
|
285
|
+
bitrate: Math.round(_data.pq.kbps),
|
|
286
|
+
fps: Math.round(_data.pq.fps)
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
// console.log('推流延迟丢包zego',_data);
|
|
291
|
+
NOTICE.pushLossAndDelay({
|
|
292
|
+
userId: util.getUidByStreamId(_data.pszStreamID),
|
|
293
|
+
delay: _data.pq.rtt,
|
|
294
|
+
lostrate: _data.pq.pktLostRate
|
|
295
|
+
});
|
|
296
|
+
heartBeatDataReportCalc(event, _data.pq, _data.pszStreamID);
|
|
297
|
+
}
|
|
298
|
+
break;
|
|
299
|
+
case 'OnCaptureSoundLevelUpdate':
|
|
300
|
+
if (isNoticeMicVolumeZego) {
|
|
301
|
+
NOTICE.captureMicVolumeChanged({
|
|
302
|
+
volume: Math.round(_data.pCaptureSoundLevel[0].soundLevel)
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
// heartBeatDataReportObj.volume.push(Math.round(_data.pCaptureSoundLevel[0].soundLevel));
|
|
306
|
+
heartBeatDataReportObj.volume = heartBeatDataReportObj.volume + Math.round(_data.pCaptureSoundLevel[0].soundLevel) + ',';
|
|
307
|
+
break;
|
|
308
|
+
case 'OnSoundLevelUpdate':
|
|
309
|
+
_data.pSoundLevelList.forEach(item => {
|
|
310
|
+
const cbData = {
|
|
311
|
+
streamid: item.szStreamID,
|
|
312
|
+
userId: util.getUidByStreamId(item.szStreamID),
|
|
313
|
+
volume: Math.round(item.soundLevel)
|
|
314
|
+
};
|
|
315
|
+
NOTICE.playerVolumeChanged(cbData);
|
|
316
|
+
NOTICE.volumeChange(cbData);
|
|
317
|
+
// currStreamIdRtcPlayerInfo && currStreamIdRtcPlayerInfo.volume.push(Math.round(item.soundLevel));
|
|
318
|
+
// streamIdRtcPlayerInfo[item.szStreamID] && streamIdRtcPlayerInfo[item.szStreamID].volume.push(Math.round(item.soundLevel));
|
|
319
|
+
if (streamIdRtcPlayerInfo[item.szStreamID]) {
|
|
320
|
+
streamIdRtcPlayerInfo[item.szStreamID].volume = streamIdRtcPlayerInfo[item.szStreamID].volume + Math.round(item.soundLevel) + ',';
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
break;
|
|
324
|
+
case 'OnPlayStateUpdate':
|
|
325
|
+
if (_data.hasOwnProperty('eState')) {
|
|
326
|
+
let code = _data.eState;
|
|
327
|
+
if (code === 3) {
|
|
328
|
+
defaultApi.writeLog('error', `ZEGO:: OnPlayStateUpdate eState: ${code}`);
|
|
329
|
+
}
|
|
330
|
+
let normalCode = [0, 1, 3, 1011];
|
|
331
|
+
if (code === 10 && !hasNetWrong) {
|
|
332
|
+
hasNetWrong = true;
|
|
333
|
+
defaultApi.writeLog('error', 'Network error');
|
|
334
|
+
NOTICE.networkError({
|
|
335
|
+
message: 'Network error'
|
|
336
|
+
});
|
|
337
|
+
dabanDataReport({
|
|
338
|
+
action: 'zbzt_live_sdk_player_network_error',
|
|
339
|
+
uid: window.zbztAVSDK_init_params.zego.userId,
|
|
340
|
+
streamid: _data.pszStreamID,
|
|
341
|
+
teacherId: window.zbztAVSDK_init_params.zego.teacherId,
|
|
342
|
+
errorcode: code,
|
|
343
|
+
sdktype: 'zego'
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
// 拉流重试
|
|
347
|
+
if (normalCode.indexOf(code) === -1) {
|
|
348
|
+
setTimeout(() => {
|
|
349
|
+
// pullFlowExceptionHandler(_data.pszStreamID);
|
|
350
|
+
NOTICE.playError({
|
|
351
|
+
userId: util.getUidByStreamId(_data.pszStreamID),
|
|
352
|
+
message: 'play error'
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
dabanDataReport({
|
|
356
|
+
action: 'zbzt_live_sdk_player_play_error',
|
|
357
|
+
uid: window.zbztAVSDK_init_params.zego.userId,
|
|
358
|
+
streamid: _data.pszStreamID,
|
|
359
|
+
teacherId: window.zbztAVSDK_init_params.zego.teacherId,
|
|
360
|
+
errorcode: code,
|
|
361
|
+
sdktype: 'zego'
|
|
362
|
+
});
|
|
363
|
+
}, 1000);
|
|
364
|
+
};
|
|
365
|
+
try {
|
|
366
|
+
if (_data.pszStreamID.indexOf('ai') < 0) {
|
|
367
|
+
dataReport.pullResult({
|
|
368
|
+
code: code,
|
|
369
|
+
// pull_uid: _data.pszStreamID.split('_').length == 5 ? _data.pszStreamID : util.getUidByStreamId(_data.pszStreamID),
|
|
370
|
+
pull_uid: util.getUidByStreamId(_data.pszStreamID),
|
|
371
|
+
pull_streamid: _data.pszStreamID
|
|
372
|
+
});
|
|
373
|
+
NOTICE.pullFlowResult({ code: code, pull_streamid: _data.pszStreamID });
|
|
374
|
+
}
|
|
375
|
+
// dataReport.pullResult({
|
|
376
|
+
// code: code,
|
|
377
|
+
// pull_uid: util.getUidByStreamId(_data.pszStreamID),
|
|
378
|
+
// pull_streamid: _data.pszStreamID
|
|
379
|
+
// });
|
|
380
|
+
} catch (e) { };
|
|
381
|
+
}
|
|
382
|
+
break;
|
|
383
|
+
case 'OnPlayQulityUpdate': // 拉流
|
|
384
|
+
if (_data.hasOwnProperty('pq')) {
|
|
385
|
+
// console.log('拉流回调',`${new Date().getMinutes()}:${new Date().getSeconds()}`,_data);
|
|
386
|
+
_data.opt = 'quality';
|
|
387
|
+
_data.type = 'mediadownqos';
|
|
388
|
+
NOTICE.pullQuality({
|
|
389
|
+
video: {
|
|
390
|
+
streamId: _data.pszStreamID,
|
|
391
|
+
userId: util.getUidByStreamId(_data.pszStreamID),
|
|
392
|
+
bitrate: _data.pq.kbps,
|
|
393
|
+
fps: _data.pq.fps,
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
// console.log('拉流延迟丢包zego',_data);
|
|
397
|
+
NOTICE.playLossAndDelay({
|
|
398
|
+
userId: util.getUidByStreamId(_data.pszStreamID),
|
|
399
|
+
delay: _data.pq.rtt,
|
|
400
|
+
lostrate: _data.pq.pktLostRate
|
|
401
|
+
});
|
|
402
|
+
currStreamIdRtcPlayerInfo = streamIdRtcPlayerInfo[_data.pszStreamID];
|
|
403
|
+
heartBeatDataReportCalc(event, _data.pq, _data.pszStreamID);
|
|
404
|
+
}
|
|
405
|
+
break;
|
|
406
|
+
case 'OnVideoDeviceStateChanged': // 视频设备状态变更
|
|
407
|
+
// _data.state 0=添加设备 1=移除设备
|
|
408
|
+
// console.log('hsghsghsg摄像头热插拔',_data);
|
|
409
|
+
setVideoDevice({ deviceId: _data.state == 1 ? '' : _data.deviceInfo.szDeviceId, idx: 0, operationType: 'hotPlug', deviceState: _data.state, changedDeviceId: _data.deviceInfo.szDeviceId });
|
|
410
|
+
// try {
|
|
411
|
+
// dataReport.deviceTest({
|
|
412
|
+
// device: '1',
|
|
413
|
+
// fore_state: _data.state == 0 ? 1 : 2 ,
|
|
414
|
+
// camera_name: _data.deviceInfo && _data.deviceInfo.szDeviceName,
|
|
415
|
+
// });
|
|
416
|
+
// } catch (e){};
|
|
417
|
+
break;
|
|
418
|
+
case 'OnAudioDeviceStateChanged': // 音频设备状态变更
|
|
419
|
+
// console.log('hsghsghsg扬声器热插拔1',_data);
|
|
420
|
+
if (_data.deviceType === 0) {
|
|
421
|
+
// _data.state 0=添加设备 1=移除设备
|
|
422
|
+
setMicrophoneDevice({ deviceId: _data.state == 1 ? '' : _data.deviceInfo.szDeviceId, operationType: 'hotPlug', deviceState: _data.state, changedDeviceId: _data.deviceInfo.szDeviceId });
|
|
423
|
+
}
|
|
424
|
+
if (_data.deviceType === 1) {
|
|
425
|
+
// console.log('hsghsghsg扬声器热插拔',_data);
|
|
426
|
+
setSpeakerDevice({ deviceId: _data.state == 1 ? '' : _data.deviceInfo.szDeviceId, operationType: 'hotPlug', deviceState: _data.state, changedDeviceId: _data.deviceInfo.szDeviceId });
|
|
427
|
+
}
|
|
428
|
+
// try {
|
|
429
|
+
// dataReport.deviceTest({
|
|
430
|
+
// device: _data.deviceType === 0 ? '2' : '3',
|
|
431
|
+
// fore_state: _data.state == 0 ? 1 : 2 ,
|
|
432
|
+
// microphone_name: _data.deviceInfo && _data.deviceInfo.szDeviceName,
|
|
433
|
+
// speaker_name: _data.deviceInfo && _data.deviceInfo.szDeviceName
|
|
434
|
+
// });
|
|
435
|
+
// } catch (e){};
|
|
436
|
+
break;
|
|
437
|
+
case 'OnDeviceError':
|
|
438
|
+
//errorCode 无效设备ID (-2), 没有权限 (-3), 采集帧率为0 (-4), 设备被占用 (-5), 设备未插入 (-6), 需要重启系统 (-7), 媒体服务无法恢复 (-8), 设备被SIRI占用 (-9)
|
|
439
|
+
let codemsg = {
|
|
440
|
+
'-2': '无效设备ID',
|
|
441
|
+
'-3': '没有权限',
|
|
442
|
+
'-4': '采集帧率为0',
|
|
443
|
+
'-5': '设备被占用',
|
|
444
|
+
'-6': '设备未插入',
|
|
445
|
+
'-7': '需要重启系统',
|
|
446
|
+
'-8': '媒体服务无法恢复',
|
|
447
|
+
'-9': '设备被SIRI占用'
|
|
448
|
+
};
|
|
449
|
+
defaultApi.writeLog(`avsdk ZEGO:: OnDeviceError ${_data.deviceName} ${_data.errorCode}`);
|
|
450
|
+
dataReport.deviceError({ deviceName: _data.deviceName, errorCode: _data.errorCode });
|
|
451
|
+
// _data.deviceName === 'camera' ? setVideoDevice({deviceId: '', idx: 0, operationType: 'deviceError', deviceState: '', code: codemsg[_data.errorCode]}) : setMicrophoneDevice({deviceId: '', operationType: 'deviceError', deviceState: '', code: codemsg[_data.errorCode]});
|
|
452
|
+
break;
|
|
453
|
+
case 'OnAVKitEvent':
|
|
454
|
+
// defaultApi.writeLog('avsdk ZEGO:: OnAVKitEvent');
|
|
455
|
+
if (_data.event === 4 && hasNetWrong) {
|
|
456
|
+
hasNetWrong = false;
|
|
457
|
+
NOTICE.networkRecovery({
|
|
458
|
+
message: 'Network recovery'
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
break;
|
|
462
|
+
case 'OnAVEngineStop':
|
|
463
|
+
isAVEngineStopped = 1;
|
|
464
|
+
defaultApi.writeLog('avsdk ZEGO:: listened AVEngineStop');
|
|
465
|
+
break;
|
|
466
|
+
case 'OnMixStream':
|
|
467
|
+
defaultApi.writeLog('avsdk ZEGO:: listened mix_stream_response');
|
|
468
|
+
break;
|
|
469
|
+
case 'OnRenderRemoteVideoFirstFrame':
|
|
470
|
+
// 大班数据上报
|
|
471
|
+
if (window.zbztAVSDK_init_params.zego.role === 'student') {
|
|
472
|
+
dabanDataReport({
|
|
473
|
+
action: 'interact_play',
|
|
474
|
+
teammate_streamid: _data.pszStreamID,
|
|
475
|
+
uid: window.zbztAVSDK_init_params.zego.userId
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
try {
|
|
479
|
+
NOTICE.firstVideoSize({
|
|
480
|
+
streamId: _data.pszStreamID,
|
|
481
|
+
// userId: _data.pszStreamID.split('_').length == 5 ? _data.pszStreamID : util.getUidByStreamId(_data.pszStreamID)
|
|
482
|
+
userId: util.getUidByStreamId(_data.pszStreamID)
|
|
483
|
+
});
|
|
484
|
+
dataReport.firstVideoSize({
|
|
485
|
+
pull_streamid: _data.pszStreamID,
|
|
486
|
+
pull_uid: util.getUidByStreamIdDr(_data.pszStreamID),
|
|
487
|
+
code: '0'
|
|
488
|
+
});
|
|
489
|
+
} catch (e) { };
|
|
490
|
+
defaultApi.writeLog(`ZEGO: pullStream success & haveFirstVideoSize streamId: ${_data.pszStreamID}`);
|
|
491
|
+
// try {
|
|
492
|
+
// dataReport.pullResult({
|
|
493
|
+
// status: 0,
|
|
494
|
+
// pull_uid: util.getUidByStreamId(_data.pszStreamID),
|
|
495
|
+
// pull_streamid: _data.pszStreamID
|
|
496
|
+
// });
|
|
497
|
+
// } catch (e) {};
|
|
498
|
+
break;
|
|
499
|
+
case 'OnRecvRemoteAudioFirstFrame':
|
|
500
|
+
try {
|
|
501
|
+
NOTICE.firstAudioSize({
|
|
502
|
+
streamId: _data.pszStreamID,
|
|
503
|
+
userId: util.getUidByStreamId(_data.pszStreamID)
|
|
504
|
+
});
|
|
505
|
+
dataReport.firstAudioSize({
|
|
506
|
+
pull_streamid: _data.pszStreamID,
|
|
507
|
+
pull_uid: util.getUidByStreamIdDr(_data.pszStreamID),
|
|
508
|
+
code: '0'
|
|
509
|
+
});
|
|
510
|
+
} catch (e) { };
|
|
511
|
+
break;
|
|
512
|
+
// 转推回调 0=转推停止 1=正在转推 2=正在重试
|
|
513
|
+
case 'onRecvMediaSideInfo':
|
|
514
|
+
defaultApi.writeLog(`avsdk ZEGO:: onRecvMediaSideInfo, ${JSON.stringify(_data)}`);
|
|
515
|
+
NOTICE.seiReceived({ data: _data });
|
|
516
|
+
break;
|
|
517
|
+
case 'zego_recovery_start':
|
|
518
|
+
defaultApi.writeLog(`avsdk ZEGO:: zego_recovery_start ${JSON.stringify(_data)}`);
|
|
519
|
+
NOTICE.zegoRecoveryStart();
|
|
520
|
+
break;
|
|
521
|
+
case 'OnRelayCDNStateUpdate':
|
|
522
|
+
if (_data.statesInfo && _data.statesInfo[0] && _data.statesInfo[0].state === 1) {
|
|
523
|
+
NOTICE.recordResponse({
|
|
524
|
+
streamId: _data.streamID,
|
|
525
|
+
userId: util.getUidByStreamId(_data.streamID)
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
// try {
|
|
529
|
+
// dataReport.turnPushResult({
|
|
530
|
+
// errorcode:_data.statesInfo[0].state,
|
|
531
|
+
// case: 'turn push',
|
|
532
|
+
// streamid: _data.streamID
|
|
533
|
+
// })
|
|
534
|
+
// } catch (e) {};
|
|
535
|
+
break;
|
|
536
|
+
case 'OnCaptureVideoFirstFrame':
|
|
537
|
+
// 大班数据上报
|
|
538
|
+
dabanDataReport({
|
|
539
|
+
action: 'open_camera',
|
|
540
|
+
camera_status: 1,
|
|
541
|
+
uid: window.zbztAVSDK_init_params.zego.userId
|
|
542
|
+
});
|
|
543
|
+
break;
|
|
544
|
+
case 'OnKaDunEvent':
|
|
545
|
+
if (_data.event === 8) {
|
|
546
|
+
currStreamIdRtcPlayerInfo && (currStreamIdRtcPlayerInfo.video_ifg += _data.kaDunTime);
|
|
547
|
+
}
|
|
548
|
+
if (_data.event === 10) {
|
|
549
|
+
currStreamIdRtcPlayerInfo && (currStreamIdRtcPlayerInfo.audio_ifg += _data.kaDunTime);
|
|
550
|
+
}
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
if (zbztsdk.openListenerLog) {
|
|
554
|
+
defaultApi.writeLog(`Zego::Listener:: event: ${event}, data: ${JSON.stringify(data)}`);
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* @function 添加扩展监听机制
|
|
562
|
+
* @return void
|
|
563
|
+
*/
|
|
564
|
+
const removerListener = () => {
|
|
565
|
+
hasAddListener = false;
|
|
566
|
+
defaultApi.writeLog(`ZEGO::action--removerListener EMListenerId:${EMListenerId}`);
|
|
567
|
+
EM.RemoverListener(extensionId, EMListenerId, (ec, content) => { });
|
|
568
|
+
EMListenerId = 0;
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* @function 推流异常恢复
|
|
573
|
+
*/
|
|
574
|
+
export const pushFlowExceptionHandler = async () => {
|
|
575
|
+
await new Promise((resolve, reject) => {
|
|
576
|
+
setTimeout(() => {
|
|
577
|
+
resolve();
|
|
578
|
+
}, 1000);
|
|
579
|
+
});
|
|
580
|
+
defaultApi.writeLog('断网重推');
|
|
581
|
+
defaultApi.writeLog('avsdk ZEGO::try to pushFlow again');
|
|
582
|
+
await stopPublish();
|
|
583
|
+
await startPublish2();
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* @function 拉流异常恢复
|
|
588
|
+
*/
|
|
589
|
+
export const pullFlowExceptionHandler = async (streamId) => {
|
|
590
|
+
await new Promise((resolve, reject) => {
|
|
591
|
+
setTimeout(() => {
|
|
592
|
+
resolve();
|
|
593
|
+
}, 1000);
|
|
594
|
+
});
|
|
595
|
+
defaultApi.writeLog('断网重拉');
|
|
596
|
+
defaultApi.writeLog(`avsdk ZEGO::try to pullFlow again ,streamId : ${streamId}`);
|
|
597
|
+
await stopPlayStream(streamId);
|
|
598
|
+
await playStream(streamId);
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* @function 初始化 Engine
|
|
603
|
+
* @param appId:String Zego 秘钥,必选
|
|
604
|
+
* @param appSignature:String 签名,必选
|
|
605
|
+
* @param businessType:Number 业务类型,可选,默认为 0
|
|
606
|
+
* @param videoRenderType:Number zego视频渲染类型,默认为2(只外部渲染),zego小组课需要设置为5(同时支持内部+外部渲染)
|
|
607
|
+
* @return Promise | void
|
|
608
|
+
*/
|
|
609
|
+
export const startEngine = (appId, appSignature, businessType, videoRenderType=2) => {
|
|
610
|
+
if (typeof businessType === 'undefined') {
|
|
611
|
+
businessType = 0;
|
|
612
|
+
}
|
|
613
|
+
defaultApi.writeLog('avsdk ZEGO::StartEngine');
|
|
614
|
+
return callMethod('StartEngine', {
|
|
615
|
+
appId,
|
|
616
|
+
appSignature,
|
|
617
|
+
businessType,
|
|
618
|
+
videoRenderType
|
|
619
|
+
});
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
//开启消除回声
|
|
623
|
+
export const setEnableAEC = (bEnable) => {
|
|
624
|
+
return callMethod('EnableAEC', { bEnable });
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
//设置回声消除模式 mode :激进模式 =0/中等模式 =1/轻度模式 =2
|
|
628
|
+
export const setAECMode = (mode) => {
|
|
629
|
+
return callMethod('SetAECMode', { mode });
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
//开启噪音消除
|
|
633
|
+
export const setEnableNoiseSuppress = (bEnable) => {
|
|
634
|
+
return callMethod('EnableNoiseSuppress', { bEnable });
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
//设置噪音消除模式 mode :0:低 1:中 2高
|
|
638
|
+
export const setNoiseSuppressMode = (level) => {
|
|
639
|
+
return callMethod('SetNoiseSuppressMode', { level });
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
//新增瞬时降噪接口 瞬时降噪 可以处理掉 敲键盘、敲桌子、敲门等瞬态噪声。非瞬态噪声,此接口无法处理,比如划桌子等摩擦噪音。
|
|
643
|
+
export const enableTransientNoiseSuppress = (enable) => {
|
|
644
|
+
return callMethod('EnableTransientNoiseSuppress', { enable })
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* @function 加载采集插件的输入数据 //调用后,zego 可以向采集插件传送摄像头数据,用于拼接
|
|
649
|
+
* @return: Promise
|
|
650
|
+
*/
|
|
651
|
+
export const loadCollectionInputEntry = () => {
|
|
652
|
+
return callMethod('LoadCollectionInputEntry', {});
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* @function 加载采集插件的输出数据 //调用后,zego 可以向采集插件传送学生流数据(加载截屏插件,获取截屏插件设置拉流头像回调函数)
|
|
657
|
+
* @param stream_ids array 设置需要拼接的学生头像流id,按数组顺序拼接
|
|
658
|
+
* @return: Promise
|
|
659
|
+
*/
|
|
660
|
+
export const loadCollectionInputEntry2 = (stream_ids) => {
|
|
661
|
+
return callMethod('LoadCollectionInputEntry2', { stream_ids });
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* @function 加载采集插件的输出数据 //调用后,zego 可以从采集插件获取拼接数据
|
|
666
|
+
* @return: Promise
|
|
667
|
+
*/
|
|
668
|
+
export const loadCollectionOutputEntry = () => {
|
|
669
|
+
return callMethod('LoadCollectionOutputEntry', {});
|
|
670
|
+
};
|
|
671
|
+
/**
|
|
672
|
+
* @function 设置直推url //调用后,zego 可以从采集插件获取拼接数据
|
|
673
|
+
* @param pRtmpUrl:String 直推地址
|
|
674
|
+
* @param idx:Number 使用外部采集的通道idx,与StartEngine中channel_idx保持一致
|
|
675
|
+
* @return: Promise
|
|
676
|
+
*/
|
|
677
|
+
export const setCDNPublishTarget = (pRtmpUrl, idx) => {
|
|
678
|
+
return callMethod('SetCDNPublishTarget', { pRtmpUrl, idx });
|
|
679
|
+
};
|
|
680
|
+
/**
|
|
681
|
+
* @function 销毁引擎
|
|
682
|
+
* @return Promise | void
|
|
683
|
+
*/
|
|
684
|
+
export const destroyEngine = () => {
|
|
685
|
+
return callMethod('DestroyEngine', {});
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* @function 加入频道
|
|
690
|
+
* @param userId:Number 用户 id,必选
|
|
691
|
+
* @param userName:String 用户名,必选
|
|
692
|
+
* @param channelId:String 频道 id,必选
|
|
693
|
+
* @param nNetType:Number 网络类型,可选,默认为 1
|
|
694
|
+
* @return Promise | void
|
|
695
|
+
*/
|
|
696
|
+
export const loginChannel = (userId, userName, channelId, nNetType) => {
|
|
697
|
+
if (typeof nNetType === 'undefined') {
|
|
698
|
+
nNetType = 1;
|
|
699
|
+
}
|
|
700
|
+
return callMethod('LoginChannel', {
|
|
701
|
+
pszUserID: userId + '',
|
|
702
|
+
pszUserName: userName,
|
|
703
|
+
pszChannelID: channelId,
|
|
704
|
+
nNetType
|
|
705
|
+
});
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* @function 退出直播频道
|
|
710
|
+
* @return Promise | void
|
|
711
|
+
*/
|
|
712
|
+
export const logoutChannel = () => {
|
|
713
|
+
defaultApi.writeLog('avsdk ZEGO:: CallMethod : LogoutChannel');
|
|
714
|
+
return callMethod('LogoutChannel', {});
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* @function 云控时退出房间
|
|
719
|
+
* @return Promise
|
|
720
|
+
*/
|
|
721
|
+
export const leaveRoomWithChangeSDK = async () => {
|
|
722
|
+
defaultApi.writeLog(`leaveRoomWithChangeSDK--currentClassMode--currentGroupSdkType ${currentClassMode}, ${currentGroupSdkType}`);
|
|
723
|
+
let needDestroyZegoEngine = true; //云控从zego切到其他sdk时,默认释放zego引擎。但是如果zego在推拉RTMP流,则不能释放
|
|
724
|
+
if (currentGroupSdkType == 'zego' || window.zbzt_isM1Type) {
|
|
725
|
+
switch (currentClassMode) {
|
|
726
|
+
case 0: // 小组
|
|
727
|
+
case 2: // 组合小班
|
|
728
|
+
needDestroyZegoEngine = false;
|
|
729
|
+
break;
|
|
730
|
+
case 1: // 小班
|
|
731
|
+
if (window.zbzt_sdk_init_params.role === 'teacher' || window.zbzt_sdk_init_params.role === 'assistant') {
|
|
732
|
+
needDestroyZegoEngine = false;
|
|
733
|
+
}
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
await stopSoundLevelMonitor();
|
|
738
|
+
for (let key in streamIdToPreviewId) {
|
|
739
|
+
await stopPlayStream(key, true);
|
|
740
|
+
}
|
|
741
|
+
if ((isZegoGroupClass() && (currentRole === 'teacher' || currentRole === 'assistant')) || (isZegoCombinationClass() && currentRole === 'assistant')) {
|
|
742
|
+
// zego小组课,切RTC流云控后,授课端不能停止预览
|
|
743
|
+
console.log('zego小组课不可停止预览,会影响rtmp')
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
await stopPreview();
|
|
747
|
+
}
|
|
748
|
+
await stopPublish();
|
|
749
|
+
removerListener();
|
|
750
|
+
|
|
751
|
+
if (needDestroyZegoEngine === true) {
|
|
752
|
+
await destroyEngine();
|
|
753
|
+
}
|
|
754
|
+
if ((window.zbzt_sdk_init_params.role === 'teacher') && window.zbzt_sdk_init_params.mode === 1) {
|
|
755
|
+
//坐立模式关闭外部采集器,站立关闭外部采集器
|
|
756
|
+
await setVideoCaptureFactory(false);
|
|
757
|
+
}
|
|
758
|
+
heartBeatDataReport('stop');
|
|
759
|
+
isFirstHeartBeatReport = false;
|
|
760
|
+
streamIdToPreviewId = {};
|
|
761
|
+
previewIdToStreamId = {};
|
|
762
|
+
streamIdRtcPlayerInfo = {};
|
|
763
|
+
streamIdRtcPlayerInfo1 = {};
|
|
764
|
+
// heartBeatDataReportObj = {};
|
|
765
|
+
hasLoginChannel = 0;
|
|
766
|
+
hasPushFlow = 0;
|
|
767
|
+
isAVEngineStopped = 0;
|
|
768
|
+
window.zegoHasPushFlow = 0;
|
|
769
|
+
};
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* @function 退出房间
|
|
773
|
+
* @return Promise
|
|
774
|
+
*/
|
|
775
|
+
export const leaveRoom = async (type) => {
|
|
776
|
+
await stopSoundLevelMonitor();
|
|
777
|
+
for (let key in streamIdToPreviewId) {
|
|
778
|
+
await stopPlayStream(key, true);
|
|
779
|
+
}
|
|
780
|
+
await stopPublish();
|
|
781
|
+
removerListener();
|
|
782
|
+
// await logoutChannel();
|
|
783
|
+
// await new Promise((resolve, reject) => {
|
|
784
|
+
// let timer = setInterval(() => {
|
|
785
|
+
// if (isAVEngineStopped) {
|
|
786
|
+
// clearInterval(timer);
|
|
787
|
+
// resolve();
|
|
788
|
+
// }
|
|
789
|
+
// }, 300);
|
|
790
|
+
// });
|
|
791
|
+
if (type == 'reload') {
|
|
792
|
+
defaultApi.writeLog('leaveroom -- reload --小组课刷新不可销毁zego引擎')
|
|
793
|
+
} else {
|
|
794
|
+
await stopPreview();
|
|
795
|
+
await destroyEngine();
|
|
796
|
+
}
|
|
797
|
+
if ((window.zbzt_sdk_init_params.role === 'teacher') && window.zbzt_sdk_init_params.mode === 1) {
|
|
798
|
+
//坐立模式关闭外部采集器,站立关闭外部采集器
|
|
799
|
+
await setVideoCaptureFactory(false);
|
|
800
|
+
}
|
|
801
|
+
heartBeatDataReport('stop');
|
|
802
|
+
isFirstHeartBeatReport = false;
|
|
803
|
+
streamIdToPreviewId = {};
|
|
804
|
+
previewIdToStreamId = {};
|
|
805
|
+
streamIdRtcPlayerInfo = {};
|
|
806
|
+
streamIdRtcPlayerInfo1 = {};
|
|
807
|
+
// heartBeatDataReportObj = {};
|
|
808
|
+
hasLoginChannel = 0;
|
|
809
|
+
hasPushFlow = 0;
|
|
810
|
+
isAVEngineStopped = 0;
|
|
811
|
+
window.zegoHasPushFlow = 0;
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
export const stopCheckDevice = async () => {
|
|
815
|
+
removerListener();
|
|
816
|
+
await stopSoundLevelMonitor();
|
|
817
|
+
await stopPreview();
|
|
818
|
+
defaultApi.writeLog('rtc stopCheckDevice and removerListener and captureDestroy');
|
|
819
|
+
return callMethod('DestroyEngine', {});
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* @function 获取系统默认的音频设备
|
|
824
|
+
* @param deviceType:Number 音频设备类型,0 -> 麦克风,1 -> 扬声器,必选
|
|
825
|
+
* @return Promise | void
|
|
826
|
+
*/
|
|
827
|
+
export const getDefaultAudioDeviceId = (deviceType) => {
|
|
828
|
+
return callMethod('GetDefaultAudioDeviceId', {
|
|
829
|
+
deviceType,
|
|
830
|
+
// 以下两个参数仅仅是为了向下向后兼容,使用 hardcore 即可
|
|
831
|
+
deviceId: '',
|
|
832
|
+
deviceIdLength: 0
|
|
833
|
+
});
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* @function 获取系统默认的麦克风设备 id
|
|
838
|
+
* @return Promise
|
|
839
|
+
*/
|
|
840
|
+
export const getDefaultMicrophone = () => {
|
|
841
|
+
return getDefaultAudioDeviceId(0);
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* @function 获取系统默认的扬声器设备 id
|
|
846
|
+
* @return Promise
|
|
847
|
+
*/
|
|
848
|
+
export const getDefaultSpeaker = () => {
|
|
849
|
+
return getDefaultAudioDeviceId(1);
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* @function 获取摄像头列表
|
|
854
|
+
* @return Promise | void
|
|
855
|
+
*/
|
|
856
|
+
export const getVideoDeviceList = async () => {
|
|
857
|
+
let videoListArr = JSON.parse((await callMethod('GetVideoDeviceList', {
|
|
858
|
+
// 这个参数是 C++ 要使用的引用参数,随便传个整型就行
|
|
859
|
+
device_count: 1
|
|
860
|
+
})).msg).ret;
|
|
861
|
+
let videoList = [];
|
|
862
|
+
for (let i = 0, len = videoListArr.length; i < len; i++) {
|
|
863
|
+
videoList.push({
|
|
864
|
+
deviceId: videoListArr[i].szDeviceId,
|
|
865
|
+
deviceName: videoListArr[i].szDeviceName,
|
|
866
|
+
isDefault: i === 0
|
|
867
|
+
});
|
|
868
|
+
deviceListReport.cameraList[videoListArr[i].szDeviceId] = videoListArr[i].szDeviceName;
|
|
869
|
+
}
|
|
870
|
+
if (!window.zbztAVSDK_device_checker_init) {
|
|
871
|
+
window.zbztAVSDK_device_checker_init = {};
|
|
872
|
+
}
|
|
873
|
+
if (!window.zbztAVSDK_device_checker_init.camera) {
|
|
874
|
+
window.zbztAVSDK_device_checker_init.camera = {};
|
|
875
|
+
}
|
|
876
|
+
window.zbztAVSDK_device_checker_init.camera.hasTest = true;
|
|
877
|
+
window.zbztAVSDK_device_checker_init.camera.list = videoList;
|
|
878
|
+
return videoList;
|
|
879
|
+
};
|
|
880
|
+
|
|
881
|
+
/**
|
|
882
|
+
* @function 指定使用的摄像头
|
|
883
|
+
* @param deviceId:String 摄像头 id,必选
|
|
884
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
885
|
+
* @param operationType:String 操作类型,可选
|
|
886
|
+
* 'device_error' -> 设备出错处理,'plug_and_unplug' -> 热插拔处理,
|
|
887
|
+
* 不传即是普通的设置摄像头设备的行为
|
|
888
|
+
* @return Promise | void
|
|
889
|
+
*/
|
|
890
|
+
export const setVideoDevice = async (args) => {
|
|
891
|
+
defaultApi.writeLog(`${JSON.stringify(args)}----setVideoDevice-zego----`);
|
|
892
|
+
let { deviceId, idx, operationType, deviceState, code, changedDeviceId } = args;
|
|
893
|
+
let deviceName = '';
|
|
894
|
+
let cameraData;
|
|
895
|
+
if (!deviceId) {
|
|
896
|
+
cameraData = await getVideoDeviceList();
|
|
897
|
+
// console.log('hsghsghsg0',cameraData);
|
|
898
|
+
if (cameraData.length) {
|
|
899
|
+
let hasGetCamare = false;
|
|
900
|
+
// console.log('hsghsghsg1',hasGetSpeaker);
|
|
901
|
+
for (let item of cameraData) {
|
|
902
|
+
if (item.isDefault) {
|
|
903
|
+
deviceId = item.deviceId;
|
|
904
|
+
deviceName = item.deviceName;
|
|
905
|
+
hasGetCamare = true;
|
|
906
|
+
break;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
// console.log('hsghsghsg2',hasGetSpeaker);
|
|
910
|
+
if (!hasGetCamare) {
|
|
911
|
+
deviceId = cameraData[0].deviceId;
|
|
912
|
+
deviceName = cameraData[0].deviceName;
|
|
913
|
+
// console.log('hsghsghsg91',deviceId);
|
|
914
|
+
}
|
|
915
|
+
} else {
|
|
916
|
+
deviceId = '';
|
|
917
|
+
}
|
|
918
|
+
// console.log('hsghsghsg1',deviceId);
|
|
919
|
+
if (deviceId === '') {
|
|
920
|
+
NOTICE.noDevice({
|
|
921
|
+
deviceType: 'camera'
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
window.zbztAVSDK_device_checker_init.camera.use = deviceId;
|
|
926
|
+
window.zbztAVSDK_device_checker_init.camera.name = deviceListReport.cameraList[deviceId];
|
|
927
|
+
if (typeof idx === 'undefined') {
|
|
928
|
+
idx = 0;
|
|
929
|
+
}
|
|
930
|
+
try {
|
|
931
|
+
dataReport.setDevice({
|
|
932
|
+
device_type: 1,
|
|
933
|
+
device_id: deviceId,
|
|
934
|
+
device_name: deviceListReport.cameraList[deviceId],
|
|
935
|
+
operationType,
|
|
936
|
+
fore_state: operationType == 'hotPlug' ? deviceState + 1 : '-'
|
|
937
|
+
});
|
|
938
|
+
} catch (e) { };
|
|
939
|
+
await callMethod('SetVideoDevice', {
|
|
940
|
+
pszDeviceID: deviceId,
|
|
941
|
+
idx
|
|
942
|
+
});
|
|
943
|
+
if (operationType == 'hotPlug' || operationType == 'deviceError') {
|
|
944
|
+
if (!cameraData) {
|
|
945
|
+
cameraData = await getVideoDeviceList();
|
|
946
|
+
deviceName = deviceListReport.cameraList[deviceId];
|
|
947
|
+
}
|
|
948
|
+
NOTICE[operationType]({
|
|
949
|
+
deviceType: 'camera',
|
|
950
|
+
useDeviceId: deviceId,
|
|
951
|
+
useDeviceName: deviceName,
|
|
952
|
+
deviceList: cameraData,
|
|
953
|
+
messge: code,
|
|
954
|
+
deviceState,
|
|
955
|
+
changedDeviceId
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
try {
|
|
959
|
+
NOTICE.useredCamera({
|
|
960
|
+
deviceId,
|
|
961
|
+
deviceName
|
|
962
|
+
});
|
|
963
|
+
} catch (e) { };
|
|
964
|
+
};
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* @function 开/关摄像头
|
|
968
|
+
* @param enable:Boolean false -> 关闭,true -> 打开,必选
|
|
969
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
970
|
+
* @return Promise | void
|
|
971
|
+
*/
|
|
972
|
+
export const enableCamera = (enable, idx = 0) => {
|
|
973
|
+
// try {
|
|
974
|
+
// dataReport.deviceChange({
|
|
975
|
+
// device: 1,
|
|
976
|
+
// device_state: enable? 1 : 0
|
|
977
|
+
// });
|
|
978
|
+
// } catch (e){};
|
|
979
|
+
return callMethod('EnableCamera', {
|
|
980
|
+
bEnable: enable,
|
|
981
|
+
idx
|
|
982
|
+
});
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* @function 开/关麦克风
|
|
987
|
+
* @param bEnable:Boolean false -> 关闭,true -> 打开,必选
|
|
988
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
989
|
+
* @return Promise | void
|
|
990
|
+
*/
|
|
991
|
+
export const enableMic = async (bEnable, idx) => {
|
|
992
|
+
defaultApi.writeLog('enableMic --start');
|
|
993
|
+
isNoticeMicVolumeZego = bEnable;
|
|
994
|
+
// if (bEnable) {
|
|
995
|
+
// await setMicDeviceMute(false);
|
|
996
|
+
// defaultApi.writeLog('openMic and muteFalse');
|
|
997
|
+
// }
|
|
998
|
+
if (typeof idx === 'undefined') {
|
|
999
|
+
idx = 0;
|
|
1000
|
+
}
|
|
1001
|
+
// try {
|
|
1002
|
+
// dataReport.deviceChange({
|
|
1003
|
+
// device: 2,
|
|
1004
|
+
// device_state: bEnable ? 1 : 0
|
|
1005
|
+
// });
|
|
1006
|
+
// } catch (e){};
|
|
1007
|
+
return callMethod('EnableMic', {
|
|
1008
|
+
bEnable,
|
|
1009
|
+
idx
|
|
1010
|
+
});
|
|
1011
|
+
};
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* @function 是否推声音
|
|
1015
|
+
* @param mute:Boolean true/不推声音,false/推声音,必选
|
|
1016
|
+
* @return Promise | void
|
|
1017
|
+
*/
|
|
1018
|
+
export const setMuteStreamAudio = (mute) => {
|
|
1019
|
+
return callMethod('MuteStreamAudio', { mute });
|
|
1020
|
+
};
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* @function 是否推画面
|
|
1024
|
+
* @param mute:Boolean true/不推画面,false/推画面,必选
|
|
1025
|
+
* @return Promise | void
|
|
1026
|
+
*/
|
|
1027
|
+
export const setMuteStreamVideo = (mute) => {
|
|
1028
|
+
return callMethod('MuteStreamVideo', { mute });
|
|
1029
|
+
};
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* @function 获取音频设备
|
|
1033
|
+
* @param deviceType:Number 音频设备类型,0 -> 麦克风,1 -> 扬声器,必选
|
|
1034
|
+
* @return Promise | void
|
|
1035
|
+
*/
|
|
1036
|
+
export const getAudioDeviceList = (deviceType) => {
|
|
1037
|
+
return callMethod('GetAudioDeviceList', {
|
|
1038
|
+
deviceType,
|
|
1039
|
+
// 这个参数是 C++ 要使用的引用参数,随便传个整型就行
|
|
1040
|
+
device_count: 0
|
|
1041
|
+
});
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* @function 指定音频设备
|
|
1046
|
+
* @param deviceType:Number 音频设备类型,0 -> 麦克风,1 -> 扬声器,必选
|
|
1047
|
+
* @param deviceId:String 音频设备 id,必选
|
|
1048
|
+
* @return Promise | void
|
|
1049
|
+
*/
|
|
1050
|
+
export const setAudioDevice = (deviceType, deviceId) => {
|
|
1051
|
+
if (deviceType == 0) {
|
|
1052
|
+
window.zbztAVSDK_device_checker_init.microphone.use = deviceId;
|
|
1053
|
+
} else {
|
|
1054
|
+
window.zbztAVSDK_device_checker_init.speaker.use = deviceId;
|
|
1055
|
+
}
|
|
1056
|
+
return callMethod('SetAudioDevice', {
|
|
1057
|
+
deviceType,
|
|
1058
|
+
pszDeviceID: deviceId
|
|
1059
|
+
}).then((result) => {
|
|
1060
|
+
if (deviceType == 1 && result.code === 0) {
|
|
1061
|
+
NOTICE.speakerChanged({
|
|
1062
|
+
deviceId
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
return result;
|
|
1066
|
+
});
|
|
1067
|
+
};
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* 获取当前扬声器设备id
|
|
1071
|
+
* @return {String} 当前扬声器设备id
|
|
1072
|
+
*/
|
|
1073
|
+
const getCurrentSpeakerDevice = () => {
|
|
1074
|
+
defaultApi.writeLog(`avsdk ZEGO::getSpeakerDevice ${usingAudioDeviceId.speaker}`);
|
|
1075
|
+
return usingAudioDeviceId.speaker;
|
|
1076
|
+
};
|
|
1077
|
+
|
|
1078
|
+
/**
|
|
1079
|
+
* @function 获取扬声器列表
|
|
1080
|
+
* @return Promise | void
|
|
1081
|
+
*/
|
|
1082
|
+
export const getSpeakerDeviceList = async () => {
|
|
1083
|
+
const defaultSpeakerId = JSON.parse((await getDefaultSpeaker()).msg).ret.deviceId;
|
|
1084
|
+
let speakerListArr = JSON.parse((await getAudioDeviceList(1)).msg).ret;
|
|
1085
|
+
let speakerList = [];
|
|
1086
|
+
for (let i = 0, len = speakerListArr.length; i < len; i++) {
|
|
1087
|
+
speakerList.push({
|
|
1088
|
+
deviceId: speakerListArr[i].szDeviceId,
|
|
1089
|
+
deviceName: speakerListArr[i].szDeviceName,
|
|
1090
|
+
isDefault: defaultSpeakerId === speakerListArr[i].szDeviceId
|
|
1091
|
+
});
|
|
1092
|
+
deviceListReport.speakerList[speakerListArr[i].szDeviceId] = speakerListArr[i].szDeviceName;
|
|
1093
|
+
|
|
1094
|
+
}
|
|
1095
|
+
if (!window.zbztAVSDK_device_checker_init) {
|
|
1096
|
+
window.zbztAVSDK_device_checker_init = {};
|
|
1097
|
+
}
|
|
1098
|
+
if (!window.zbztAVSDK_device_checker_init.speaker) {
|
|
1099
|
+
window.zbztAVSDK_device_checker_init.speaker = {};
|
|
1100
|
+
}
|
|
1101
|
+
window.zbztAVSDK_device_checker_init.speaker.hasTest = true;
|
|
1102
|
+
window.zbztAVSDK_device_checker_init.speaker.list = speakerList;
|
|
1103
|
+
return speakerList;
|
|
1104
|
+
};
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* @function 指定扬声器
|
|
1108
|
+
* @param deviceId:String 扬声器 id,必选
|
|
1109
|
+
* @param operationType:String 操作类型,可选
|
|
1110
|
+
* 'device_error' -> 设备出错处理,'plug_and_unplug' -> 热插拔处理,
|
|
1111
|
+
* 不传即是普通的设置扬声器设备的行为
|
|
1112
|
+
* @return Promise | void
|
|
1113
|
+
*/
|
|
1114
|
+
export const setSpeakerDevice = async (args) => {
|
|
1115
|
+
defaultApi.writeLog(`${JSON.stringify(args)}----setSpeakerDevice-zego----`);
|
|
1116
|
+
// console.log('hsghsghsg999',args);
|
|
1117
|
+
let { deviceId, operationType, deviceState, code, changedDeviceId } = args;
|
|
1118
|
+
let deviceName = '';
|
|
1119
|
+
let speakerData;
|
|
1120
|
+
if (!deviceId) {
|
|
1121
|
+
speakerData = await getSpeakerDeviceList();
|
|
1122
|
+
// console.log('hsghsghsg0',speakerData.length);
|
|
1123
|
+
if (speakerData.length) {
|
|
1124
|
+
let hasGetSpeaker = false;
|
|
1125
|
+
// console.log('hsghsghsg1',hasGetSpeaker);
|
|
1126
|
+
for (let item of speakerData) {
|
|
1127
|
+
if (item.isDefault) {
|
|
1128
|
+
deviceId = item.deviceId;
|
|
1129
|
+
deviceName = item.deviceName;
|
|
1130
|
+
hasGetSpeaker = true;
|
|
1131
|
+
break;
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
// console.log('hsghsghsg2',hasGetSpeaker);
|
|
1135
|
+
if (!hasGetSpeaker) {
|
|
1136
|
+
deviceId = speakerData[0].deviceId;
|
|
1137
|
+
deviceName = speakerData[0].deviceName;
|
|
1138
|
+
// console.log('hsghsghsg91',deviceId);
|
|
1139
|
+
}
|
|
1140
|
+
} else {
|
|
1141
|
+
deviceId = '';
|
|
1142
|
+
}
|
|
1143
|
+
if (deviceId === '') {
|
|
1144
|
+
NOTICE.noDevice({
|
|
1145
|
+
deviceType: 'speaker'
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
// console.log('hsghsghsg999',deviceId);
|
|
1150
|
+
try {
|
|
1151
|
+
dataReport.setDevice({
|
|
1152
|
+
device_type: 3,
|
|
1153
|
+
device_id: deviceId,
|
|
1154
|
+
device_name: deviceListReport.speakerList[deviceId],
|
|
1155
|
+
operationType,
|
|
1156
|
+
fore_state: operationType == 'hotPlug' ? deviceState + 1 : '-'
|
|
1157
|
+
});
|
|
1158
|
+
window.zbztAVSDK_device_checker_init.speaker.name = deviceListReport.speakerList[deviceId];
|
|
1159
|
+
} catch (e) { };
|
|
1160
|
+
usingAudioDeviceId.speaker = deviceId;
|
|
1161
|
+
await setAudioDevice(1, deviceId);
|
|
1162
|
+
if (operationType == 'hotPlug' || operationType == 'deviceError') {
|
|
1163
|
+
if (!speakerData) {
|
|
1164
|
+
speakerData = await getSpeakerDeviceList();
|
|
1165
|
+
deviceName = deviceListReport.speakerList[deviceId];
|
|
1166
|
+
}
|
|
1167
|
+
NOTICE[operationType]({
|
|
1168
|
+
deviceType: 'speaker',
|
|
1169
|
+
useDeviceId: deviceId,
|
|
1170
|
+
useDeviceName: deviceName,
|
|
1171
|
+
deviceList: speakerData,
|
|
1172
|
+
message: code,
|
|
1173
|
+
deviceState,
|
|
1174
|
+
changedDeviceId
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
|
|
1179
|
+
/**
|
|
1180
|
+
* @function 获取扬声器音量
|
|
1181
|
+
* @return Promise | void
|
|
1182
|
+
*/
|
|
1183
|
+
export const getSpeakerDeviceVolume = () => {
|
|
1184
|
+
return callMethod('GetSpeakerDeviceVolume', {
|
|
1185
|
+
deviceId: usingAudioDeviceId.speaker
|
|
1186
|
+
});
|
|
1187
|
+
};
|
|
1188
|
+
|
|
1189
|
+
/**
|
|
1190
|
+
* @function 设置扬声器音量
|
|
1191
|
+
* @param volume:Number 扬声器音量,必选
|
|
1192
|
+
* @return Promise | void
|
|
1193
|
+
*/
|
|
1194
|
+
export const setSpeakerDeviceVolume = (volume) => {
|
|
1195
|
+
return callMethod('SetSpeakerDeviceVolume', {
|
|
1196
|
+
deviceId: usingAudioDeviceId.speaker,
|
|
1197
|
+
volume
|
|
1198
|
+
});
|
|
1199
|
+
};
|
|
1200
|
+
|
|
1201
|
+
/**
|
|
1202
|
+
* @function 设置扬声器静音
|
|
1203
|
+
* @param mute:Boolean 必选
|
|
1204
|
+
* @return Promise | void
|
|
1205
|
+
*/
|
|
1206
|
+
export const setSpeakerDeviceMute = (mute) => {
|
|
1207
|
+
// try {
|
|
1208
|
+
// dataReport.deviceChange({
|
|
1209
|
+
// device: 3,
|
|
1210
|
+
// device_state: mute ? 0 :1
|
|
1211
|
+
// });
|
|
1212
|
+
// } catch (e){};
|
|
1213
|
+
return callMethod('SetSpeakerDeviceMute', {
|
|
1214
|
+
deviceId: usingAudioDeviceId.speaker,
|
|
1215
|
+
mute
|
|
1216
|
+
});
|
|
1217
|
+
};
|
|
1218
|
+
|
|
1219
|
+
/**
|
|
1220
|
+
* @function 获取麦克风列表
|
|
1221
|
+
* @return Promise | void
|
|
1222
|
+
*/
|
|
1223
|
+
export const getMicrophoneDeviceList = async () => {
|
|
1224
|
+
const defaultMicrophoneId = JSON.parse((await getDefaultMicrophone()).msg).ret.deviceId;
|
|
1225
|
+
let microphoneListArr = JSON.parse((await getAudioDeviceList(0)).msg).ret;
|
|
1226
|
+
let microphoneList = [];
|
|
1227
|
+
for (let i = 0, len = microphoneListArr.length; i < len; i++) {
|
|
1228
|
+
microphoneList.push({
|
|
1229
|
+
deviceId: microphoneListArr[i].szDeviceId,
|
|
1230
|
+
deviceName: microphoneListArr[i].szDeviceName,
|
|
1231
|
+
isDefault: defaultMicrophoneId === microphoneListArr[i].szDeviceId
|
|
1232
|
+
});
|
|
1233
|
+
deviceListReport.micList[microphoneListArr[i].szDeviceId] = microphoneListArr[i].szDeviceName;
|
|
1234
|
+
|
|
1235
|
+
}
|
|
1236
|
+
if (!window.zbztAVSDK_device_checker_init) {
|
|
1237
|
+
window.zbztAVSDK_device_checker_init = {};
|
|
1238
|
+
}
|
|
1239
|
+
if (!window.zbztAVSDK_device_checker_init.microphone) {
|
|
1240
|
+
window.zbztAVSDK_device_checker_init.microphone = {};
|
|
1241
|
+
}
|
|
1242
|
+
window.zbztAVSDK_device_checker_init.microphone.hasTest = true;
|
|
1243
|
+
window.zbztAVSDK_device_checker_init.microphone.list = microphoneList;
|
|
1244
|
+
return microphoneList;
|
|
1245
|
+
};
|
|
1246
|
+
|
|
1247
|
+
/**
|
|
1248
|
+
* @function 指定麦克风
|
|
1249
|
+
* @param deviceId:String 麦克风 id,必选
|
|
1250
|
+
* @param operationType:String 操作类型,可选
|
|
1251
|
+
* 'device_error' -> 设备出错处理,'plug_and_unplug' -> 热插拔处理,
|
|
1252
|
+
* 不传即是普通的设置麦克风设备的行为
|
|
1253
|
+
* @return Promise | void
|
|
1254
|
+
*/
|
|
1255
|
+
export const setMicrophoneDevice = async (args) => {
|
|
1256
|
+
defaultApi.writeLog(`${JSON.stringify(args)}----setMicrophoneDevice-zego----`);
|
|
1257
|
+
let { deviceId, operationType, deviceState, code, changedDeviceId } = args;
|
|
1258
|
+
let deviceName = '';
|
|
1259
|
+
let microPhoneData;
|
|
1260
|
+
if (!deviceId) {
|
|
1261
|
+
microPhoneData = await getMicrophoneDeviceList();
|
|
1262
|
+
if (microPhoneData.length) {
|
|
1263
|
+
let hasGetMicrophone = false;
|
|
1264
|
+
for (let item of microPhoneData) {
|
|
1265
|
+
if (item.isDefault) {
|
|
1266
|
+
deviceId = item.deviceId;
|
|
1267
|
+
deviceName = item.deviceName;
|
|
1268
|
+
hasGetMicrophone = true;
|
|
1269
|
+
break;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
if (!hasGetMicrophone) {
|
|
1273
|
+
deviceId = microPhoneData[0].deviceId;
|
|
1274
|
+
deviceName = microPhoneData[0].deviceName;
|
|
1275
|
+
}
|
|
1276
|
+
} else {
|
|
1277
|
+
deviceId = '';
|
|
1278
|
+
}
|
|
1279
|
+
if (deviceId === '') {
|
|
1280
|
+
NOTICE.noDevice({
|
|
1281
|
+
deviceType: 'microphone'
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
try {
|
|
1286
|
+
dataReport.setDevice({
|
|
1287
|
+
device_type: 2,
|
|
1288
|
+
device_id: deviceId,
|
|
1289
|
+
device_name: deviceListReport.micList[deviceId],
|
|
1290
|
+
operationType,
|
|
1291
|
+
fore_state: operationType == 'hotPlug' ? deviceState + 1 : '-'
|
|
1292
|
+
});
|
|
1293
|
+
window.zbztAVSDK_device_checker_init.microphone.name = deviceListReport.micList[deviceId];
|
|
1294
|
+
} catch (e) { };
|
|
1295
|
+
usingAudioDeviceId.microphone = deviceId;
|
|
1296
|
+
await setAudioDevice(0, deviceId);
|
|
1297
|
+
await setAudioVolumeNotify(0, deviceId);
|
|
1298
|
+
if (operationType == 'hotPlug' || operationType == 'deviceError') {
|
|
1299
|
+
if (!microPhoneData) {
|
|
1300
|
+
microPhoneData = await getMicrophoneDeviceList();
|
|
1301
|
+
deviceName = deviceListReport.micList[deviceId];
|
|
1302
|
+
}
|
|
1303
|
+
NOTICE[operationType]({
|
|
1304
|
+
deviceType: 'microphone',
|
|
1305
|
+
useDeviceId: deviceId,
|
|
1306
|
+
useDeviceName: deviceName,
|
|
1307
|
+
deviceList: microPhoneData,
|
|
1308
|
+
message: code,
|
|
1309
|
+
deviceState,
|
|
1310
|
+
changedDeviceId
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1314
|
+
|
|
1315
|
+
/**
|
|
1316
|
+
* @function 获取麦克风音量
|
|
1317
|
+
* @return Promise | void
|
|
1318
|
+
*/
|
|
1319
|
+
export const getMicDeviceVolume = () => {
|
|
1320
|
+
return callMethod('GetMicDeviceVolume', {
|
|
1321
|
+
deviceId: usingAudioDeviceId.microphone
|
|
1322
|
+
});
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* @function 设置麦克风音量
|
|
1327
|
+
* @param volume:Number 麦克风音量,必选
|
|
1328
|
+
* @return Promise | void
|
|
1329
|
+
*/
|
|
1330
|
+
export const setMicDeviceVolume = (volume) => {
|
|
1331
|
+
return callMethod('SetMicDeviceVolume', {
|
|
1332
|
+
deviceId: usingAudioDeviceId.microphone,
|
|
1333
|
+
volume
|
|
1334
|
+
});
|
|
1335
|
+
};
|
|
1336
|
+
|
|
1337
|
+
/**
|
|
1338
|
+
* @function 设置麦克风静音
|
|
1339
|
+
* @param mute:Boolean 必选
|
|
1340
|
+
* @return Promise | void
|
|
1341
|
+
*/
|
|
1342
|
+
export const setMicDeviceMute = (mute) => {
|
|
1343
|
+
return callMethod('SetMicDeviceMute', {
|
|
1344
|
+
deviceId: usingAudioDeviceId.microphone,
|
|
1345
|
+
mute
|
|
1346
|
+
});
|
|
1347
|
+
};
|
|
1348
|
+
|
|
1349
|
+
//设置采集扬声器声音
|
|
1350
|
+
export const setAudioSpeakerCapture = async (bEnable) => {
|
|
1351
|
+
return callMethod('EnableMixSystemPlayout', {
|
|
1352
|
+
bEnable,
|
|
1353
|
+
});
|
|
1354
|
+
};
|
|
1355
|
+
|
|
1356
|
+
// //采集扬声器
|
|
1357
|
+
// export const setAudioSpeakerCapture2 = async (bEnable) => {
|
|
1358
|
+
// return callMethod('MixEnginePlayout', {
|
|
1359
|
+
// bEnable,
|
|
1360
|
+
// });
|
|
1361
|
+
// };
|
|
1362
|
+
|
|
1363
|
+
/**
|
|
1364
|
+
* @function 获取当前应用程序音量
|
|
1365
|
+
* @return Promise | void
|
|
1366
|
+
*/
|
|
1367
|
+
export const getSpeakerSimpleVolume = () => {
|
|
1368
|
+
return callMethod('GetSpeakerSimpleVolume', {
|
|
1369
|
+
deviceId: usingAudioDeviceId.speaker
|
|
1370
|
+
});
|
|
1371
|
+
};
|
|
1372
|
+
|
|
1373
|
+
/**
|
|
1374
|
+
* @function 设置视频预览载体 view
|
|
1375
|
+
* @param idx:Number 直播通道,可选,默认为 0
|
|
1376
|
+
* @return Promise | void
|
|
1377
|
+
*/
|
|
1378
|
+
export const setPreviewView = (idx) => {
|
|
1379
|
+
if (typeof idx === 'undefined') {
|
|
1380
|
+
idx = 0;
|
|
1381
|
+
}
|
|
1382
|
+
return callMethod('SetPreviewView', {
|
|
1383
|
+
idx
|
|
1384
|
+
});
|
|
1385
|
+
};
|
|
1386
|
+
|
|
1387
|
+
/**
|
|
1388
|
+
* @function 设置本地预览视频视图的模式
|
|
1389
|
+
* @param mode:Number 模式,必选,0 | 1 | 2
|
|
1390
|
+
* 0:等比缩放,可能有黑边
|
|
1391
|
+
* 1:等比缩放填充整View,可能有部分被裁减
|
|
1392
|
+
* 2:填充整个View
|
|
1393
|
+
* @param idx:Number 直播通道,可选,默认为 0
|
|
1394
|
+
* @return Promise | void
|
|
1395
|
+
*/
|
|
1396
|
+
export const setPreviewViewMode = (mode, idx) => {
|
|
1397
|
+
if (typeof idx === 'undefined') {
|
|
1398
|
+
idx = 0;
|
|
1399
|
+
}
|
|
1400
|
+
return callMethod('SetPreviewViewMode', {
|
|
1401
|
+
mode,
|
|
1402
|
+
idx
|
|
1403
|
+
});
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1406
|
+
/**
|
|
1407
|
+
* @function 开启预览
|
|
1408
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1409
|
+
* @return Promise | void
|
|
1410
|
+
*/
|
|
1411
|
+
export const startPreview = (idx) => {
|
|
1412
|
+
if (typeof idx === 'undefined') {
|
|
1413
|
+
idx = 0;
|
|
1414
|
+
}
|
|
1415
|
+
return callMethod('StartPreview', {
|
|
1416
|
+
idx
|
|
1417
|
+
});
|
|
1418
|
+
};
|
|
1419
|
+
|
|
1420
|
+
/**
|
|
1421
|
+
* @function 停止预览
|
|
1422
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1423
|
+
* @return Promise | void
|
|
1424
|
+
*/
|
|
1425
|
+
export const stopPreview = (idx) => {
|
|
1426
|
+
if (typeof idx === 'undefined') {
|
|
1427
|
+
idx = 0;
|
|
1428
|
+
}
|
|
1429
|
+
return callMethod('StopPreview', {
|
|
1430
|
+
idx
|
|
1431
|
+
});
|
|
1432
|
+
};
|
|
1433
|
+
|
|
1434
|
+
/**
|
|
1435
|
+
* @function 设置当前应用程序音量
|
|
1436
|
+
* @param volume:Number 应用程序音量,必选
|
|
1437
|
+
* @return Promise | void
|
|
1438
|
+
*/
|
|
1439
|
+
export const setSpeakerSimpleVolume = (volume) => {
|
|
1440
|
+
return callMethod('SetSpeakerSimpleVolume', {
|
|
1441
|
+
deviceId: usingAudioDeviceId.speaker,
|
|
1442
|
+
volume
|
|
1443
|
+
});
|
|
1444
|
+
};
|
|
1445
|
+
|
|
1446
|
+
/**
|
|
1447
|
+
* @function 设置当前应用程序静音
|
|
1448
|
+
* @param mute:Boolean 是否静音,必选
|
|
1449
|
+
* @return Promise | void
|
|
1450
|
+
*/
|
|
1451
|
+
export const setSpeakerSimpleMute = (mute) => {
|
|
1452
|
+
return callMethod('SetSpeakerSimpleMute', {
|
|
1453
|
+
deviceId: usingAudioDeviceId.speaker,
|
|
1454
|
+
mute
|
|
1455
|
+
});
|
|
1456
|
+
};
|
|
1457
|
+
|
|
1458
|
+
/**
|
|
1459
|
+
* @function 开启本地或者远程的视频视图
|
|
1460
|
+
* @param isLocal:Boolean 是否是本地的视频预览,必选
|
|
1461
|
+
* @param streamId:String 要拉取的视频流的 id,可选,只有拉取远程的视频流的时候才是必选的
|
|
1462
|
+
* @param domId:String <video> 标签的 id,可选
|
|
1463
|
+
* 如果传了 domId,就把视频绑定到对应的 <video> 标签上
|
|
1464
|
+
* @return Promise 可从 Promise 中获取 src,Promise.then((src) => {})
|
|
1465
|
+
*/
|
|
1466
|
+
export const startLocalOrRemotePreview = async (isLocal, streamId, domId, isTeacherNewWindowPreview) => {
|
|
1467
|
+
defaultApi.writeLog(`${streamId}----streamId-zego----`);
|
|
1468
|
+
let playChannel = null;
|
|
1469
|
+
let isUpdateChromeVersion = await util.getChromeVersion();
|
|
1470
|
+
// zego 的本地视频预览必须使用 -1 通道,为了与远程的视频预览兼容使用,此处需要判断是否是本地预览
|
|
1471
|
+
if (isLocal) {
|
|
1472
|
+
playChannel = -1;
|
|
1473
|
+
} else {
|
|
1474
|
+
playChannel = streamIdToPreviewId[streamId];
|
|
1475
|
+
}
|
|
1476
|
+
const externalConstraints = {
|
|
1477
|
+
audio: false,
|
|
1478
|
+
video: {
|
|
1479
|
+
mandatory: {
|
|
1480
|
+
chromeMediaSource: 'external',
|
|
1481
|
+
chromeMediaSourceId: `ems://zego/${isLocal || isTeacherNewWindowPreview ? -1 : streamId}`
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
};
|
|
1485
|
+
defaultApi.writeLog(`avsdk ZEGO::startLocalOrRemotePreview streamId: ${streamId} uiChnIndex: ${playChannel}`);
|
|
1486
|
+
|
|
1487
|
+
return new Promise((resolve, reject) => {
|
|
1488
|
+
const handleExternalSuccess = (stream) => {
|
|
1489
|
+
defaultApi.writeLog(`${stream}----stream-zego----`);
|
|
1490
|
+
stream.oninactive = () => {
|
|
1491
|
+
defaultApi.writeLog('Stream inactive');
|
|
1492
|
+
};
|
|
1493
|
+
const src = isUpdateChromeVersion ? stream : window.URL.createObjectURL(stream);
|
|
1494
|
+
if (domId && document.querySelector(domId)) {
|
|
1495
|
+
if (isUpdateChromeVersion) {
|
|
1496
|
+
document.querySelector(domId).srcObject = src;
|
|
1497
|
+
} else {
|
|
1498
|
+
document.querySelector(domId).src = src;
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
defaultApi.writeLog(`setVidoeSrc, streamId:${streamId}, domId: ${domId}, src: ${src}`);
|
|
1502
|
+
resolve(src);
|
|
1503
|
+
};
|
|
1504
|
+
|
|
1505
|
+
const handleExternalError = (error) => {
|
|
1506
|
+
if (error.name === 'ConstraintNotSatisfiedError') {
|
|
1507
|
+
console.error('ConstraintNotSatisfiedError');
|
|
1508
|
+
} else if (error.name === 'PermissionDeniedError') {
|
|
1509
|
+
console.error(
|
|
1510
|
+
'Permissions have not been granted to use your camera and ' +
|
|
1511
|
+
'microphone, you need to allow the page access to your devices in ' +
|
|
1512
|
+
'order for the demo to work.'
|
|
1513
|
+
);
|
|
1514
|
+
}
|
|
1515
|
+
console.error(`getUserMedia error: ${error.name}`, error);
|
|
1516
|
+
if (domId) {
|
|
1517
|
+
document.querySelector(domId).src = '';
|
|
1518
|
+
}
|
|
1519
|
+
reject('');
|
|
1520
|
+
};
|
|
1521
|
+
|
|
1522
|
+
if (navigator.webkitGetUserMedia) {
|
|
1523
|
+
navigator.webkitGetUserMedia(
|
|
1524
|
+
externalConstraints,
|
|
1525
|
+
handleExternalSuccess,
|
|
1526
|
+
handleExternalError
|
|
1527
|
+
);
|
|
1528
|
+
}
|
|
1529
|
+
});
|
|
1530
|
+
};
|
|
1531
|
+
|
|
1532
|
+
/**
|
|
1533
|
+
* @function 设置本地预览以及推流的视频帧率
|
|
1534
|
+
* @param nFps:Number 帧率,必选
|
|
1535
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1536
|
+
* @return Promise | void
|
|
1537
|
+
*/
|
|
1538
|
+
export const setVideoFPS = (nFps, idx) => {
|
|
1539
|
+
if (typeof idx === 'undefined') {
|
|
1540
|
+
idx = 0;
|
|
1541
|
+
}
|
|
1542
|
+
return callMethod('SetVideoFPS', {
|
|
1543
|
+
nFps,
|
|
1544
|
+
idx
|
|
1545
|
+
});
|
|
1546
|
+
};
|
|
1547
|
+
|
|
1548
|
+
/**
|
|
1549
|
+
* @function 设置本地预览以及推流的视频码率
|
|
1550
|
+
* @param nBitrate:Number 码率,必选
|
|
1551
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1552
|
+
* @return Promise | void
|
|
1553
|
+
*/
|
|
1554
|
+
export const setVideoBitrate = (nBitrate, idx) => {
|
|
1555
|
+
if (typeof idx === 'undefined') {
|
|
1556
|
+
idx = 0;
|
|
1557
|
+
}
|
|
1558
|
+
return callMethod('SetVideoBitrate', {
|
|
1559
|
+
nBitrate,
|
|
1560
|
+
idx
|
|
1561
|
+
});
|
|
1562
|
+
};
|
|
1563
|
+
|
|
1564
|
+
/**
|
|
1565
|
+
* @function 设置本地预览以及推流的音频码率
|
|
1566
|
+
* @param bitrate:Number 码率,必选
|
|
1567
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1568
|
+
* @return Promise | void
|
|
1569
|
+
*/
|
|
1570
|
+
export const setAudioBitrate = (bitrate, idx) => {
|
|
1571
|
+
if (typeof idx === 'undefined') {
|
|
1572
|
+
idx = 0;
|
|
1573
|
+
}
|
|
1574
|
+
return callMethod('SetAudioBitrate', {
|
|
1575
|
+
bitrate,
|
|
1576
|
+
idx
|
|
1577
|
+
});
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
/**
|
|
1581
|
+
* @function 设置本地预览的视频分辨率
|
|
1582
|
+
* @param nWidth:Number 分辨率宽,必选
|
|
1583
|
+
* @param nHeight:Numnber 分辨率高,必选
|
|
1584
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1585
|
+
* @return Promise | void
|
|
1586
|
+
*/
|
|
1587
|
+
export const setCameraParam = async (nWidth, nHeight, idx) => {
|
|
1588
|
+
defaultApi.writeLog(`avsdk ZEGO::setCameraParam ${nWidth}--${nHeight}`);
|
|
1589
|
+
await enableCamera(false);
|
|
1590
|
+
await setVideoCaptureResolution(nWidth, nHeight, idx);
|
|
1591
|
+
return enableCamera(true);
|
|
1592
|
+
};
|
|
1593
|
+
|
|
1594
|
+
/**
|
|
1595
|
+
* @function 设置本地预览的视频分辨率
|
|
1596
|
+
* @param nWidth:Number 分辨率宽,必选
|
|
1597
|
+
* @param nHeight:Numnber 分辨率高,必选
|
|
1598
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1599
|
+
* @return Promise | void
|
|
1600
|
+
*/
|
|
1601
|
+
export const setVideoCaptureResolution = async (nWidth, nHeight, idx) => {
|
|
1602
|
+
if (typeof idx === 'undefined') {
|
|
1603
|
+
idx = 0;
|
|
1604
|
+
}
|
|
1605
|
+
await setCapturePipelineScaleMode();
|
|
1606
|
+
return callMethod('SetVideoCaptureResolution', {
|
|
1607
|
+
nWidth,
|
|
1608
|
+
nHeight,
|
|
1609
|
+
idx
|
|
1610
|
+
});
|
|
1611
|
+
};
|
|
1612
|
+
|
|
1613
|
+
export const setCapturePipelineScaleMode = () => {
|
|
1614
|
+
return callMethod('SetCapturePipelineScaleMode', {
|
|
1615
|
+
scaleMode: 1
|
|
1616
|
+
});
|
|
1617
|
+
};
|
|
1618
|
+
|
|
1619
|
+
/**
|
|
1620
|
+
* @function 设置推流的视频分辨率
|
|
1621
|
+
* @param nWidth:Number 分辨率宽,必选
|
|
1622
|
+
* @param nHeight:Numnber 分辨率高,必选
|
|
1623
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1624
|
+
* @return Promise | void
|
|
1625
|
+
*/
|
|
1626
|
+
export const setVideoEncodeResolution = (nWidth, nHeight, idx) => {
|
|
1627
|
+
if (typeof idx === 'undefined') {
|
|
1628
|
+
idx = 0;
|
|
1629
|
+
}
|
|
1630
|
+
return callMethod('SetVideoEncodeResolution', {
|
|
1631
|
+
nWidth,
|
|
1632
|
+
nHeight,
|
|
1633
|
+
idx
|
|
1634
|
+
});
|
|
1635
|
+
};
|
|
1636
|
+
|
|
1637
|
+
/**
|
|
1638
|
+
* @function 初始化
|
|
1639
|
+
* @param args:Object
|
|
1640
|
+
* {
|
|
1641
|
+
* extensionVersion, // String,扩展版本号,必选
|
|
1642
|
+
* appId, // String,Zego 秘钥,必选
|
|
1643
|
+
* appSignature, // String,签名,必选
|
|
1644
|
+
* businessType, // Number,业务类型,必选
|
|
1645
|
+
* userId, // Number,用户 id,必选
|
|
1646
|
+
* userName, // String,用户名,必选
|
|
1647
|
+
* roomId, // String,频道(房间) id,必选
|
|
1648
|
+
* nNetType // Number,网络类型,可选,默认为 1
|
|
1649
|
+
* }
|
|
1650
|
+
* classMode 0:小组课及其他 1:小班课 2:组合小班课
|
|
1651
|
+
* @return Promise
|
|
1652
|
+
*/
|
|
1653
|
+
export const init = async (args) => {
|
|
1654
|
+
defaultApi.writeLog(`avsdk ZEGO::init ${JSON.stringify(args)}`);
|
|
1655
|
+
currentRole = args.role;
|
|
1656
|
+
currentClassMode = args.classMode;
|
|
1657
|
+
currentGroupSdkType = args.sdkTypeGroup;
|
|
1658
|
+
localStreamId = args.streamId;
|
|
1659
|
+
await loadZego(args.extensionVersion);
|
|
1660
|
+
if (args.role === 'teacher' && args.mode === 1) {
|
|
1661
|
+
//坐立模式开启外部采集器,站立关闭外部采集器,只有小组课坐立模式才会调用,通过这个把rtmp数据给到zego或者rtc(头像),开启了外部采集,zego不会再本地采集数据
|
|
1662
|
+
await setVideoCaptureFactory(true);
|
|
1663
|
+
}
|
|
1664
|
+
// if (args.classMode === 1 || args.classMode === 2){
|
|
1665
|
+
// //如果是小班课保证关闭外部采集器,小组课上一步打开
|
|
1666
|
+
// await setVideoCaptureFactory(false);
|
|
1667
|
+
// };
|
|
1668
|
+
// 注册回调
|
|
1669
|
+
addListener(args.userId, args.userName, args.confId, args.nNetType, args.devices, args.role);
|
|
1670
|
+
//rtc同屏以及高光时刻,都开启音频外部采集,默认传1
|
|
1671
|
+
if (args.role === 'teacher') {
|
|
1672
|
+
defaultApi.writeLog('avsdk ZEGO::init_ open setAudioAuxSource');
|
|
1673
|
+
if (args.classMode === 1 || args.classMode === 2) {
|
|
1674
|
+
await setAudioAuxSource(1);
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
if (args.mode === 1 && ((isZegoGroupClass() && (args.role === 'teacher' || args.role === 'assistant')) || (isZegoCombinationClass() && args.role === 'assistant'))) {
|
|
1679
|
+
//zego推拉RTMP小组课,授课端坐立模式、辅导端坐立模式 或 zego推拉RTMP组合小班辅导端坐立模式,需要将摄像头渲染模式设置为 内部渲染+外部渲染
|
|
1680
|
+
await startEngine(args.appId, args.appSignature, args.businessType, 5); //5为摄像头内部渲染+外部渲染
|
|
1681
|
+
} else {
|
|
1682
|
+
await startEngine(args.appId, args.appSignature, args.businessType); //默认为摄像头外部渲染
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
//小班课 需要加载采集插件的输入数据,为了拼接zego头像
|
|
1686
|
+
if ((args.classMode === 1 || args.classMode === 2) && args.role === 'teacher') {
|
|
1687
|
+
screenStreamId = `${window.zbzt_sdk_init_params.institutionId}_${args.roomId}_${args.userId}_${args.live_id}_1`;
|
|
1688
|
+
loadCollectionInputEntry();
|
|
1689
|
+
};
|
|
1690
|
+
if (args.noiseSuppressMode == -2) {
|
|
1691
|
+
defaultApi.writeLog(`noiseSuppressMode 关闭噪声消除 ${args.noiseSuppressMod}`);
|
|
1692
|
+
await setEnableNoiseSuppress(false);
|
|
1693
|
+
} else if (args.noiseSuppressMode == -1) {
|
|
1694
|
+
defaultApi.writeLog(`noiseSuppressMode 由底层进行配置,js层不进行配置 ${args.noiseSuppressMode}`);
|
|
1695
|
+
} else {
|
|
1696
|
+
defaultApi.writeLog(`noiseSuppressMode 启动噪音消除,模式为: ${args.noiseSuppressMode}`);
|
|
1697
|
+
await setEnableNoiseSuppress(true);
|
|
1698
|
+
await setNoiseSuppressMode(+args.noiseSuppressMode);
|
|
1699
|
+
await enableTransientNoiseSuppress(true);
|
|
1700
|
+
};
|
|
1701
|
+
//aecMode为-1是关闭回音消除,云控下传
|
|
1702
|
+
if (args.aecMode == -2) {
|
|
1703
|
+
defaultApi.writeLog(`aecMode 关闭回音消除 ${args.aecMode}`);
|
|
1704
|
+
await setEnableAEC(false);
|
|
1705
|
+
} else if (args.aecMode == -1) {
|
|
1706
|
+
defaultApi.writeLog(`aecMode 由底层进行配置,js层不进行配置 ${args.aecMode}`);
|
|
1707
|
+
} else {
|
|
1708
|
+
defaultApi.writeLog(`aecMode 启动回音消除,模式为: ${args.aecMode}`);
|
|
1709
|
+
await setEnableAEC(true);
|
|
1710
|
+
await setAECMode(+args.aecMode);
|
|
1711
|
+
};
|
|
1712
|
+
await setVideoBitrate(args.encodeCaptureBitrate);
|
|
1713
|
+
await setAudioBitrate(args.encodeCaptureBitrate);
|
|
1714
|
+
await setVideoFPS(args.encodeCaptureFps);
|
|
1715
|
+
await setVideoCaptureResolution(args.previewResolutionWidth, args.previewResolutionHeight);
|
|
1716
|
+
await setVideoEncodeResolution(args.encodedResolutionWidth, args.encodedResolutionHeight);
|
|
1717
|
+
|
|
1718
|
+
if ((isZegoGroupClass() && (args.role === 'teacher' || args.role === 'assistant')) || (isZegoCombinationClass() && args.role === 'assistant')) {
|
|
1719
|
+
defaultApi.writeLog('zego小组课或辅导端组合小班课,用第二路推RTMP流,在pyzx初始化采集参数');
|
|
1720
|
+
} else {
|
|
1721
|
+
await setVideoBitrate(args.screenSameBitrate,1);
|
|
1722
|
+
await setVideoFPS(args.screenSameFps, 1);
|
|
1723
|
+
await setVideoCaptureResolution(args.screenSameResolutionWidth, args.screenSameResolutionHeight, 1);
|
|
1724
|
+
await setVideoEncodeResolution(args.screenSameResolutionWidth, args.screenSameResolutionHeight, 1);
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
// await setVideoBitrate(500000);
|
|
1728
|
+
// await setAudioBitrate(500000);
|
|
1729
|
+
// await setVideoFPS(15);
|
|
1730
|
+
// await setVideoCaptureResolution(1280, 720);
|
|
1731
|
+
// await setVideoEncodeResolution(1280, 720);
|
|
1732
|
+
await setSoundLevelMonitorCycle(500);
|
|
1733
|
+
if (isInitFinished) {
|
|
1734
|
+
defaultApi.writeLog(`avsdk ZEGO::init_isInitFinished ${isInitFinished}`);
|
|
1735
|
+
// await afterInitSDK(args.userId, args.userName, args.roomId, args.nNetType, JSON.parse(JSON.stringify(args.devices)));
|
|
1736
|
+
isInitFinished = 0;
|
|
1737
|
+
window.current_sdk_type = 'zego';
|
|
1738
|
+
defaultApi.writeLog('zego init finished current_sdk_type : zego');
|
|
1739
|
+
} else {
|
|
1740
|
+
await new Promise((resolve, reject) => {
|
|
1741
|
+
let timer = null;
|
|
1742
|
+
timer = setInterval(() => {
|
|
1743
|
+
if (isInitFinished) {
|
|
1744
|
+
isInitFinished = 0;
|
|
1745
|
+
clearInterval(timer);
|
|
1746
|
+
resolve();
|
|
1747
|
+
}
|
|
1748
|
+
}, 30);
|
|
1749
|
+
});
|
|
1750
|
+
window.current_sdk_type = 'zego';
|
|
1751
|
+
defaultApi.writeLog('zego init finished current_sdk_type : zego');
|
|
1752
|
+
}
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1755
|
+
/**
|
|
1756
|
+
* @function 在OnInitSDK事件之后调用的初始化方法
|
|
1757
|
+
* @param userId:Number 用户 id,必选
|
|
1758
|
+
* @param userName:String 用户名,必选
|
|
1759
|
+
* @param roomId:String 频道(房间) id,必选
|
|
1760
|
+
* @param nNetType:Number 网络类型,可选,默认为 1
|
|
1761
|
+
* @return Promise
|
|
1762
|
+
*/
|
|
1763
|
+
const afterInitSDK = async (userId, userName, confId, nNetType, devices, role, classMode) => {
|
|
1764
|
+
// 指定默认设备
|
|
1765
|
+
const usedDevices = window.zbztAVSDK_device_checker_init;
|
|
1766
|
+
const _devices = {
|
|
1767
|
+
camera: (devices && devices.camera) || (usedDevices && usedDevices.camera && usedDevices.camera.use) || '',
|
|
1768
|
+
microphone: (devices && devices.microphone) || (usedDevices && usedDevices.microphone && usedDevices.microphone.use) || '',
|
|
1769
|
+
speaker: (devices && devices.speaker) || (usedDevices && usedDevices.speaker && usedDevices.speaker.use) || ''
|
|
1770
|
+
};
|
|
1771
|
+
defaultApi.writeLog('avsdk ZEGO::afterInitSDK');
|
|
1772
|
+
await setDefaultDevice(_devices, 'default');
|
|
1773
|
+
await loginChannel(userId, userName, confId, nNetType);
|
|
1774
|
+
//设置拉流质量监控周期
|
|
1775
|
+
await setPlayQualityMoniterCycle(5000);
|
|
1776
|
+
await setPublishQualityMoniterCycle(5000);
|
|
1777
|
+
await setMediaSideFlags();
|
|
1778
|
+
defaultApi.writeLog(`test: isZegoGroupClass, ${isZegoGroupClass()}`);
|
|
1779
|
+
if ((isZegoGroupClass() && (role === 'teacher' || role === 'assistant')) || (isZegoCombinationClass() && role === 'assistant')) {
|
|
1780
|
+
defaultApi.writeLog(`avsdk ZEGO::afterInitSDK zegoRtmp, classMode: ${classMode} role: ${role}`);
|
|
1781
|
+
} else {
|
|
1782
|
+
// 初始化的时候不打开摄像头
|
|
1783
|
+
await enableCamera(false);
|
|
1784
|
+
// 只有调用了这个方法之后才开启关闭摄像头才有效
|
|
1785
|
+
await startPreview();
|
|
1786
|
+
}
|
|
1787
|
+
// 置为 1 表示初始化完成
|
|
1788
|
+
isInitFinished = 1;
|
|
1789
|
+
};
|
|
1790
|
+
|
|
1791
|
+
const deviceCheckerInitSDK = async () => {
|
|
1792
|
+
defaultApi.writeLog('avsdk ZEGO::deviceCheckerInitSDK');
|
|
1793
|
+
await enableCamera(false);
|
|
1794
|
+
await startPreview();
|
|
1795
|
+
isDeviceCheckInitFinished = 1;
|
|
1796
|
+
};
|
|
1797
|
+
|
|
1798
|
+
const getDeviceCheckInitStatus = () => {
|
|
1799
|
+
return isDeviceCheckInitFinished;
|
|
1800
|
+
};
|
|
1801
|
+
|
|
1802
|
+
const setDeviceCheckInitStatus = () => {
|
|
1803
|
+
isDeviceCheckInitFinished = 0;
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
//设置是否发送sei
|
|
1807
|
+
const setMediaSideFlags = (bStart = true, bOnlyAudioPublish = false, mediaInfoType = 2, seiSendType = 1, idx = 0) => {
|
|
1808
|
+
return callMethod('SetMediaSideFlags', { bStart, bOnlyAudioPublish, mediaInfoType, seiSendType, idx });
|
|
1809
|
+
};
|
|
1810
|
+
//设置拉流质量监控周期
|
|
1811
|
+
const setPlayQualityMoniterCycle = (timeInMS) => {
|
|
1812
|
+
return callMethod('SetPlayQualityMoniterCycle', { timeInMS });
|
|
1813
|
+
};
|
|
1814
|
+
|
|
1815
|
+
//设置推流质量监控周期
|
|
1816
|
+
const setPublishQualityMoniterCycle = (timeInMS) => {
|
|
1817
|
+
return callMethod('SetPublishQualityMoniterCycle', { timeInMS });
|
|
1818
|
+
};
|
|
1819
|
+
|
|
1820
|
+
/**
|
|
1821
|
+
* @function 设置默认的硬件设备,包括摄像头、麦克风以及扬声器
|
|
1822
|
+
* @return Promise
|
|
1823
|
+
*/
|
|
1824
|
+
export const setDefaultDevice = async (devices, operationType) => {
|
|
1825
|
+
// 设置默认的摄像头
|
|
1826
|
+
if (devices && devices.camera) {
|
|
1827
|
+
if (zbztAVSDK_device_checker_init.camera.list.length == 0) {
|
|
1828
|
+
await getVideoDeviceList();
|
|
1829
|
+
}
|
|
1830
|
+
await setVideoDevice({ deviceId: devices.camera, operationType: `${operationType}_1` });
|
|
1831
|
+
} else {
|
|
1832
|
+
const cameraData = await getVideoDeviceList();
|
|
1833
|
+
if (cameraData.length) {
|
|
1834
|
+
let hasSetCamera = false;
|
|
1835
|
+
for (let item of cameraData) {
|
|
1836
|
+
if (item.isDefault) {
|
|
1837
|
+
await setVideoDevice({ deviceId: item.deviceId, operationType: `${operationType}_2` });
|
|
1838
|
+
hasSetCamera = true;
|
|
1839
|
+
break;
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
if (!hasSetCamera) {
|
|
1843
|
+
await setVideoDevice({ deviceId: cameraData[0].deviceId, operationType: `${operationType}_3` });
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
// 设置默认的麦克风
|
|
1848
|
+
if (devices && devices.microphone) {
|
|
1849
|
+
if (zbztAVSDK_device_checker_init.microphone.list.length == 0) {
|
|
1850
|
+
await getMicrophoneDeviceList();
|
|
1851
|
+
}
|
|
1852
|
+
await setMicrophoneDevice({ deviceId: devices.microphone, operationType: `${operationType}_1` });
|
|
1853
|
+
} else {
|
|
1854
|
+
const microPhoneData = await getMicrophoneDeviceList();
|
|
1855
|
+
if (microPhoneData.length) {
|
|
1856
|
+
let hasSetMicrophone = false;
|
|
1857
|
+
for (let item of microPhoneData) {
|
|
1858
|
+
if (item.isDefault) {
|
|
1859
|
+
await setMicrophoneDevice({ deviceId: item.deviceId, operationType: `${operationType}_2` });
|
|
1860
|
+
hasSetMicrophone = true;
|
|
1861
|
+
break;
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
if (!hasSetMicrophone) {
|
|
1865
|
+
await setMicrophoneDevice({ deviceId: microPhoneData[0].deviceId, operationType: `${operationType}_3` });
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
// 设置默认的扬声器
|
|
1870
|
+
if (devices && devices.speaker) {
|
|
1871
|
+
await setSpeakerDevice({ deviceId: devices.speaker, operationType: `${operationType}_1` });
|
|
1872
|
+
} else {
|
|
1873
|
+
const speakerData = await getSpeakerDeviceList();
|
|
1874
|
+
if (speakerData.length) {
|
|
1875
|
+
let hasSetSpeaker = false;
|
|
1876
|
+
for (let item of speakerData) {
|
|
1877
|
+
if (item.isDefault) {
|
|
1878
|
+
await setSpeakerDevice({ deviceId: item.deviceId, operationType: `${operationType}_2` });
|
|
1879
|
+
hasSetSpeaker = true;
|
|
1880
|
+
break;
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
if (!hasSetSpeaker) {
|
|
1884
|
+
await setSpeakerDevice({ deviceId: speakerData[0].deviceId, operationType: `${operationType}_3` });
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
};
|
|
1889
|
+
|
|
1890
|
+
/**
|
|
1891
|
+
* @function 开始推流
|
|
1892
|
+
* @param title:String 直播的名称,可选,默认为 ''
|
|
1893
|
+
* @param flag:Number 直播属性,可选,默认为 0
|
|
1894
|
+
* @param seq:Number 请求序号,可选,默认为 0
|
|
1895
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1896
|
+
* @return Promise | void
|
|
1897
|
+
*/
|
|
1898
|
+
export const startPublish2 = async (streamid, idx, title, flag, seq) => {
|
|
1899
|
+
const streamId = streamid || window.zbztAVSDK_init_params.zego.streamId;
|
|
1900
|
+
if (typeof title === 'undefined') {
|
|
1901
|
+
title = 'none';
|
|
1902
|
+
}
|
|
1903
|
+
if (typeof flag === 'undefined') {
|
|
1904
|
+
flag = 0;
|
|
1905
|
+
}
|
|
1906
|
+
if (typeof seq === 'undefined') {
|
|
1907
|
+
seq = 0;
|
|
1908
|
+
}
|
|
1909
|
+
if (typeof idx === 'undefined') {
|
|
1910
|
+
idx = 0;
|
|
1911
|
+
}
|
|
1912
|
+
await new Promise((resolve, reject) => {
|
|
1913
|
+
let timer = setInterval(() => {
|
|
1914
|
+
if (hasLoginChannel) {
|
|
1915
|
+
clearInterval(timer);
|
|
1916
|
+
resolve();
|
|
1917
|
+
}
|
|
1918
|
+
}, 30);
|
|
1919
|
+
});
|
|
1920
|
+
let res = await callMethod('StartPublish2', {
|
|
1921
|
+
pszStreamID: streamId,
|
|
1922
|
+
pszTitle: title,
|
|
1923
|
+
seq,
|
|
1924
|
+
idx,
|
|
1925
|
+
flag
|
|
1926
|
+
});
|
|
1927
|
+
await startSoundLevelMonitor();
|
|
1928
|
+
await new Promise((resolve, reject) => {
|
|
1929
|
+
let timer = setInterval(() => {
|
|
1930
|
+
if (hasPushFlow) {
|
|
1931
|
+
clearInterval(timer);
|
|
1932
|
+
resolve();
|
|
1933
|
+
}
|
|
1934
|
+
}, 300);
|
|
1935
|
+
});
|
|
1936
|
+
// 心跳开始
|
|
1937
|
+
if (!isFirstHeartBeatReport) {
|
|
1938
|
+
isFirstHeartBeatReport = true;
|
|
1939
|
+
heartBeatDataReport('start');
|
|
1940
|
+
}
|
|
1941
|
+
return res;
|
|
1942
|
+
};
|
|
1943
|
+
|
|
1944
|
+
/**
|
|
1945
|
+
* @function 结束推流
|
|
1946
|
+
* @param msg:String 自定义信息,server 对接流结束回调包含此字段内容,可选,默认为 'none'
|
|
1947
|
+
* @param flag:Number 直播属性,可选,默认为 0
|
|
1948
|
+
* @param idx:Number 推流通道,可选,默认为 0
|
|
1949
|
+
* @return Promise | void
|
|
1950
|
+
*/
|
|
1951
|
+
export const stopPublish = (idx, msg, flag) => {
|
|
1952
|
+
if (typeof msg === 'undefined') {
|
|
1953
|
+
msg = 'none';
|
|
1954
|
+
}
|
|
1955
|
+
if (typeof flag === 'undefined') {
|
|
1956
|
+
flag = 0;
|
|
1957
|
+
}
|
|
1958
|
+
if (typeof idx === 'undefined') {
|
|
1959
|
+
idx = 0;
|
|
1960
|
+
}
|
|
1961
|
+
// try {
|
|
1962
|
+
// dataReport.stopPublish({publish_streamid:window.zbztAVSDK_init_params.zego.streamId});
|
|
1963
|
+
// } catch (error) {}
|
|
1964
|
+
return callMethod('StopPublish', {
|
|
1965
|
+
pszMsg: msg,
|
|
1966
|
+
flag,
|
|
1967
|
+
idx
|
|
1968
|
+
});
|
|
1969
|
+
};
|
|
1970
|
+
|
|
1971
|
+
/**
|
|
1972
|
+
* @function 初始化拉流
|
|
1973
|
+
* @param streamId:String 从传来的信道消息中获取,必选
|
|
1974
|
+
* @param domId:String <video> 标签的 id,可选
|
|
1975
|
+
* 如果传了就把视频绑定到对应的 <video> 标签上
|
|
1976
|
+
* @param pInfo:String 多媒体流附加信息,可选,默认为 'none'
|
|
1977
|
+
* @return src:String 视频预览地址
|
|
1978
|
+
*/
|
|
1979
|
+
export const initPullFlow = async (streamId, domId, mute, pInfo, notAutoPlay, audioOnly) => {
|
|
1980
|
+
defaultApi.writeLog(`ZEGO:: initPullFlow_start ,streamId :${streamId}`);
|
|
1981
|
+
let playChannel;
|
|
1982
|
+
resetStreamIdRtcPlayerInfo1(streamId);
|
|
1983
|
+
resetStreamIdRtcPlayerInfo(streamId);
|
|
1984
|
+
try {
|
|
1985
|
+
if (!isFirstHeartBeatReport) {
|
|
1986
|
+
isFirstHeartBeatReport = true;
|
|
1987
|
+
heartBeatDataReport('start');
|
|
1988
|
+
}
|
|
1989
|
+
} catch (error) { }
|
|
1990
|
+
if (streamIdToPreviewId[streamId] == undefined) {
|
|
1991
|
+
// if (typeof zegoCallback === 'function' && uiChnIndexs.length === 0) {
|
|
1992
|
+
// zegoCallback({
|
|
1993
|
+
// type: 'over_max_connect',
|
|
1994
|
+
// data: {
|
|
1995
|
+
// message: 'ZEGO:: all uiChnIndexs are used'
|
|
1996
|
+
// }
|
|
1997
|
+
// });
|
|
1998
|
+
// }
|
|
1999
|
+
defaultApi.writeLog(`ZEGO:: The streamId queue does not contain this streamId ${uiChnIndexs}`);
|
|
2000
|
+
if (uiChnIndexs.length === 0) {
|
|
2001
|
+
NOTICE.overMaxConnect();
|
|
2002
|
+
defaultApi.writeLog('error', `ZEGO:: all uiChnIndexs are used ${uiChnIndexs}`);
|
|
2003
|
+
return {
|
|
2004
|
+
videoSrc: '',
|
|
2005
|
+
playerId: -2
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
playChannel = uiChnIndexs.pop();
|
|
2009
|
+
streamIdToPreviewId[streamId] = playChannel;
|
|
2010
|
+
defaultApi.writeLog(`streamIdIsNoExited ${playChannel} ${uiChnIndexs}`);
|
|
2011
|
+
} else {
|
|
2012
|
+
playChannel = streamIdToPreviewId[streamId];
|
|
2013
|
+
defaultApi.writeLog(`ZEGO:: The streamId queue contains this streamId ${playChannel} ${uiChnIndexs}`);
|
|
2014
|
+
await stopPlayStream(streamId);
|
|
2015
|
+
resetStreamIdRtcPlayerInfo(streamId);
|
|
2016
|
+
}
|
|
2017
|
+
// 判断是否创建或者获取播放通道成功,不成功就删掉重试
|
|
2018
|
+
if (playChannel == undefined) {
|
|
2019
|
+
delete streamIdToPreviewId[streamId];
|
|
2020
|
+
defaultApi.writeLog('error', 'ZEGO:: uiChnIndex is not exist');
|
|
2021
|
+
// delete streamIdToBlobUrl[streamId];
|
|
2022
|
+
return initPullFlow(streamId, domId, mute, pInfo, notAutoPlay, audioOnly);
|
|
2023
|
+
}
|
|
2024
|
+
previewIdToStreamId[playChannel] = streamId;
|
|
2025
|
+
//是否拉取声音
|
|
2026
|
+
activateAudioPlayStream(streamId, !!!mute);
|
|
2027
|
+
//是否拉取画面
|
|
2028
|
+
activateVideoPlayStream(streamId, !!!audioOnly);
|
|
2029
|
+
if (!notAutoPlay) {
|
|
2030
|
+
await playStream(streamId, playChannel, pInfo);
|
|
2031
|
+
}
|
|
2032
|
+
const videoSrc = await startLocalOrRemotePreview(false, streamId, domId);
|
|
2033
|
+
return {
|
|
2034
|
+
videoSrc,
|
|
2035
|
+
playerId: playChannel
|
|
2036
|
+
};
|
|
2037
|
+
};
|
|
2038
|
+
|
|
2039
|
+
/**
|
|
2040
|
+
* @function 恢复拉指定的流
|
|
2041
|
+
* @param streamId:String 被拉取的流的 id,必选
|
|
2042
|
+
* @param uiChnIndex:Number 播放通道,可选
|
|
2043
|
+
* @param pInfo:String 多媒体流附加信息,可选,默认为 'none'
|
|
2044
|
+
* @return Promise | void
|
|
2045
|
+
*/
|
|
2046
|
+
export const playStream = (streamId, uiChnIndex, pInfo) => {
|
|
2047
|
+
if (typeof uiChnIndex === 'undefined') {
|
|
2048
|
+
uiChnIndex = streamIdToPreviewId[streamId];
|
|
2049
|
+
}
|
|
2050
|
+
if (typeof pInfo === 'undefined') {
|
|
2051
|
+
pInfo = 'none';
|
|
2052
|
+
}
|
|
2053
|
+
defaultApi.writeLog(`avsdk ZEGO::PlayStream streamId: ${streamId} uiChnIndex: ${uiChnIndex}`);
|
|
2054
|
+
return callMethod('PlayStream', {
|
|
2055
|
+
pszStreamID: streamId,
|
|
2056
|
+
uiChnIndex,
|
|
2057
|
+
pInfo
|
|
2058
|
+
});
|
|
2059
|
+
};
|
|
2060
|
+
|
|
2061
|
+
/**
|
|
2062
|
+
* @function 停止拉指定的流
|
|
2063
|
+
* @param streamId:String 被拉取的流的 id,必选
|
|
2064
|
+
* @param recovery:Boolean 是否回收播放器, 可选
|
|
2065
|
+
* @return Promise | void
|
|
2066
|
+
*/
|
|
2067
|
+
export const stopPlayStream = async (streamId, recovery) => {
|
|
2068
|
+
const id = streamIdToPreviewId[streamId];
|
|
2069
|
+
delete streamIdRtcPlayerInfo[streamId];
|
|
2070
|
+
if (recovery && id && !uiChnIndexs.includes(id)) {
|
|
2071
|
+
uiChnIndexs.push(id);
|
|
2072
|
+
defaultApi.writeLog(`avsdk ZEGO::stopPlayStream streamId: ${streamId} id: ${id} uiChnIndexs: ${uiChnIndexs}`);
|
|
2073
|
+
delete streamIdToPreviewId[streamId];
|
|
2074
|
+
// delete streamIdToBlobUrl[streamId];
|
|
2075
|
+
}
|
|
2076
|
+
return callMethod('StopPlayStream', {
|
|
2077
|
+
pszStreamID: streamId
|
|
2078
|
+
});
|
|
2079
|
+
};
|
|
2080
|
+
|
|
2081
|
+
/**
|
|
2082
|
+
* @function 停止并回收所有拉流
|
|
2083
|
+
* @return Promise | void
|
|
2084
|
+
*/
|
|
2085
|
+
export const stopAllPlayStream = () => {
|
|
2086
|
+
const toRecoveryArr = [];
|
|
2087
|
+
for (let streamId in streamIdToPreviewId) {
|
|
2088
|
+
if (streamIdToPreviewId.hasOwnProperty(streamId)) {
|
|
2089
|
+
const id = streamIdToPreviewId[streamId];
|
|
2090
|
+
if (id && !uiChnIndexs.includes(id)) {
|
|
2091
|
+
uiChnIndexs.push(id);
|
|
2092
|
+
toRecoveryArr.push(callMethod('StopPlayStream', {
|
|
2093
|
+
pszStreamID: streamId
|
|
2094
|
+
}));
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
defaultApi.writeLog(`avsdk ZEGO::stopAllPlayStream uiChnIndexs: ${uiChnIndexs}`);
|
|
2099
|
+
streamIdToPreviewId = {};
|
|
2100
|
+
return Promise.all(toRecoveryArr);
|
|
2101
|
+
};
|
|
2102
|
+
|
|
2103
|
+
/**
|
|
2104
|
+
* @function 切换播放流
|
|
2105
|
+
* @param streamId:String 需要停止流的 id,必选
|
|
2106
|
+
* @param toStreamId:String 被拉取的流的 id,必选
|
|
2107
|
+
* @param toDomId:String <video> 标签的 id,可选
|
|
2108
|
+
* @return Promise | void
|
|
2109
|
+
*/
|
|
2110
|
+
export const changePullFlow = async (streamId, toStreamId, toDomId) => {
|
|
2111
|
+
await stopPlayStream(streamId, true);
|
|
2112
|
+
return initPullFlow(toStreamId, toDomId);
|
|
2113
|
+
};
|
|
2114
|
+
|
|
2115
|
+
/**
|
|
2116
|
+
* @function 转推,录课
|
|
2117
|
+
* @param type:String 必选,'start' | 'stop'
|
|
2118
|
+
* @param seq:Number 可选,默认为 1
|
|
2119
|
+
* @return Promise | void
|
|
2120
|
+
*/
|
|
2121
|
+
export const mixStream = (type, args, seq) => {
|
|
2122
|
+
if (!args) {
|
|
2123
|
+
const zego = window.zbztAVSDK_init_params.zego;
|
|
2124
|
+
const streamId = zego.streamId;
|
|
2125
|
+
const sid = zego.sid;
|
|
2126
|
+
let pInputStreamList;
|
|
2127
|
+
let nInputStreamCount;
|
|
2128
|
+
if (type === 'start') {
|
|
2129
|
+
pInputStreamList = [{
|
|
2130
|
+
szStreamID: streamId,
|
|
2131
|
+
layout: {
|
|
2132
|
+
top: 0,
|
|
2133
|
+
right: zego.previewResolutionWidth,
|
|
2134
|
+
bottom: zego.previewResolutionHeight,
|
|
2135
|
+
left: 0
|
|
2136
|
+
},
|
|
2137
|
+
uSoundLevelID: 0,
|
|
2138
|
+
nContentControl: 0
|
|
2139
|
+
}];
|
|
2140
|
+
nInputStreamCount = 1;
|
|
2141
|
+
}
|
|
2142
|
+
if (type === 'stop') {
|
|
2143
|
+
pInputStreamList = [];
|
|
2144
|
+
nInputStreamCount = 0;
|
|
2145
|
+
}
|
|
2146
|
+
if (typeof seq === 'undefined') {
|
|
2147
|
+
seq = 1;
|
|
2148
|
+
}
|
|
2149
|
+
|
|
2150
|
+
return callMethod('MixStream', {
|
|
2151
|
+
config: {
|
|
2152
|
+
szOutputStream: zego.recordUrl + '/' + sid,
|
|
2153
|
+
bOutputIsUrl: true,
|
|
2154
|
+
nOutputFps: zego.previewCaptureFps,
|
|
2155
|
+
nOutputBitrate: zego.previewCaptureBitrate,
|
|
2156
|
+
nOutputAudioBitrate: zego.previewCaptureBitrate,
|
|
2157
|
+
nOutputWidth: zego.previewResolutionWidth,
|
|
2158
|
+
nOutputHeight: zego.previewResolutionHeight,
|
|
2159
|
+
nOutputAudioConfig: 1,
|
|
2160
|
+
pInputStreamList,
|
|
2161
|
+
nInputStreamCount,
|
|
2162
|
+
pUserData: '',
|
|
2163
|
+
nLenOfUserData: 0,
|
|
2164
|
+
nChannels: 0,
|
|
2165
|
+
nOutputBackgroundColor: 0,
|
|
2166
|
+
pOutputBackgroundImage: '',
|
|
2167
|
+
bWithSoundLevel: false
|
|
2168
|
+
},
|
|
2169
|
+
seq
|
|
2170
|
+
});
|
|
2171
|
+
} else {
|
|
2172
|
+
return callMethod('MixStream', args);
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
};
|
|
2176
|
+
|
|
2177
|
+
/**
|
|
2178
|
+
* @function 是否拉取音频流--通过流id控制
|
|
2179
|
+
* @param streamId:String 被拉取的流的 id,必选
|
|
2180
|
+
* @param bActive:Boolean true -> 拉取,false -> 不拉取,必选
|
|
2181
|
+
* @return Promise | void
|
|
2182
|
+
*/
|
|
2183
|
+
export const activateAudioPlayStream = (streamId, bActive) => {
|
|
2184
|
+
streamIdRtcPlayerInfo1[streamId].audio_type = bActive;
|
|
2185
|
+
return callMethod('ActivateAudioPlayStream', {
|
|
2186
|
+
nChannelIdx: streamIdToPreviewId[streamId],
|
|
2187
|
+
bActive
|
|
2188
|
+
});
|
|
2189
|
+
};
|
|
2190
|
+
|
|
2191
|
+
/**
|
|
2192
|
+
* @function 是否拉取音频流--通过播放器id控制
|
|
2193
|
+
* @param operation:Boolean,必选,true -> 拉取,false -> 不拉取,必选
|
|
2194
|
+
* @param playerId:Number,必选,播放器id
|
|
2195
|
+
* @return Promise | void
|
|
2196
|
+
*/
|
|
2197
|
+
export const pullAudioFlow = (playerId, operation, streamid) => {
|
|
2198
|
+
defaultApi.writeLog(`pullAudioFlow -- playerId ${playerId} operation ${operation} streamId ${streamid}`);
|
|
2199
|
+
if (streamid) {
|
|
2200
|
+
if (streamIdToPreviewId[streamid] == undefined) {
|
|
2201
|
+
NOTICE.pullAudioFlowError({ streamid })
|
|
2202
|
+
return;
|
|
2203
|
+
} else {
|
|
2204
|
+
playerId = streamIdToPreviewId[streamid]
|
|
2205
|
+
defaultApi.writeLog(`pullAudioFlow-playerId ${playerId}`);
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
let streamId = previewIdToStreamId[playerId];
|
|
2209
|
+
try {
|
|
2210
|
+
streamIdRtcPlayerInfo1[streamId].audio_type = operation;
|
|
2211
|
+
defaultApi.writeLog(`pullAudioFlow ${streamId}`);
|
|
2212
|
+
} catch (e) {
|
|
2213
|
+
defaultApi.writeLog(`pullAudioFlow ${streamId} --error ${JSON.stringify(e)}`, null, 'error');
|
|
2214
|
+
}
|
|
2215
|
+
try {
|
|
2216
|
+
dataReport.setPullVoice({
|
|
2217
|
+
code: +operation,
|
|
2218
|
+
pull_uid: util.getUidByStreamId(streamId),
|
|
2219
|
+
pull_streamid: streamId,
|
|
2220
|
+
playerId
|
|
2221
|
+
// operator:'client'
|
|
2222
|
+
});
|
|
2223
|
+
} catch (e) { };
|
|
2224
|
+
return callMethod('ActivateAudioPlayStream', {
|
|
2225
|
+
bActive: operation,
|
|
2226
|
+
nChannelIdx: playerId
|
|
2227
|
+
});
|
|
2228
|
+
};
|
|
2229
|
+
|
|
2230
|
+
/**
|
|
2231
|
+
* @function 是否拉取画面流
|
|
2232
|
+
* @param streamId:String 被拉取的流的 id,必选
|
|
2233
|
+
* @param bActive:Boolean true -> 拉取,false -> 不拉取,必选
|
|
2234
|
+
* @return Promise | void
|
|
2235
|
+
*/
|
|
2236
|
+
export const activateVideoPlayStream = (streamId, bActive) => {
|
|
2237
|
+
try {
|
|
2238
|
+
streamIdRtcPlayerInfo1[streamId].video_type = bActive;
|
|
2239
|
+
defaultApi.writeLog(`'activateVideoPlayStream ${streamId}`);
|
|
2240
|
+
} catch (e) {
|
|
2241
|
+
defaultApi.writeLog(`activateVideoPlayStream ${streamId} --error ${JSON.stringify(e)}`, null, 'error');
|
|
2242
|
+
}
|
|
2243
|
+
return callMethod('ActivateVideoPlayStream', {
|
|
2244
|
+
nChannelIdx: streamIdToPreviewId[streamId],
|
|
2245
|
+
bActive
|
|
2246
|
+
});
|
|
2247
|
+
};
|
|
2248
|
+
|
|
2249
|
+
/**
|
|
2250
|
+
* @function 开启/关闭麦克风音量回调
|
|
2251
|
+
* @param open:Boolean true -> 开启,false -> 关闭,必选
|
|
2252
|
+
* @return void
|
|
2253
|
+
*/
|
|
2254
|
+
export const openMicVolumeCb = (open) => {
|
|
2255
|
+
// if (open) {
|
|
2256
|
+
// runMicVolumeCb = true;
|
|
2257
|
+
// } else {
|
|
2258
|
+
// runMicVolumeCb = false;
|
|
2259
|
+
// }
|
|
2260
|
+
};
|
|
2261
|
+
|
|
2262
|
+
/**
|
|
2263
|
+
* @function 监听设备的音量变化
|
|
2264
|
+
* @param deviceType:Number 音频设备类型,0 -> 麦克风,1 -> 扬声器,必选
|
|
2265
|
+
* @param deviceId:String 音频设备 id,必选
|
|
2266
|
+
* @return Promise | void
|
|
2267
|
+
*/
|
|
2268
|
+
export const setAudioVolumeNotify = (deviceType, deviceId) => {
|
|
2269
|
+
return callMethod('SetAudioVolumeNotify', {
|
|
2270
|
+
deviceType,
|
|
2271
|
+
deviceId
|
|
2272
|
+
});
|
|
2273
|
+
};
|
|
2274
|
+
|
|
2275
|
+
/**
|
|
2276
|
+
* @function 关闭监听设备的音量变化
|
|
2277
|
+
* @param deviceType:Number 音频设备类型,0 -> 麦克风,1 -> 扬声器,必选
|
|
2278
|
+
* @param deviceId:String 音频设备 id,必选
|
|
2279
|
+
* @return Promise | void
|
|
2280
|
+
*/
|
|
2281
|
+
export const stopAudioVolumeNotify = (deviceType, deviceId) => {
|
|
2282
|
+
return callMethod('StopAudioVolumeNotify', {
|
|
2283
|
+
deviceType,
|
|
2284
|
+
deviceId
|
|
2285
|
+
});
|
|
2286
|
+
};
|
|
2287
|
+
|
|
2288
|
+
/**
|
|
2289
|
+
* @function 启动 soundLevel 监听
|
|
2290
|
+
* StartSoundLevelMonitor 后一定要 StopSoundLevelMonitor
|
|
2291
|
+
* @return Promise | void
|
|
2292
|
+
*/
|
|
2293
|
+
export const startSoundLevelMonitor = () => {
|
|
2294
|
+
return callMethod('StartSoundLevelMonitor', {});
|
|
2295
|
+
};
|
|
2296
|
+
|
|
2297
|
+
/**
|
|
2298
|
+
* @function 停止 soundLevel 监听
|
|
2299
|
+
* @return Promise | void
|
|
2300
|
+
*/
|
|
2301
|
+
export const stopSoundLevelMonitor = () => {
|
|
2302
|
+
return callMethod('StopSoundLevelMonitor', {});
|
|
2303
|
+
};
|
|
2304
|
+
|
|
2305
|
+
/**
|
|
2306
|
+
* @function 设置 soundLevel 的监控周期
|
|
2307
|
+
* @param timeInMS:Number 时间周期,单位为毫秒,取值范围 [100, 3000],必选
|
|
2308
|
+
* @return Promise | void
|
|
2309
|
+
*/
|
|
2310
|
+
export const setSoundLevelMonitorCycle = (timeInMS) => {
|
|
2311
|
+
return callMethod('SetSoundLevelMonitorCycle', {
|
|
2312
|
+
timeInMS
|
|
2313
|
+
});
|
|
2314
|
+
};
|
|
2315
|
+
|
|
2316
|
+
/**
|
|
2317
|
+
* @function 单路录制
|
|
2318
|
+
* @param type:String start/stop,必选
|
|
2319
|
+
* @param szOutputStream:转推地址(支持rtmp/avertp),必选
|
|
2320
|
+
* @param szStreamID:推流ID,必选
|
|
2321
|
+
* @return Promise | void
|
|
2322
|
+
*/
|
|
2323
|
+
/*export const singleRecord = async (type, szOutputStream, szStreamID, seq = 1) => {
|
|
2324
|
+
defaultApi.writeLog(`avsdk ZEGO::singleRecord szStreamID: ${szStreamID} szOutputStream: ${szOutputStream} type: ${type}`);
|
|
2325
|
+
const zego = window.zbztAVSDK_init_params.zego;
|
|
2326
|
+
let pInputStreamList = [];
|
|
2327
|
+
let nInputStreamCount = 0;
|
|
2328
|
+
if (type === 'start') {
|
|
2329
|
+
pInputStreamList = [{
|
|
2330
|
+
szStreamID,
|
|
2331
|
+
layout: {
|
|
2332
|
+
top: 0,
|
|
2333
|
+
right: zego.previewResolutionWidth,
|
|
2334
|
+
bottom: zego.previewResolutionHeight,
|
|
2335
|
+
left: 0
|
|
2336
|
+
},
|
|
2337
|
+
uSoundLevelID: 0,
|
|
2338
|
+
nContentControl: 0
|
|
2339
|
+
}];
|
|
2340
|
+
nInputStreamCount = 1;
|
|
2341
|
+
}
|
|
2342
|
+
return callMethod('MixStream', {
|
|
2343
|
+
config: {
|
|
2344
|
+
szOutputStream,
|
|
2345
|
+
bOutputIsUrl: true,
|
|
2346
|
+
nOutputFps: zego.previewCaptureFps,
|
|
2347
|
+
nOutputBitrate: zego.previewCaptureBitrate,
|
|
2348
|
+
nOutputAudioBitrate: zego.previewCaptureBitrate,
|
|
2349
|
+
nOutputWidth: zego.previewResolutionWidth,
|
|
2350
|
+
nOutputHeight: zego.previewResolutionHeight,
|
|
2351
|
+
nOutputAudioConfig: 1,
|
|
2352
|
+
pInputStreamList,
|
|
2353
|
+
nInputStreamCount,
|
|
2354
|
+
pUserData: '',
|
|
2355
|
+
nLenOfUserData: 0,
|
|
2356
|
+
nChannels: 0,
|
|
2357
|
+
nOutputBackgroundColor: 0,
|
|
2358
|
+
pOutputBackgroundImage: '',
|
|
2359
|
+
bWithSoundLevel: false
|
|
2360
|
+
},
|
|
2361
|
+
seq
|
|
2362
|
+
});
|
|
2363
|
+
};
|
|
2364
|
+
*/
|
|
2365
|
+
export const hasStream = streamId => {
|
|
2366
|
+
return Object.keys(streamIdToPreviewId).includes(streamId);
|
|
2367
|
+
};
|
|
2368
|
+
|
|
2369
|
+
/**
|
|
2370
|
+
* @function 获取当前视频流的通道
|
|
2371
|
+
* @param streamId 流 id
|
|
2372
|
+
* @return channelIndex
|
|
2373
|
+
*/
|
|
2374
|
+
export const getChannelIndex = (streamId) => {
|
|
2375
|
+
defaultApi.writeLog(`ZEGO : getChannelIndex streamId: ${streamId} ${JSON.stringify(streamIdToPreviewId)}`);
|
|
2376
|
+
return streamIdToPreviewId[streamId];
|
|
2377
|
+
};
|
|
2378
|
+
|
|
2379
|
+
/**
|
|
2380
|
+
* @function 获取当前视频流所有的通道
|
|
2381
|
+
* @param streamId 流 id
|
|
2382
|
+
* @return channelIndex
|
|
2383
|
+
*/
|
|
2384
|
+
export const getAllChannelIndex = () => {
|
|
2385
|
+
defaultApi.writeLog(`ZEGO : getAllChannelIndex ${JSON.stringify(streamIdToPreviewId)}`);
|
|
2386
|
+
return streamIdToPreviewId;
|
|
2387
|
+
};
|
|
2388
|
+
|
|
2389
|
+
|
|
2390
|
+
/**
|
|
2391
|
+
* @function 录制转推对外接口
|
|
2392
|
+
* @param type:String start/stop,必选
|
|
2393
|
+
* @param szOutputStream:转推地址(支持rtmp/avertp),必选
|
|
2394
|
+
* @param szStreamID:推流ID,必选
|
|
2395
|
+
* @return Promise | void
|
|
2396
|
+
*/
|
|
2397
|
+
export const singleRecord = async (type, szOutputStream, szStreamID) => {
|
|
2398
|
+
defaultApi.writeLog(`avsdk ZEGO::recordPublishTarget szStreamID: ${szStreamID} szOutputStream: ${szOutputStream} type: ${type}`);
|
|
2399
|
+
const zego = window.zbztAVSDK_init_params.zego;
|
|
2400
|
+
if (!szOutputStream) {
|
|
2401
|
+
const sid = zego.sid;
|
|
2402
|
+
// 拼接转推地址
|
|
2403
|
+
szOutputStream = zego.recordUrl + '/' + sid;
|
|
2404
|
+
}
|
|
2405
|
+
if (!szStreamID) {
|
|
2406
|
+
szStreamID = window.zbztAVSDK_init_params.zego.streamId;
|
|
2407
|
+
}
|
|
2408
|
+
if (type === 'start') {
|
|
2409
|
+
return addPublishTarget(szOutputStream, szStreamID);
|
|
2410
|
+
}
|
|
2411
|
+
if (type === 'stop') {
|
|
2412
|
+
return deletePublishTarget(szOutputStream, szStreamID);
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2415
|
+
|
|
2416
|
+
/**
|
|
2417
|
+
* @function 开始转推
|
|
2418
|
+
* @param szTarget:转推地址(支持rtmp/avertp),必选
|
|
2419
|
+
* @param szStreamID:推流ID,必选
|
|
2420
|
+
* @return Promise | void
|
|
2421
|
+
*/
|
|
2422
|
+
export const addPublishTarget = async (szTarget, szStreamID) => {
|
|
2423
|
+
defaultApi.writeLog(`avsdk ZEGO::addPublishTarget szStreamID: ${szStreamID} szTarget: ${szTarget}`);
|
|
2424
|
+
let res = await callMethod('AddPublishTarget', {
|
|
2425
|
+
strTarget: szTarget,
|
|
2426
|
+
pszStreamID: szStreamID,
|
|
2427
|
+
});
|
|
2428
|
+
try {
|
|
2429
|
+
dataReport.turnPushResult({
|
|
2430
|
+
errorcode: res == 0 ? 0 : 1,
|
|
2431
|
+
case: 'turn push',
|
|
2432
|
+
streamid: szStreamID
|
|
2433
|
+
});
|
|
2434
|
+
} catch (e) { };
|
|
2435
|
+
return res;
|
|
2436
|
+
};
|
|
2437
|
+
|
|
2438
|
+
/**
|
|
2439
|
+
* @function 结束转推
|
|
2440
|
+
* @param szTarget:转推地址(支持rtmp/avertp),必选
|
|
2441
|
+
* @param szStreamID:推流ID,必选
|
|
2442
|
+
* @param seqNum
|
|
2443
|
+
* @return Promise | void
|
|
2444
|
+
*/
|
|
2445
|
+
export const deletePublishTarget = async (szTarget, szStreamID) => {
|
|
2446
|
+
defaultApi.writeLog(`avsdk ZEGO::deletePublishTarget szStreamID: ${szStreamID} szTarget: ${szTarget}`);
|
|
2447
|
+
return callMethod('DeletePublishTarget', {
|
|
2448
|
+
strTarget: szTarget,
|
|
2449
|
+
pszStreamID: szStreamID
|
|
2450
|
+
});
|
|
2451
|
+
};
|
|
2452
|
+
|
|
2453
|
+
/**
|
|
2454
|
+
* @function 开始本地视频录制
|
|
2455
|
+
* @param enableRecord 开始/结束
|
|
2456
|
+
* @param storagePath 录制路径
|
|
2457
|
+
* @return Promise | void
|
|
2458
|
+
*/
|
|
2459
|
+
export const localRecordVideo = async (enableRecord, storagePath) => {
|
|
2460
|
+
defaultApi.writeLog(`avsdk ZEGO::localRecordVideo enableRecord: ${enableRecord}, storagePath: ${storagePath}`);
|
|
2461
|
+
if (enableRecord) {
|
|
2462
|
+
return callMethod('StartRecord', {
|
|
2463
|
+
channelIndex: 0,
|
|
2464
|
+
recordType: 3,
|
|
2465
|
+
enableStatusCallback: true,
|
|
2466
|
+
interval: 3000,
|
|
2467
|
+
recordFormat: 2,
|
|
2468
|
+
isFragment: false,
|
|
2469
|
+
storagePath
|
|
2470
|
+
});
|
|
2471
|
+
} else {
|
|
2472
|
+
return callMethod('StopRecord', {
|
|
2473
|
+
channelIndex: 0
|
|
2474
|
+
});
|
|
2475
|
+
}
|
|
2476
|
+
};
|
|
2477
|
+
|
|
2478
|
+
/**
|
|
2479
|
+
* @function 本地音频录制
|
|
2480
|
+
* @param enableRecord 开始/结束
|
|
2481
|
+
* @param storagePath 录制路径
|
|
2482
|
+
* @return Promise | void
|
|
2483
|
+
*/
|
|
2484
|
+
export const localRecordAudio = async (enableRecord, storagePath) => {
|
|
2485
|
+
defaultApi.writeLog(`avsdk ZEGO::localRecordAudio enableRecord: ${enableRecord}, storagePath: ${storagePath}`);
|
|
2486
|
+
return callMethod('EnableSelectedAudioRecord', {
|
|
2487
|
+
uMask: 1,
|
|
2488
|
+
nSampleRate: 16000,
|
|
2489
|
+
nChannels: 1,
|
|
2490
|
+
enableRecord,
|
|
2491
|
+
storagePath,
|
|
2492
|
+
});
|
|
2493
|
+
};
|
|
2494
|
+
/**
|
|
2495
|
+
* @function 本地录制
|
|
2496
|
+
* @param {string | undefined} fileName
|
|
2497
|
+
* @param {number} fileType 1:flv 2:mp4
|
|
2498
|
+
* @param {number} idx 0:主流 1:辅流 2:RTMP流
|
|
2499
|
+
* @returns {Promise<any>}
|
|
2500
|
+
*/
|
|
2501
|
+
export const startRecord = async (fileName, fileType, idx) => {
|
|
2502
|
+
defaultApi.writeLog(`avsdk ZEGO::startRecord fileName: ${fileName}, fileType: ${fileType}, idx: ${idx}`);
|
|
2503
|
+
if (idx === 1 && !screenStreamId) {
|
|
2504
|
+
defaultApi.writeLog('avsdk ZEGO::startRecord screenStreamId is null', null, 'error');
|
|
2505
|
+
return;
|
|
2506
|
+
}
|
|
2507
|
+
if (!fileName) {
|
|
2508
|
+
const fileNameMap = [localStreamId, screenStreamId, 'rtmp'];
|
|
2509
|
+
fileName = `${fileNameMap[idx]}-${util.currentTimeString().replace(/:/g, '-')}`;
|
|
2510
|
+
}
|
|
2511
|
+
dataReport.startRecord({fileName, fileType, idx});
|
|
2512
|
+
return callMethod('StartRecord', {
|
|
2513
|
+
idx,
|
|
2514
|
+
recordType: 3, // 1:音频 2:视频 3:音视频
|
|
2515
|
+
fileName,
|
|
2516
|
+
recordFormat: fileType,
|
|
2517
|
+
});
|
|
2518
|
+
};
|
|
2519
|
+
/**
|
|
2520
|
+
* 结束音视频录制 channelIndex(number) 录制通道 0主推流通道/ 1辅助推流通道/ 2辅助推流通道
|
|
2521
|
+
* @param {number} idx 0 | 1 | 2
|
|
2522
|
+
* @returns
|
|
2523
|
+
*/
|
|
2524
|
+
export const stopRecord = async (idx) => {
|
|
2525
|
+
defaultApi.writeLog(`avsdk ZEGO::stopRecord idx: ${idx}`);
|
|
2526
|
+
dataReport.stopRecord({idx});
|
|
2527
|
+
return callMethod('StopRecord',{idx});
|
|
2528
|
+
};
|
|
2529
|
+
/**
|
|
2530
|
+
* 开启外部音频采集(通知sdk)推流前,调用此接口,publish_channel,number类型,传2代表第三路流
|
|
2531
|
+
* @param {number} idx 0 | 1 | 2
|
|
2532
|
+
* @returns
|
|
2533
|
+
*/
|
|
2534
|
+
export const startCapture = async (idx) => {
|
|
2535
|
+
defaultApi.writeLog(`avsdk ZEGO::startCapture idx: ${idx}`);
|
|
2536
|
+
return callMethod('StartCapture',{publish_channel:idx});
|
|
2537
|
+
};
|
|
2538
|
+
/**
|
|
2539
|
+
* 结束外部音频采集(通知sdk)
|
|
2540
|
+
* @param {number} idx 0 | 1 | 2
|
|
2541
|
+
* @returns
|
|
2542
|
+
*/
|
|
2543
|
+
export const stopCapture = async (idx) => {
|
|
2544
|
+
defaultApi.writeLog(`avsdk ZEGO::stopCapture idx: ${idx}`);
|
|
2545
|
+
return callMethod('StopCapture',{publish_channel:idx});
|
|
2546
|
+
};
|
|
2547
|
+
|
|
2548
|
+
/**
|
|
2549
|
+
* @function 设置外部采集设备模块
|
|
2550
|
+
* @param bUseVideoCapture 是否开启外部采集设备模块
|
|
2551
|
+
* @attention 必须在 InitSDK 前调用,置空必须在UninitSDK之后
|
|
2552
|
+
* @return Promise | void
|
|
2553
|
+
*/
|
|
2554
|
+
const setVideoCaptureFactory = (bUseVideoCapture = false, streamChannel) => {
|
|
2555
|
+
defaultApi.writeLog('info', 'avsdk ZEGO::setVideoCaptureFactory');
|
|
2556
|
+
return callMethod('SetVideoCaptureFactory', {
|
|
2557
|
+
bUseVideoCapture,
|
|
2558
|
+
streamChannel
|
|
2559
|
+
});
|
|
2560
|
+
};
|
|
2561
|
+
|
|
2562
|
+
//设置音频数据来源
|
|
2563
|
+
const setAudioAuxSource = (source) => {
|
|
2564
|
+
defaultApi.writeLog('info', 'avsdk ZEGO::setAudioAuxSource');
|
|
2565
|
+
return callMethod('SetAudioAuxSource', {
|
|
2566
|
+
source
|
|
2567
|
+
});
|
|
2568
|
+
};
|
|
2569
|
+
|
|
2570
|
+
//RTC同屏 辅助通道音频类型 0:静音 / 1:麦克风 / 2:拉流的声音 / 3:1+2 / 4:麦克风+扬声器 / 5:扬声器(不含拉流)
|
|
2571
|
+
const setAUXAudioType = (type) => {
|
|
2572
|
+
defaultApi.writeLog('info', 'avsdk ZEGO::SetAUXAudioType');
|
|
2573
|
+
return callMethod('SetAUXAudioType', {
|
|
2574
|
+
type
|
|
2575
|
+
});
|
|
2576
|
+
};
|
|
2577
|
+
|
|
2578
|
+
//录制通道音频类型 0:静音 / 1:麦克风 / 2:拉流的声音 / 4:1+2 / 8:麦克风+扬声器(不含拉流)
|
|
2579
|
+
const setThirdAudioType = (type) => {
|
|
2580
|
+
defaultApi.writeLog('info', 'avsdk ZEGO::SetThirdAudioType');
|
|
2581
|
+
return callMethod('SetThirdAudioType', {
|
|
2582
|
+
type
|
|
2583
|
+
});
|
|
2584
|
+
};
|
|
2585
|
+
|
|
2586
|
+
//开启音频外部采集 参数:channel 参数类型:int 通道(传1使用辅通道)
|
|
2587
|
+
const startAudioExCapture = (channel) => {
|
|
2588
|
+
defaultApi.writeLog('info', 'avsdk ZEGO::startAudioExCapture');
|
|
2589
|
+
return callMethod('StartAudioExCapture', {
|
|
2590
|
+
channel
|
|
2591
|
+
});
|
|
2592
|
+
};
|
|
2593
|
+
|
|
2594
|
+
//加载截屏插件
|
|
2595
|
+
const LoadCollectionOutputEntry2 = () => {
|
|
2596
|
+
defaultApi.writeLog('info', 'avsdk ZEGO::LoadCollectionOutputEntry2');
|
|
2597
|
+
return callMethod('LoadCollectionOutputEntry2', {});
|
|
2598
|
+
};
|
|
2599
|
+
|
|
2600
|
+
//native调用开启同屏, Web端屏幕共享
|
|
2601
|
+
const startMultiScreen = async () => {
|
|
2602
|
+
defaultApi.writeLog('info', 'avsdk ZEGO::startMultiScreen');
|
|
2603
|
+
// await setVideoCaptureFactory(true,1);
|
|
2604
|
+
await LoadCollectionOutputEntry2();
|
|
2605
|
+
};
|
|
2606
|
+
|
|
2607
|
+
|
|
2608
|
+
/**
|
|
2609
|
+
* @function 设置推流时是否发送视频数据
|
|
2610
|
+
* @param mute true不发送(仅预览),false 发送
|
|
2611
|
+
* @param idx 推流通道索引 0表示主推流通道,默认;1表示第二路流推流通道,无法推出声音
|
|
2612
|
+
* @return Promise | void (0代表设置成功,否则设置失败)
|
|
2613
|
+
*/
|
|
2614
|
+
const muteVideoPublish = (mute = true, idx = 0) => {
|
|
2615
|
+
return callMethod('MuteVideoPublish', {
|
|
2616
|
+
mute,
|
|
2617
|
+
idx
|
|
2618
|
+
});
|
|
2619
|
+
};
|
|
2620
|
+
|
|
2621
|
+
/**
|
|
2622
|
+
* @function 开始连麦
|
|
2623
|
+
* @param mode:number 采集器默认, 默认0=站立 1=坐立
|
|
2624
|
+
* @return Promise | void
|
|
2625
|
+
*/
|
|
2626
|
+
export const teacherStartLinkMic = async (mode = 0) => {
|
|
2627
|
+
if (mode === 0) {
|
|
2628
|
+
await muteVideoPublish(true, 0);
|
|
2629
|
+
await setMicrophoneDevice({});
|
|
2630
|
+
await enableMic(true);
|
|
2631
|
+
} else {
|
|
2632
|
+
//开始连麦后,需要打开摄像头(开启外部采集器后,不会争抢摄像头),否则学生拉到的小班流会没有画面
|
|
2633
|
+
await enableCamera(true);
|
|
2634
|
+
await enableMic(true);
|
|
2635
|
+
}
|
|
2636
|
+
};
|
|
2637
|
+
|
|
2638
|
+
/**
|
|
2639
|
+
* @function 结束连麦
|
|
2640
|
+
* @param mode:number 采集器默认, 默认0=站立 1=坐立
|
|
2641
|
+
* @return Promise | void
|
|
2642
|
+
*/
|
|
2643
|
+
export const teacherStopLinkMic = async (mode = 0) => {
|
|
2644
|
+
// if (mode === 0) {
|
|
2645
|
+
// await muteVideoPublish(false,0);
|
|
2646
|
+
// } else {
|
|
2647
|
+
// await setVideoCaptureFactory(false);
|
|
2648
|
+
// }
|
|
2649
|
+
};
|
|
2650
|
+
|
|
2651
|
+
/**
|
|
2652
|
+
* @function 设置镜像状态(预览)
|
|
2653
|
+
* @param { boolean } type true=开启 false=关闭
|
|
2654
|
+
* @return: Promise
|
|
2655
|
+
*/
|
|
2656
|
+
export const setMirrorStatus = (isMirror) => {
|
|
2657
|
+
// return callMethod('SetPreViewMirror', { isMirror });
|
|
2658
|
+
return setVideoMirrorMode(isMirror >> 0);
|
|
2659
|
+
};
|
|
2660
|
+
|
|
2661
|
+
/**
|
|
2662
|
+
* @function 设置拉流镜像状态
|
|
2663
|
+
* @param { boolean } type true=开启 false=关闭
|
|
2664
|
+
* @return: Promise
|
|
2665
|
+
*/
|
|
2666
|
+
export const setPlayViewMirror = (isMirror) => {
|
|
2667
|
+
return callMethod('SetPlayViewMirror', { isMirror });
|
|
2668
|
+
};
|
|
2669
|
+
|
|
2670
|
+
/**
|
|
2671
|
+
* @function 设置推流镜像状态
|
|
2672
|
+
* @param { boolean } id 采集器Id
|
|
2673
|
+
* @param { 0 | 1 | 2 | 3 } mode 0: 预览启用镜像,推流不启用镜像; 1: 预览启用镜像,推流启用镜像; 2: 预览不启用镜像,推流不启用镜像; 3: 预览不启用镜像,推流启用镜像
|
|
2674
|
+
* @return: Promise
|
|
2675
|
+
*/
|
|
2676
|
+
export const setVideoMirrorMode = (mode, idx = 0) => {
|
|
2677
|
+
let realId = mode == 0 ? 2 : 1;
|
|
2678
|
+
defaultApi.writeLog(`ZEGO: setVideoMirrorMode, mode: ${mode}, idx:${idx}, realId:${realId}`);
|
|
2679
|
+
return callMethod('SetVideoMirrorMode', { idx, mode: realId });
|
|
2680
|
+
};
|
|
2681
|
+
|
|
2682
|
+
//美颜相关
|
|
2683
|
+
/**
|
|
2684
|
+
* @function 开启美颜
|
|
2685
|
+
* @return: Promise
|
|
2686
|
+
*/
|
|
2687
|
+
export const startSenseMe = async () => {
|
|
2688
|
+
return callMethod('StartSenseMe', {});
|
|
2689
|
+
};
|
|
2690
|
+
/**
|
|
2691
|
+
* @function 设置美颜参数
|
|
2692
|
+
* * @param { number } type //美颜类型,1、红润强度,3、磨皮强度,4、美白强度,5、大眼,6、瘦脸,7、小脸,8、对比度强度,9、饱和度强度
|
|
2693
|
+
* * @param { number } value //美颜数值,有效值范围0~100
|
|
2694
|
+
* @return: Promise
|
|
2695
|
+
*/
|
|
2696
|
+
export const setBeautifyParam = async (type, value) => {
|
|
2697
|
+
return callMethod('SetBeautifyParam', { type, value });
|
|
2698
|
+
};
|
|
2699
|
+
/**
|
|
2700
|
+
* @function 关闭美颜
|
|
2701
|
+
* @return: Promise
|
|
2702
|
+
*/
|
|
2703
|
+
export const endSenseMe = async () => {
|
|
2704
|
+
return callMethod('EndSenseMe', {});
|
|
2705
|
+
};
|
|
2706
|
+
|
|
2707
|
+
/**
|
|
2708
|
+
* @function zego40路拉流混音接口
|
|
2709
|
+
* * @param { number } mixMode //混流模式 0=关闭混流 1=开启混流
|
|
2710
|
+
* * @param { array } streamIdArr //表示要突出声音的channel
|
|
2711
|
+
* * @param { number } mixNum //表示要突出channel的个数, 需要与参数'channels'的数组大小相同
|
|
2712
|
+
* @return: Promise
|
|
2713
|
+
*/
|
|
2714
|
+
export const setAudioMixMode = async (mixMode, streamIdArr) => {
|
|
2715
|
+
let channelsArr = [];
|
|
2716
|
+
if (streamIdArr.length > 0) {
|
|
2717
|
+
streamIdArr.forEach(item => {
|
|
2718
|
+
channelsArr.push(getChannelIndex(item));
|
|
2719
|
+
});
|
|
2720
|
+
}
|
|
2721
|
+
return callMethod('SetAudioMixMode', { mixMode: mixMode, channels: channelsArr, num: channelsArr.length });
|
|
2722
|
+
};
|
|
2723
|
+
|
|
2724
|
+
// 获取TalMedia.dll版本号
|
|
2725
|
+
export const getSDKVersion = async () => {
|
|
2726
|
+
return callMethod('GetSDKVersion', {});
|
|
2727
|
+
};
|
|
2728
|
+
|
|
2729
|
+
/**
|
|
2730
|
+
* @function 获取摄像头所支持的分辨率
|
|
2731
|
+
* @param deviceId:String 设备id
|
|
2732
|
+
* @return Promise | void
|
|
2733
|
+
*/
|
|
2734
|
+
export const getCameraSupportedRes = (deviceId) => {
|
|
2735
|
+
return callMethod('GetCameraSupportedResolution', {
|
|
2736
|
+
deviceId
|
|
2737
|
+
});
|
|
2738
|
+
};
|
|
2739
|
+
|
|
2740
|
+
/**
|
|
2741
|
+
* @function 发送SEI
|
|
2742
|
+
* @param inData: String 需要传输的音视频次要信息数据,外部输入。
|
|
2743
|
+
* @param dataLen: Number 数据长度,不能超过 4096 bytes
|
|
2744
|
+
* @param bPacket: Bool 是否采用外部打包好的包头,填写 false。
|
|
2745
|
+
* @param idx:Number 推流通道 index
|
|
2746
|
+
* 调用频率不能超过帧率,假设推流采用默认帧率15 fps,即调用频率不能超过 1000/15=66.7 ms/次。
|
|
2747
|
+
*/
|
|
2748
|
+
export const sendMediaSideInfo = (info) => {
|
|
2749
|
+
defaultApi.writeLog(`SendMediaSideInfo --info${info}`);
|
|
2750
|
+
return callMethod('SendMediaSideInfo', {
|
|
2751
|
+
inData: info,
|
|
2752
|
+
dataLen: info.length,
|
|
2753
|
+
bPacket: false,
|
|
2754
|
+
idx: 0
|
|
2755
|
+
});
|
|
2756
|
+
};
|
|
2757
|
+
|
|
2758
|
+
//判断当前课型是否为zego推拉RTMP小组课
|
|
2759
|
+
export const isZegoGroupClass = () => {
|
|
2760
|
+
defaultApi.writeLog(`test: isZegoGroupClass--currentClassMode--currentGroupSdkType', ${currentClassMode}, ${currentGroupSdkType}`);
|
|
2761
|
+
return currentClassMode == 0 && currentGroupSdkType == 'zego'/*rtmp流为zego*/;
|
|
2762
|
+
};
|
|
2763
|
+
//判断当前课型是否为zego推拉RTMP组合小班课
|
|
2764
|
+
export const isZegoCombinationClass = () => {
|
|
2765
|
+
console.log('test: isZegoCombinationClass--currentClassMode--currentGroupSdkType', currentClassMode, currentGroupSdkType);
|
|
2766
|
+
return currentClassMode == 2 && currentGroupSdkType == 'zego'/*rtmp流为zego*/;
|
|
2767
|
+
};
|
|
2768
|
+
//判断推流类型是否为音频流
|
|
2769
|
+
export const isStreamAudioMuted = () => {
|
|
2770
|
+
return callMethod('IsStreamAudioMuted', {});
|
|
2771
|
+
};
|
|
2772
|
+
//判断推流类型是否为视频流
|
|
2773
|
+
export const isStreamVideoMuted = () => {
|
|
2774
|
+
return callMethod('IsStreamVideoMuted', {});
|
|
2775
|
+
};
|
|
2776
|
+
export const getStreamType = async () => {
|
|
2777
|
+
try {
|
|
2778
|
+
const pushAudio = JSON.parse((await isStreamAudioMuted()).msg).ret;
|
|
2779
|
+
const pushVideo = JSON.parse((await isStreamVideoMuted()).msg).ret;
|
|
2780
|
+
let stream_type = 'both';
|
|
2781
|
+
if (pushAudio && !pushVideo) {
|
|
2782
|
+
stream_type = 'video';
|
|
2783
|
+
}
|
|
2784
|
+
if (!pushAudio && pushVideo) {
|
|
2785
|
+
stream_type = 'audio';
|
|
2786
|
+
}
|
|
2787
|
+
if (pushAudio && pushVideo) {
|
|
2788
|
+
stream_type = 'none';
|
|
2789
|
+
}
|
|
2790
|
+
return stream_type;
|
|
2791
|
+
} catch (e) {
|
|
2792
|
+
let stream_type = 'none';
|
|
2793
|
+
return stream_type;
|
|
2794
|
+
}
|
|
2795
|
+
};
|
|
2796
|
+
|
|
2797
|
+
const heartBeatRealKeys = ['video_fps', 'video_bitrate', 'audio_fps', 'audio_bitrate'];
|
|
2798
|
+
|
|
2799
|
+
const _heartBeatDataReport = () => {
|
|
2800
|
+
// let cpuRate = 0;
|
|
2801
|
+
// let memRate = 0;
|
|
2802
|
+
let rateCount = 0;
|
|
2803
|
+
// let appCpuRate = 0;
|
|
2804
|
+
// let appMemUsed = 0;
|
|
2805
|
+
let rateTimer = setInterval(async () => {
|
|
2806
|
+
rateCount++;
|
|
2807
|
+
// let {cpu_rate, mem_rate, gpus, app_cpu_rate, app_mem_used} = (await toolApi.getCurCpuMemInfo()).msg;
|
|
2808
|
+
// cpu_rate = cpu_rate < 0 ? 0 : cpu_rate;
|
|
2809
|
+
// cpuRate += parseFloat(cpu_rate);
|
|
2810
|
+
// memRate += parseFloat(mem_rate);
|
|
2811
|
+
// if (window.zbztAVSDK_init_params.zego.role === 'student') {
|
|
2812
|
+
// appCpuRate += parseFloat(app_cpu_rate);
|
|
2813
|
+
// appMemUsed += parseFloat(app_mem_used);
|
|
2814
|
+
// }
|
|
2815
|
+
|
|
2816
|
+
if (rateCount >= 3) {
|
|
2817
|
+
// heartBeatRealKeys.forEach(realKey => {
|
|
2818
|
+
// if (heartBeatDataReportObj.hasOwnProperty(realKey) && heartBeatDataReportObj.count > 0) {
|
|
2819
|
+
// heartBeatDataReportObj[realKey] = util.toFixed(heartBeatDataReportObj[realKey]/heartBeatDataReportObj.count);
|
|
2820
|
+
// }
|
|
2821
|
+
// });
|
|
2822
|
+
const pullInfo = [];
|
|
2823
|
+
Object.keys(streamIdRtcPlayerInfo).forEach(streamid => {
|
|
2824
|
+
heartBeatRealKeys.forEach(realKey => {
|
|
2825
|
+
if (!streamIdRtcPlayerInfo[streamid].hasOwnProperty(realKey)) {
|
|
2826
|
+
streamIdRtcPlayerInfo[streamid][realKey] = [];
|
|
2827
|
+
}
|
|
2828
|
+
// if (streamIdRtcPlayerInfo[streamid].count > 0) {
|
|
2829
|
+
// streamIdRtcPlayerInfo[streamid][realKey] = util.toFixed(streamIdRtcPlayerInfo[streamid][realKey]/streamIdRtcPlayerInfo[streamid].count);
|
|
2830
|
+
// }
|
|
2831
|
+
});
|
|
2832
|
+
|
|
2833
|
+
//获取拉流类型,后期可写为函数提出去
|
|
2834
|
+
if (streamIdRtcPlayerInfo1[streamid].audio_type && streamIdRtcPlayerInfo1[streamid].video_type) {
|
|
2835
|
+
streamIdRtcPlayerInfo1[streamid].stream_type = 'both';
|
|
2836
|
+
} else if (!streamIdRtcPlayerInfo1[streamid].audio_type && streamIdRtcPlayerInfo1[streamid].video_type) {
|
|
2837
|
+
streamIdRtcPlayerInfo1[streamid].stream_type = 'video';
|
|
2838
|
+
} else if (streamIdRtcPlayerInfo1[streamid].audio_type && !streamIdRtcPlayerInfo1[streamid].video_type) {
|
|
2839
|
+
streamIdRtcPlayerInfo1[streamid].stream_type = 'audio';
|
|
2840
|
+
} else {
|
|
2841
|
+
streamIdRtcPlayerInfo1[streamid].stream_type = 'none';
|
|
2842
|
+
}
|
|
2843
|
+
// console.log('hsghsghsg_type_type', streamIdRtcPlayerInfo1[streamid].stream_type);
|
|
2844
|
+
|
|
2845
|
+
// delete streamIdRtcPlayerInfo[streamid].count;
|
|
2846
|
+
pullInfo.push({
|
|
2847
|
+
streamid,
|
|
2848
|
+
// uid: util.getUidByStreamId(streamid),
|
|
2849
|
+
...streamIdRtcPlayerInfo[streamid],
|
|
2850
|
+
pull_type: streamIdRtcPlayerInfo1[streamid].stream_type,
|
|
2851
|
+
volume: streamIdRtcPlayerInfo[streamid].volume.slice(0, streamIdRtcPlayerInfo[streamid].volume.length - 1)
|
|
2852
|
+
});
|
|
2853
|
+
resetStreamIdRtcPlayerInfo(streamid);
|
|
2854
|
+
});
|
|
2855
|
+
// delete heartBeatDataReportObj.count;
|
|
2856
|
+
if (isFirstHeartBeatReport && rateCount > 0) {
|
|
2857
|
+
try {
|
|
2858
|
+
//静音推流时过滤掉音频帧率和码率,上报为0;
|
|
2859
|
+
// if (!isNoticeMicVolumeZego) {
|
|
2860
|
+
// heartBeatDataReportObj['audio_fps'] = [];
|
|
2861
|
+
// heartBeatDataReportObj['audio_bitrate'] = [];
|
|
2862
|
+
// }
|
|
2863
|
+
|
|
2864
|
+
//获取推流类型,后期可写为函数提出去
|
|
2865
|
+
if (zbztsdk.deviceStatus.camera && zbztsdk.deviceStatus.microphone) {
|
|
2866
|
+
zbztsdk.deviceStatus.stream_type = 'both';
|
|
2867
|
+
} else if (!zbztsdk.deviceStatus.camera && zbztsdk.deviceStatus.microphone) {
|
|
2868
|
+
zbztsdk.deviceStatus.stream_type = 'audio';
|
|
2869
|
+
} else if (zbztsdk.deviceStatus.camera && !zbztsdk.deviceStatus.microphone) {
|
|
2870
|
+
zbztsdk.deviceStatus.stream_type = 'video';
|
|
2871
|
+
} else {
|
|
2872
|
+
zbztsdk.deviceStatus.stream_type = 'none';
|
|
2873
|
+
};
|
|
2874
|
+
// console.log('push_type222',zbztsdk.deviceStatus,zbztsdk.deviceStatus.stream_type);
|
|
2875
|
+
defaultApi.writeLog(`push_type_zego,camera: ${zbztsdk.deviceStatus.camera},microphone: ${zbztsdk.deviceStatus.microphone},type: ${zbztsdk.deviceStatus.stream_type},a_fps: ${dataZegoCapture.afps}, a_bit: ${dataZegoCapture.akbps}, v_fps: ${dataZegoCapture.fps}, v_bit: ${dataZegoCapture.kbps}`);
|
|
2876
|
+
// if (window.zbztAVSDK_init_params.zego.role === 'teacher') {
|
|
2877
|
+
dataReport.heartbeat({
|
|
2878
|
+
...{ ...heartBeatDataReportObj, push_type: zbztsdk.deviceStatus.stream_type, volume: heartBeatDataReportObj.volume.slice(0, heartBeatDataReportObj.volume.length - 1) },
|
|
2879
|
+
// pull_info: JSON.stringify(pullInfo),
|
|
2880
|
+
pull_info: pullInfo,
|
|
2881
|
+
// cpu_rate: util.toFixed(cpuRate/rateCount),
|
|
2882
|
+
// mem_rate: util.toFixed(memRate/rateCount),
|
|
2883
|
+
});
|
|
2884
|
+
// } else {
|
|
2885
|
+
// dataReport.heartbeat({
|
|
2886
|
+
// ...heartBeatDataReportObj,
|
|
2887
|
+
// pull_info: JSON.stringify(pullInfo),
|
|
2888
|
+
// cpu_rate: util.toFixed(cpuRate/rateCount),
|
|
2889
|
+
// mem_rate: util.toFixed(memRate/rateCount),
|
|
2890
|
+
// app_cpu: util.toFixed(appCpuRate/rateCount),
|
|
2891
|
+
// app_mem: util.toFixed(appMemUsed/rateCount),
|
|
2892
|
+
// video_mem: gpus
|
|
2893
|
+
// });
|
|
2894
|
+
// }
|
|
2895
|
+
} catch (e) {
|
|
2896
|
+
console.log(e);
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2899
|
+
resetHeartBeatDataReportObj();
|
|
2900
|
+
rateCount = 0;
|
|
2901
|
+
// cpuRate = 0;
|
|
2902
|
+
// memRate = 0;
|
|
2903
|
+
// appCpuRate = 0;
|
|
2904
|
+
// appMemUsed = 0;
|
|
2905
|
+
|
|
2906
|
+
clearInterval(rateTimer);
|
|
2907
|
+
}
|
|
2908
|
+
}, 10 * 1000);
|
|
2909
|
+
};
|
|
2910
|
+
|
|
2911
|
+
const heartBeatDataReport = (type) => {
|
|
2912
|
+
try {
|
|
2913
|
+
if (type === 'start' && !heartBeatDataReportTimer) {
|
|
2914
|
+
_heartBeatDataReport();
|
|
2915
|
+
heartBeatDataReportTimer = setInterval(() => {
|
|
2916
|
+
_heartBeatDataReport();
|
|
2917
|
+
}, 30 * 1000);
|
|
2918
|
+
}
|
|
2919
|
+
if (type === 'stop') {
|
|
2920
|
+
clearInterval(heartBeatDataReportTimer);
|
|
2921
|
+
heartBeatDataReportTimer = null;
|
|
2922
|
+
}
|
|
2923
|
+
} catch (error) {
|
|
2924
|
+
console.log(error);
|
|
2925
|
+
}
|
|
2926
|
+
};
|
|
2927
|
+
|
|
2928
|
+
const heartBeatDataReportCalc = (name, _d, streamid) => {
|
|
2929
|
+
// 拉流
|
|
2930
|
+
const pullKeys = ['fps', 'kbps', 'afps', 'akbps'];
|
|
2931
|
+
if (name === 'OnPlayQulityUpdate') {
|
|
2932
|
+
if (streamIdRtcPlayerInfo && streamIdRtcPlayerInfo.hasOwnProperty(streamid)) {
|
|
2933
|
+
let isReport = true;
|
|
2934
|
+
// streamIdRtcPlayerInfo[streamid].count++;
|
|
2935
|
+
heartBeatRealKeys.forEach((realKey, index) => {
|
|
2936
|
+
if (_d.hasOwnProperty(pullKeys[index])) {
|
|
2937
|
+
if (streamIdRtcPlayerInfo[streamid][realKey] === undefined) {
|
|
2938
|
+
streamIdRtcPlayerInfo[streamid][realKey] = [];
|
|
2939
|
+
isReport = false;
|
|
2940
|
+
}
|
|
2941
|
+
// streamIdRtcPlayerInfo[streamid][realKey].push(parseFloat(parseInt(_d[pullKeys[index]])));
|
|
2942
|
+
}
|
|
2943
|
+
});
|
|
2944
|
+
if (isReport) {
|
|
2945
|
+
let audio_fps_zego_pull = 0;
|
|
2946
|
+
let audio_bitrate_zego_pull = 0;
|
|
2947
|
+
let video_fps_zego_pull = 0;
|
|
2948
|
+
let video_bitrate_zego_pull = 0;
|
|
2949
|
+
|
|
2950
|
+
if (streamIdRtcPlayerInfo1[streamid].audio_type && streamIdRtcPlayerInfo1[streamid].video_type) {
|
|
2951
|
+
audio_fps_zego_pull = parseFloat(parseInt(_d.afps));
|
|
2952
|
+
audio_bitrate_zego_pull = parseFloat(parseInt(_d.akbps));
|
|
2953
|
+
video_fps_zego_pull = parseFloat(parseInt(_d.fps));
|
|
2954
|
+
video_bitrate_zego_pull = parseFloat(parseInt(_d.kbps));
|
|
2955
|
+
} else if (!streamIdRtcPlayerInfo1[streamid].audio_type && streamIdRtcPlayerInfo1[streamid].video_type) {
|
|
2956
|
+
video_fps_zego_pull = parseFloat(parseInt(_d.fps));
|
|
2957
|
+
video_bitrate_zego_pull = parseFloat(parseInt(_d.kbps));
|
|
2958
|
+
} else if (streamIdRtcPlayerInfo1[streamid].audio_type && !streamIdRtcPlayerInfo1[streamid].video_type) {
|
|
2959
|
+
audio_fps_zego_pull = parseFloat(parseInt(_d.afps));
|
|
2960
|
+
audio_bitrate_zego_pull = parseFloat(parseInt(_d.akbps));
|
|
2961
|
+
}
|
|
2962
|
+
streamIdRtcPlayerInfo[streamid].audio_fps.push(audio_fps_zego_pull);
|
|
2963
|
+
streamIdRtcPlayerInfo[streamid].audio_bitrate.push(audio_bitrate_zego_pull);
|
|
2964
|
+
streamIdRtcPlayerInfo[streamid].video_fps.push(video_fps_zego_pull);
|
|
2965
|
+
streamIdRtcPlayerInfo[streamid].video_bitrate.push(video_bitrate_zego_pull);
|
|
2966
|
+
|
|
2967
|
+
streamIdRtcPlayerInfo[streamid].ctime.push(Math.round((new Date().getTime() + dataReport.timestamp) / 1000));
|
|
2968
|
+
streamIdRtcPlayerInfo[streamid].avtimestampdiff.push(_d.avTimestampDiff);
|
|
2969
|
+
streamIdRtcPlayerInfo[streamid].pull_loss.push(_d.pktLostRate);
|
|
2970
|
+
streamIdRtcPlayerInfo[streamid].pull_delay.push(_d.rtt);
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
// 推流
|
|
2975
|
+
const pushKeys = ['fps', 'kbps', 'afps', 'akbps'];
|
|
2976
|
+
if (name === 'OnPublishQualityUpdate') {
|
|
2977
|
+
// heartBeatDataReportObj.count++;
|
|
2978
|
+
// heartBeatRealKeys.forEach((realKey, index) => {
|
|
2979
|
+
// if (heartBeatDataReportObj.hasOwnProperty(realKey) && _d.hasOwnProperty(pushKeys[index])) {
|
|
2980
|
+
// heartBeatDataReportObj[realKey].push(parseFloat(parseInt(_d[pushKeys[index]])));
|
|
2981
|
+
// }
|
|
2982
|
+
// });
|
|
2983
|
+
let audio_fps_zego_push = 0;
|
|
2984
|
+
let audio_bitrate_zego_push = 0;
|
|
2985
|
+
let video_fps_zego_push = 0;
|
|
2986
|
+
let video_bitrate_zego_push = 0;
|
|
2987
|
+
dataZegoCapture = _d;
|
|
2988
|
+
|
|
2989
|
+
if (zbztsdk.deviceStatus.camera && zbztsdk.deviceStatus.microphone) {
|
|
2990
|
+
audio_fps_zego_push = parseFloat(parseInt(_d.afps));
|
|
2991
|
+
audio_bitrate_zego_push = parseFloat(parseInt(_d.akbps));
|
|
2992
|
+
video_fps_zego_push = parseFloat(parseInt(_d.fps));
|
|
2993
|
+
video_bitrate_zego_push = parseFloat(parseInt(_d.kbps));
|
|
2994
|
+
} else if (!zbztsdk.deviceStatus.camera && zbztsdk.deviceStatus.microphone) {
|
|
2995
|
+
audio_fps_zego_push = parseFloat(parseInt(_d.afps));
|
|
2996
|
+
audio_bitrate_zego_push = parseFloat(parseInt(_d.akbps));
|
|
2997
|
+
} else if (zbztsdk.deviceStatus.camera && !zbztsdk.deviceStatus.microphone) {
|
|
2998
|
+
video_fps_zego_push = parseFloat(parseInt(_d.fps));
|
|
2999
|
+
video_bitrate_zego_push = parseFloat(parseInt(_d.kbps));
|
|
3000
|
+
}
|
|
3001
|
+
heartBeatDataReportObj.audio_fps.push(audio_fps_zego_push);
|
|
3002
|
+
heartBeatDataReportObj.audio_bitrate.push(audio_bitrate_zego_push);
|
|
3003
|
+
heartBeatDataReportObj.video_fps.push(video_fps_zego_push);
|
|
3004
|
+
heartBeatDataReportObj.video_bitrate.push(video_bitrate_zego_push);
|
|
3005
|
+
|
|
3006
|
+
heartBeatDataReportObj.push_loss.push(_d.pktLostRate);
|
|
3007
|
+
heartBeatDataReportObj.push_delay.push(_d.rtt);
|
|
3008
|
+
heartBeatDataReportObj.ctime.push(Math.round((new Date().getTime() + dataReport.timestamp) / 1000));
|
|
3009
|
+
}
|
|
3010
|
+
};
|
|
3011
|
+
//推流字段
|
|
3012
|
+
const resetHeartBeatDataReportObj = () => {
|
|
3013
|
+
heartBeatDataReportObj = {
|
|
3014
|
+
ctime: [],
|
|
3015
|
+
push_type: 'none',
|
|
3016
|
+
// video_fps: 0,
|
|
3017
|
+
// video_bitrate: 0,
|
|
3018
|
+
// audio_fps: 0,
|
|
3019
|
+
// audio_bitrate: 0,
|
|
3020
|
+
video_fps: [],
|
|
3021
|
+
video_bitrate: [],
|
|
3022
|
+
audio_fps: [],
|
|
3023
|
+
audio_bitrate: [],
|
|
3024
|
+
push_loss: [],
|
|
3025
|
+
push_delay: [],
|
|
3026
|
+
// count: 0,
|
|
3027
|
+
volume: ''
|
|
3028
|
+
};
|
|
3029
|
+
};
|
|
3030
|
+
|
|
3031
|
+
//记录拉流类型,用作数据上报
|
|
3032
|
+
const resetStreamIdRtcPlayerInfo1 = (streamId) => {
|
|
3033
|
+
streamIdRtcPlayerInfo1[streamId] = {
|
|
3034
|
+
audio_type: false,
|
|
3035
|
+
video_type: false,
|
|
3036
|
+
stream_type: 'none'
|
|
3037
|
+
};
|
|
3038
|
+
};
|
|
3039
|
+
|
|
3040
|
+
resetHeartBeatDataReportObj();
|
|
3041
|
+
|
|
3042
|
+
//拉流字段
|
|
3043
|
+
const resetStreamIdRtcPlayerInfo = (streamId) => {
|
|
3044
|
+
streamIdRtcPlayerInfo[streamId] = {
|
|
3045
|
+
pull_uid: util.getUidByStreamId(streamId),
|
|
3046
|
+
streamid: streamId,
|
|
3047
|
+
ctime: [],
|
|
3048
|
+
pull_type: streamIdRtcPlayerInfo1[streamId].stream_type,
|
|
3049
|
+
volume: '',
|
|
3050
|
+
// 平均值
|
|
3051
|
+
// count: 0,
|
|
3052
|
+
// video_fps: 0,
|
|
3053
|
+
// video_bitrate: 0,
|
|
3054
|
+
// audio_fps: 0,
|
|
3055
|
+
// audio_bitrate: 0,
|
|
3056
|
+
video_fps: [],
|
|
3057
|
+
video_bitrate: [],
|
|
3058
|
+
audio_fps: [],
|
|
3059
|
+
audio_bitrate: [],
|
|
3060
|
+
pull_loss: [],
|
|
3061
|
+
pull_delay: [],
|
|
3062
|
+
//音画不同步字段
|
|
3063
|
+
avtimestampdiff: [],
|
|
3064
|
+
// 累加
|
|
3065
|
+
audio_ifg: 0,
|
|
3066
|
+
video_ifg: 0
|
|
3067
|
+
};
|
|
3068
|
+
};
|
|
3069
|
+
|
|
3070
|
+
export default {
|
|
3071
|
+
startEngine,
|
|
3072
|
+
destroyEngine,
|
|
3073
|
+
setDefaultDevice,
|
|
3074
|
+
getVideoDeviceList,
|
|
3075
|
+
setVideoDevice,
|
|
3076
|
+
enableCamera,
|
|
3077
|
+
enableMic,
|
|
3078
|
+
setAudioSpeakerCapture,
|
|
3079
|
+
getAudioDeviceList,
|
|
3080
|
+
setAudioDevice,
|
|
3081
|
+
getSpeakerDeviceList,
|
|
3082
|
+
setSpeakerDevice,
|
|
3083
|
+
getCurrentSpeakerDevice,
|
|
3084
|
+
getSpeakerDeviceVolume,
|
|
3085
|
+
setSpeakerDeviceVolume,
|
|
3086
|
+
setSpeakerDeviceMute,
|
|
3087
|
+
getMicrophoneDeviceList,
|
|
3088
|
+
setMicrophoneDevice,
|
|
3089
|
+
getMicDeviceVolume,
|
|
3090
|
+
setMicDeviceVolume,
|
|
3091
|
+
setMicDeviceMute,
|
|
3092
|
+
getSpeakerSimpleVolume,
|
|
3093
|
+
setSpeakerSimpleVolume,
|
|
3094
|
+
setSpeakerSimpleMute,
|
|
3095
|
+
setPreviewView,
|
|
3096
|
+
startPreview,
|
|
3097
|
+
startLocalOrRemotePreview,
|
|
3098
|
+
setVideoFPS,
|
|
3099
|
+
setVideoBitrate,
|
|
3100
|
+
setAudioBitrate,
|
|
3101
|
+
setVideoCaptureResolution,
|
|
3102
|
+
setCameraParam,
|
|
3103
|
+
setVideoEncodeResolution,
|
|
3104
|
+
init,
|
|
3105
|
+
startPublish2,
|
|
3106
|
+
stopPublish,
|
|
3107
|
+
initPullFlow,
|
|
3108
|
+
playStream,
|
|
3109
|
+
stopPlayStream,
|
|
3110
|
+
stopAllPlayStream,
|
|
3111
|
+
leaveRoom,
|
|
3112
|
+
activateAudioPlayStream,
|
|
3113
|
+
pullAudioFlow,
|
|
3114
|
+
activateVideoPlayStream,
|
|
3115
|
+
setAudioVolumeNotify,
|
|
3116
|
+
stopAudioVolumeNotify,
|
|
3117
|
+
openMicVolumeCb,
|
|
3118
|
+
startSoundLevelMonitor,
|
|
3119
|
+
stopSoundLevelMonitor,
|
|
3120
|
+
setSoundLevelMonitorCycle,
|
|
3121
|
+
setMirrorStatus,
|
|
3122
|
+
getStreamType,
|
|
3123
|
+
setPlayViewMirror,
|
|
3124
|
+
setMuteStreamAudio,
|
|
3125
|
+
setMuteStreamVideo,
|
|
3126
|
+
teacherStartLinkMic,
|
|
3127
|
+
teacherStopLinkMic,
|
|
3128
|
+
getSDKVersion,
|
|
3129
|
+
getCameraSupportedRes,
|
|
3130
|
+
setVideoMirrorMode,
|
|
3131
|
+
startMultiScreen,
|
|
3132
|
+
addListener,
|
|
3133
|
+
};
|