@tencentcloud/sdk-mcp 1.3.4 → 1.3.6
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/index.js +4 -4
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/resource/doc/chatuikit/android/features/theme.md +363 -0
- package/resource/doc/chatuikit/{android/client_api_android.md → faq/android_sdk/client-api.md} +0 -1
- package/resource/doc/chatuikit/faq/{native_sdk/faq.md → common/product.md} +8 -0
- package/resource/doc/chatuikit/faq/flutter_sdk/faq.md +54 -0
- package/resource/doc/chatuikit/faq/web_sdk/faq.md +1 -1
- package/resource/doc/chatuikit/flutter/features/theme.md +379 -0
- package/resource/doc/chatuikit/flutter/workflow.md +816 -0
- package/resource/doc/chatuikit/iOS/features/theme.md +416 -0
- package/resource/doc/chatuikit/iOS/workflow.md +0 -0
- package/resource/doc/chatuikit/react/components/chat-setting.md +124 -0
- package/resource/doc/chatuikit/react/components/contact-list.md +1331 -0
- package/resource/doc/chatuikit/react/components/search.md +885 -0
- package/resource/doc/chatuikit/vue/components/chat-setting.md +88 -0
- package/resource/doc/chatuikit/vue/components/contact-list.md +679 -0
- package/resource/doc/chatuikit/vue/components/search.md +1384 -0
- package/resource/doc/livekit/live/android/workflow.md +137 -4
- package/resource/doc/livekit/live/flutter/live-audience-list.md +337 -0
- package/resource/doc/livekit/live/flutter/live-audio-effect.md +739 -0
- package/resource/doc/livekit/live/flutter/live-barrage.md +578 -0
- package/resource/doc/livekit/live/flutter/live-base-beauty.md +484 -0
- package/resource/doc/livekit/live/flutter/live-co-guest-interaction.md +606 -0
- package/resource/doc/livekit/live/flutter/live-gift.md +812 -0
- package/resource/doc/livekit/live/flutter/live-host-interaction.md +1113 -0
- package/resource/doc/livekit/live/flutter/live-integration.md +1029 -0
- package/resource/doc/livekit/live/flutter/live-live-list.md +861 -0
- package/resource/doc/livekit/live/ios/live-audience-list.md +335 -0
- package/resource/doc/livekit/live/ios/live-audio-effect.md +373 -0
- package/resource/doc/livekit/live/ios/live-barrage.md +529 -0
- package/resource/doc/livekit/live/ios/live-base-beauty.md +237 -0
- package/resource/doc/livekit/live/ios/live-co-guest-interaction.md +483 -0
- package/resource/doc/livekit/live/ios/live-gift.md +785 -0
- package/resource/doc/livekit/live/ios/live-host-interaction.md +743 -0
- package/resource/doc/livekit/live/ios/live-integration.md +822 -0
- package/resource/doc/livekit/live/ios/live-live-list.md +535 -0
- package/resource/doc/livekit/live/ios/workflow.md +352 -0
- package/resource/doc/rtcengine/faq/web/web.md +2 -2
- package/resource/doc/rtcengine/web/how_to_integrated_web_sdk.md +2 -2
- package/resource/doc/rtcengine/web/plugin/20-advanced-customized-capture-rendering.md +84 -0
- package/resource/doc/rtcengine/web/plugin/21-advanced-auto-play-policy.md +86 -0
- package/resource/doc/rtcengine/web/plugin/22-advanced-audio-mixer.md +220 -0
- package/resource/doc/rtcengine/web/plugin/23-advanced-support-detection.md +217 -0
- package/resource/doc/rtcengine/web/plugin/24-advanced-network-quality.md +137 -0
- package/resource/doc/rtcengine/web/plugin/25-advanced-device-change.md +97 -0
- package/resource/doc/rtcengine/web/plugin/26-advanced-publish-cdn-stream.md +453 -0
- package/resource/doc/rtcengine/web/plugin/27-advanced-small-stream.md +180 -0
- package/resource/doc/rtcengine/web/plugin/28-advanced-beauty.md +349 -0
- package/resource/doc/rtcengine/web/plugin/29-advanced-water-mark.md +149 -0
- package/resource/doc/rtcengine/web/plugin/30-advanced-cross-room-link.md +96 -0
- package/resource/doc/rtcengine/web/plugin/31-advanced-plugins-overview.md +405 -0
- package/resource/doc/rtcengine/web/plugin/34-advanced-proxy.md +244 -0
- package/resource/doc/rtcengine/web/plugin/35-advanced-ai-denoiser.md +84 -0
- package/resource/doc/rtcengine/web/plugin/36-advanced-virtual-background.md +202 -0
- package/resource/doc/rtcengine/web/plugin/37-advanced-voice-changer.md +98 -0
- package/resource/doc/rtcengine/web/plugin/38-advanced-basic-beauty.md +95 -0
- package/resource/doc/rtcengine/web/plugin/39-advanced-video-decoder.md +33 -0
- package/resource/doc/rtcengine/web/plugin/40-advanced-video-mixer.md +380 -0
- package/resource/doc/rtcengine/web/plugin/41-advanced-small-stream-auto-switcher.md +91 -0
- package/resource/doc/rtcengine/web/plugin/42-advanced-realtime-transcriber.md +314 -0
- package/resource/doc/rtcengine/web/plugin/43-advanced-face-detection.md +180 -0
- package/resource/doc/tuicallkit/android/workflow.md +0 -0
- package/resource/doc/tuicallkit/flutter/integration.md +510 -0
- package/resource/doc/tuicallkit/flutter/workflow.md +331 -0
- package/tools/call/get-native-call-integration.js +27 -11
- package/tools/call/get-native-call-integration.js.map +1 -1
- package/tools/chat/get-native-chat-feature-detail.js +30 -0
- package/tools/chat/get-native-chat-feature-detail.js.map +1 -0
- package/tools/chat/get-native-chat-integration.js +30 -12
- package/tools/chat/get-native-chat-integration.js.map +1 -1
- package/tools/common/get-faq.js +2 -4
- package/tools/common/get-faq.js.map +1 -1
- package/tools/definitions/get_native_call_uikit_integration_def.js +16 -6
- package/tools/definitions/get_native_call_uikit_integration_def.js.map +1 -1
- package/tools/definitions/get_native_chat_feature_detail_def.js +32 -0
- package/tools/definitions/get_native_chat_feature_detail_def.js.map +1 -0
- package/tools/definitions/get_native_chat_uikit_integration_def.js +18 -6
- package/tools/definitions/get_native_chat_uikit_integration_def.js.map +1 -1
- package/tools/definitions/{get_native_live_extra_features_def.js → get_native_live_uikit_extra_features_def.js} +3 -3
- package/tools/definitions/get_native_live_uikit_extra_features_def.js.map +1 -0
- package/tools/definitions/{get_native_live_interaction_def.js → get_native_live_uikit_interaction_def.js} +3 -3
- package/tools/definitions/get_native_live_uikit_interaction_def.js.map +1 -0
- package/tools/definitions/get_web_chat_uikit_component_detail_def.js +46 -7
- package/tools/definitions/get_web_chat_uikit_component_detail_def.js.map +1 -1
- package/tools/index.js +6 -4
- package/tools/index.js.map +1 -1
- package/tools/live/{get_native_live_extra_features.js → get_native_live_uikit_extra_features.js} +4 -4
- package/tools/live/get_native_live_uikit_extra_features.js.map +1 -0
- package/tools/live/{get_native_live_interaction.js → get_native_live_uikit_interaction.js} +4 -4
- package/tools/live/get_native_live_uikit_interaction.js.map +1 -0
- package/tools/rtcengine/get-trtc-web-sdk-faq.js +1 -1
- package/tools/rtcengine/get-trtc-web-sdk-plugin.js +45 -0
- package/tools/rtcengine/get-trtc-web-sdk-plugin.js.map +1 -0
- package/utils/handle-component-name.js +0 -16
- package/utils/handle-component-name.js.map +1 -1
- package/utils/report-cls-client.js +1 -1
- package/utils/report-es-client.js +1 -1
- package/resource/doc/chatuikit/android/integrate_tuichat_only_android.md +0 -382
- package/resource/doc/chatuikit/android/ui_api_android.md +0 -418
- package/resource/doc/chatuikit/iOS/integrate_tuichat_only_iOS.md +0 -993
- package/resource/doc/chatuikit/iOS/ui_api_iOS.md +0 -526
- package/resource/doc/tuicallkit/flutter/how_to_integrated_flutter_callkit.md +0 -226
- package/resource/doc/tuicallkit/flutter/how_to_run_flutter_callkit_demo.md +0 -101
- package/resource/doc/tuicallkit/iOS/how_to_run_iOS_callkit_demo.md +0 -98
- package/tools/definitions/get_native_live_extra_features_def.js.map +0 -1
- package/tools/definitions/get_native_live_interaction_def.js.map +0 -1
- package/tools/live/get_native_live_extra_features.js.map +0 -1
- package/tools/live/get_native_live_interaction.js.map +0 -1
- /package/resource/doc/chatuikit/android/{integrate_tuikit_android.md → integration.md} +0 -0
- /package/resource/doc/{tuicallkit/android/.gitkeep → chatuikit/android/workflow.md} +0 -0
- /package/resource/doc/chatuikit/{flutter/client_api_Flutter.md → faq/flutter_sdk/client-api.md} +0 -0
- /package/resource/doc/chatuikit/{iOS/client_api_iOS.md → faq/ios_sdk/client-api.md} +0 -0
- /package/resource/doc/chatuikit/flutter/{integrate_tuikit_Flutter.md → integration.md} +0 -0
- /package/resource/doc/chatuikit/iOS/{integrate_tuikit_iOS.md → integration.md} +0 -0
- /package/resource/doc/chatuikit/react/components/{chatheader.md → chat-header.md} +0 -0
- /package/resource/doc/chatuikit/vue/components/{chatheader.md → chat-header.md} +0 -0
- /package/resource/doc/tuicallkit/android/{how_to_integrated_android_callkit.md → integration.md} +0 -0
- /package/resource/doc/tuicallkit/{android/api_TUICallObserver.md → faq/android_sdk/call-observer-api.md} +0 -0
- /package/resource/doc/tuicallkit/{android/api_TUICallKit.md → faq/android_sdk/callkit-api.md} +0 -0
- /package/resource/doc/tuicallkit/{flutter/api_TUICallDefine.md → faq/flutter_sdk/call-define-api.md} +0 -0
- /package/resource/doc/tuicallkit/{flutter/api_TUICallObserver.md → faq/flutter_sdk/call-observer-api.md} +0 -0
- /package/resource/doc/tuicallkit/{flutter/api_TUICallKit.md → faq/flutter_sdk/callkit-api.md} +0 -0
- /package/resource/doc/tuicallkit/{iOS/api_TUICallObserver.md → faq/ios_sdk/call-observer-api.md} +0 -0
- /package/resource/doc/tuicallkit/{iOS/api_TUICallKit.md → faq/ios_sdk/callkit-api.md} +0 -0
- /package/resource/doc/tuicallkit/iOS/{how_to_integrated_iOS_callkit.md → integration.md} +0 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
## 功能描述
|
|
2
|
+
|
|
3
|
+
本文将介绍如何在通话过程中增加背景音乐的功能,点击 [体验 demo](https://web.sdk.qcloud.com/trtc/webrtc/demo/api-sample/improve-audio-mixer.html?roomID=43222) 进行体验。
|
|
4
|
+
|
|
5
|
+
## 前提条件
|
|
6
|
+
|
|
7
|
+
- TRTC 版本 > 5.1.0
|
|
8
|
+
- 支持在通话中添加背景音乐的平台如下
|
|
9
|
+
|
|
10
|
+
| 操作系统 | 浏览器类型 | 浏览器最低版本要求 |
|
|
11
|
+
|:-------:|:-----------------|:---------:|
|
|
12
|
+
| Mac OS | 桌面版 Chrome 浏览器 | 56+ |
|
|
13
|
+
| Mac OS | 桌面版 Safari 浏览器 | 11+ |
|
|
14
|
+
| Mac OS | 桌面版 Firefox 浏览器 | 56+ |
|
|
15
|
+
| Mac OS | 桌面版 Edge | 80+ |
|
|
16
|
+
| Windows | 桌面版 Chrome 浏览器 | 56+ |
|
|
17
|
+
| Windows | 桌面版 QQ 浏览器(极速模式) | 10.4+ |
|
|
18
|
+
| Windows | 桌面版 Firefox 浏览器 | 56+ |
|
|
19
|
+
| Windows | 桌面版 Edge | 80+ |
|
|
20
|
+
| iOS | 移动版 Safari 浏览器 | 14+ |
|
|
21
|
+
| iOS | 微信内嵌网页 | ✖ |
|
|
22
|
+
| Android | 移动版 Chrome 浏览器 | 81+ |
|
|
23
|
+
| Android | 微信内嵌网页(TBS 内核) | ✔ |
|
|
24
|
+
| Android | 移动版 QQ 浏览器 | ✖ |
|
|
25
|
+
|
|
26
|
+
## 实现流程
|
|
27
|
+
|
|
28
|
+
### 1. 进房并打开麦克风
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
const trtc = TRTC.create();
|
|
32
|
+
await trtc.enterRoom({ roomId: 8888, sdkAppId, userId, userSig });
|
|
33
|
+
await trtc.startLocalAudio();
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 2. 开启一首背景音乐
|
|
37
|
+
|
|
38
|
+
如开启 `../assets/count.mp3`,使用 `trtc.startPlugin` 方法,将其 id 设置为 `count`,后续操作这个 id 即操作这个音乐。
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
await trtc.startPlugin('AudioMixer', {
|
|
42
|
+
id: 'count',
|
|
43
|
+
url: '../assets/count.mp3'
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
除此之外还可以传入 loop、volume、事件监听等参数,详见后文 API 说明部分。
|
|
48
|
+
|
|
49
|
+
### 3. 按需更新背景音乐
|
|
50
|
+
|
|
51
|
+
如果需要对音乐进行进一步操作,可以根据上一步注册的音乐 id,调用 `trtc.updatePlugin` 接口来进行。
|
|
52
|
+
|
|
53
|
+
除 loop、volume、事件监听等参数之外,updatePlugin 还可以执行音乐暂停、恢复、跳转操作。详见后文 API 说明部分。
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
// 取消循环播放
|
|
57
|
+
await trtc.updatePlugin('AudioMixer', {
|
|
58
|
+
id: 'count',
|
|
59
|
+
loop: false
|
|
60
|
+
})
|
|
61
|
+
// 设置音量
|
|
62
|
+
await trtc.updatePlugin('AudioMixer', {
|
|
63
|
+
id: 'count',
|
|
64
|
+
volume: 1
|
|
65
|
+
})
|
|
66
|
+
// 将 count 音乐暂停
|
|
67
|
+
await trtc.updatePlugin('AudioMixer', {
|
|
68
|
+
id: 'count',
|
|
69
|
+
operation: 'pause'
|
|
70
|
+
})
|
|
71
|
+
// 将 count 音乐恢复
|
|
72
|
+
await trtc.updatePlugin('AudioMixer', {
|
|
73
|
+
id: 'count',
|
|
74
|
+
operation: 'resume'
|
|
75
|
+
})
|
|
76
|
+
// 将 count 音乐从第 5s 开始播放
|
|
77
|
+
await trtc.updatePlugin('AudioMixer', {
|
|
78
|
+
id: 'count',
|
|
79
|
+
seekFrom: 5
|
|
80
|
+
})
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4. 关闭背景音乐
|
|
84
|
+
|
|
85
|
+
注意,音乐播放一旦 start 后,无法自行 stop,因此需要此接口来关闭某个不需要使用的音乐。关闭后方可再次 start。
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
await trtc.stopPlugin('AudioMixer', {
|
|
89
|
+
id: 'count'
|
|
90
|
+
})
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
// bad: 连续 start 相同 id 两次
|
|
95
|
+
startPlugin({ id: 'bgm1', url: './xxx.mp3' })
|
|
96
|
+
startPlugin({ id: 'bgm1', url: './xxx.mp3' })
|
|
97
|
+
|
|
98
|
+
// good: start 后用 update
|
|
99
|
+
startPlugin({ id: 'bgm1', url: './xxx.mp3' })
|
|
100
|
+
updatePlugin({ id: 'bgm1' })
|
|
101
|
+
|
|
102
|
+
// good: 可以同时开启两个背景音乐
|
|
103
|
+
startPlugin({ id: 'bgm1' })
|
|
104
|
+
startPlugin({ id: 'bgm2' })
|
|
105
|
+
|
|
106
|
+
// good: stop 后下次可以正常再开启
|
|
107
|
+
startPlugin({ id: 'bgm1' })
|
|
108
|
+
stopPlugin({ id: 'bgm1' })
|
|
109
|
+
startPlugin({ id: 'bgm1' })
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## API 说明
|
|
113
|
+
|
|
114
|
+
### trtc.startPlugin('AudioMixer', options)
|
|
115
|
+
|
|
116
|
+
用于增加一个背景音乐
|
|
117
|
+
|
|
118
|
+
#### options
|
|
119
|
+
|
|
120
|
+
| Name | Type | Attributes | Description |
|
|
121
|
+
|--------|-----------|--------------|-------------------------------------|
|
|
122
|
+
| id | `string` | | 给当前传入的音乐 url 自定义一个唯一的 ID, 例如: 'bgm' |
|
|
123
|
+
| url | `string` | | 音乐文件地址,与下方的 track 字段必须二选一填入,若同时传入,以 url 为准 |
|
|
124
|
+
| track | `MediaStreamAudioTrack` | | 自 v5.4.3+ 支持,与 url 二选一,可以传入从 `<audio/>` 标签中提取的 ,若同时传入,以 url 为准 |
|
|
125
|
+
| loop | `boolean` | `<optional>` | 是否循环播放,默认为 false |
|
|
126
|
+
| volume | `number` | `<optional>` | 设置初始音量,默认为 1 (0-1)。暂不支持 iOS。 |
|
|
127
|
+
| playbackRate | `number` | `<optional>` | 设置播放速率,默认为 1.0 |
|
|
128
|
+
| onDurationChange | `function` | `<optional>` | 回调函数,音乐加载完会执行,参数为 (duration: number) 标识音乐总时长 |
|
|
129
|
+
| onTimeUpdate | `function` | `<optional>` | 回调函数,音乐播放过程中会持续触发,参数为 (currentTime: number, duration: number) 标识音乐当前进度和总时长 |
|
|
130
|
+
| onEnded | `function` | `<optional>` | 回调函数,音乐结束会执行(注意 loop 时每次播放到音乐末尾不会执行),无参数 |
|
|
131
|
+
|
|
132
|
+
**Example:**
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
await trtc.startPlugin('AudioMixer', {
|
|
136
|
+
id: 'count',
|
|
137
|
+
url: '../assets/count.mp3',
|
|
138
|
+
loop: true,
|
|
139
|
+
volume: 0.2,
|
|
140
|
+
playbackRate: 1.5
|
|
141
|
+
})
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
使用回调:
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
await trtc.startPlugin('AudioMixer', {
|
|
148
|
+
id: 'wow',
|
|
149
|
+
url: '../assets/music/wow.mp3',
|
|
150
|
+
onDurationChange: (duration) => {
|
|
151
|
+
console.warn(`duration: ${duration}`);
|
|
152
|
+
},
|
|
153
|
+
onTimeUpdate: (currentTime, duration) => {
|
|
154
|
+
console.warn(`currentTime/duration: ${currentTime}/${duration}`);
|
|
155
|
+
},
|
|
156
|
+
onEnded: () => {
|
|
157
|
+
console.warn('ended');
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### trtc.updatePlugin('AudioMixer', options)
|
|
163
|
+
|
|
164
|
+
#### options
|
|
165
|
+
|
|
166
|
+
| Name | Type | Attributes | Description |
|
|
167
|
+
|-----------|-----------|--------------|---------------------------------------|
|
|
168
|
+
| id | `string` | | 调用 startPlugin 时定义的背景音乐文件的 ID |
|
|
169
|
+
| loop | `boolean` | `<optional>` | 是否循环播放,默认为false |
|
|
170
|
+
| volume | `number` | `<optional>` | 设置初始音量,默认为1 (0-1) |
|
|
171
|
+
| seekFrom | `number` | `<optional>` | 从第几秒开始 seek 播放,此功能需要背景音乐资源文件的请求支持[范围请求](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Range_requests) |
|
|
172
|
+
| operation | `number` | `<optional>` | 对背景音乐的操作: 'pause' | 'resume' | 'stop' |
|
|
173
|
+
| playbackRate | `number` | `<optional>` | 设置播放速率,默认为 1.0 |
|
|
174
|
+
| onDurationChange | `function` | `<optional>` | 回调函数,音乐加载完会执行,参数为 (duration: number) 标识音乐总时长 |
|
|
175
|
+
| onTimeUpdate | `function` | `<optional>` | 回调函数,音乐播放过程中会持续触发,参数为 (currentTime: number, duration: number) 标识音乐当前进度和总时长 |
|
|
176
|
+
| onEnded | `function` | `<optional>` | 回调函数,音乐结束会执行(注意 loop 时每次播放到音乐末尾不会执行),无参数 |
|
|
177
|
+
|
|
178
|
+
**Example:**
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
await trtc.updatePlugin('AudioMixer', {
|
|
182
|
+
id: 'count',
|
|
183
|
+
loop: true,
|
|
184
|
+
volume: 0.2,
|
|
185
|
+
operation: 'pause'
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### trtc.stopPlugin('AudioMixer', options)
|
|
190
|
+
|
|
191
|
+
关闭某个背景音乐。
|
|
192
|
+
|
|
193
|
+
#### options
|
|
194
|
+
|
|
195
|
+
| Name | Type | Attributes | Description |
|
|
196
|
+
|-----------|-----------|--------------|-------------------------------|
|
|
197
|
+
| id | `string` | | 调用 startPlugin 时定义的背景音乐文件的 ID |
|
|
198
|
+
|
|
199
|
+
**Example:**
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
await trtc.stopPlugin('AudioMixer', {
|
|
203
|
+
id: 'count'
|
|
204
|
+
})
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## 常见问题
|
|
208
|
+
|
|
209
|
+
**1. 出现跨域错误**
|
|
210
|
+
|
|
211
|
+
例如:Access to audio at XXX from origin XXX has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is
|
|
212
|
+
present on the requested resource.
|
|
213
|
+
|
|
214
|
+
解决:您需要配置线上音乐文件的 CORS 协议。
|
|
215
|
+
|
|
216
|
+
**2. 音频格式不对,浏览器无法播放**
|
|
217
|
+
|
|
218
|
+
例如:NotSupportedError: The operation is not supported.
|
|
219
|
+
|
|
220
|
+
解决:您需要使用浏览器支持的音频格式。
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
## 浏览器环境检测
|
|
2
|
+
|
|
3
|
+
在开始音视频通话之前,建议您先使用 {@link TRTC.isSupported TRTC.isSupported} 接口检测 SDK 是否支持当前网页。如果 SDK 不支持当前浏览器,建议用户使用最新版的 Chrome 浏览器、Edge 浏览器、Safari 浏览器、Firefox 浏览器。
|
|
4
|
+
|
|
5
|
+
```javascript
|
|
6
|
+
TRTC.isSupported().then(checkResult => {
|
|
7
|
+
// 不支持使用 SDK,引导用户使用最新版的 Chrome 浏览器。
|
|
8
|
+
if (!checkResult.result) {}
|
|
9
|
+
// 不支持发布视频
|
|
10
|
+
if (!checkResult.detail.isH264EncodeSupported) {}
|
|
11
|
+
// 不支持拉视频
|
|
12
|
+
if (!checkResult.detail.isH264DecodeSupported) {}
|
|
13
|
+
})
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
⚠️ `TRTC.isSupported` 返回的检测结果为 false 时,可能是以下原因:
|
|
17
|
+
|
|
18
|
+
1. 网页使用了 http 协议。浏览器不允许 http 协议的网站采集摄像头和麦克风,您需要使用 https 协议部署您的网页。
|
|
19
|
+
2. 当前浏览器不支持 WebRTC 相关能力,您需要引导用户使用推荐的浏览器 {@tutorial 05-info-browser}
|
|
20
|
+
3. Firefox 浏览器安装完成后需要动态加载 H264 编解码器,因此会出现短暂的检测结果为 false 的情况,请稍等再试或引导使用其他浏览器。
|
|
21
|
+
|
|
22
|
+
## 通话前设备检测
|
|
23
|
+
|
|
24
|
+
### 方案一:使用设备检测插件(包括默认 UI)
|
|
25
|
+
|
|
26
|
+
检测用户的媒体设备(摄像头、麦克风、扬声器)以及网络,建议在用户进房之前使用,支持移动端适配。
|
|
27
|
+
|
|
28
|
+
> - 该插件需要:TRTC Web SDK 版本 >= 5.8.0。
|
|
29
|
+
> - 该插件包括默认的 UI,若 UI 不符合您的产品设计需求,可以参考方案二自定义 UI 实现。
|
|
30
|
+
|
|
31
|
+
#### 实现流程
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
import { DeviceDetector } from 'trtc-sdk-v5/plugins/device-detector';
|
|
35
|
+
const trtc = TRTC.create({ plugins: [DeviceDetector] });
|
|
36
|
+
|
|
37
|
+
// 1. Test Media Device Only
|
|
38
|
+
const result = await trtc.startPlugin('DeviceDetector');
|
|
39
|
+
|
|
40
|
+
// 2. Test Media Device & Network Quality
|
|
41
|
+
const options = {
|
|
42
|
+
networkDetect: { sdkAppId, userId, userSig }
|
|
43
|
+
}
|
|
44
|
+
const resultWithNetwork = await trtc.startPlugin('DeviceDetector', options);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### API
|
|
48
|
+
|
|
49
|
+
##### trtc.startPlugin('DeviceDetector', options)
|
|
50
|
+
|
|
51
|
+
第一个参数为'DeviceDetector'字符串,用于开启设备检测插件。
|
|
52
|
+
|
|
53
|
+
##### options
|
|
54
|
+
|
|
55
|
+
| Name | Type | Attributes | Description |
|
|
56
|
+
| --------------- | ------ | ---------- | ------------------------------------------------------------ |
|
|
57
|
+
| language | 'auto' \| 'zh' \| 'en' | 选填 | 选填。设置 UI 的语言,支持中文和英文。默认为 'auto',表示根据当前浏览器语言自动判断。'zh' 表示使用中文, 'en' 表示使用英文。|
|
|
58
|
+
| allowSkip | boolean | 选填 | 选填。默认为 true,会显示跳过按钮。若为 false,则不显示跳过按钮,用户必须完成每一步检测才能进行下一步。|
|
|
59
|
+
| cameraDetect | object | 选填 | 选填。摄像头检测选项,详见下文 cameraDetect 选项|
|
|
60
|
+
| networkDetect | object | 选填 | 选填。网络检测选项,详见下文 networkDetect 选项|
|
|
61
|
+
|
|
62
|
+
###### options.cameraDetect(optional)
|
|
63
|
+
| Name | Type | Attributes | Description |
|
|
64
|
+
| --------------- | ------ | ---------- | ------------------------------------------------------------ |
|
|
65
|
+
| mirror | boolean | 选填 | 选填。为true时,在摄像头检测环节会开启画面镜像,并显示镜像画面的复选框 |
|
|
66
|
+
|
|
67
|
+
###### options.networkDetect(optional)
|
|
68
|
+
|
|
69
|
+
| Name | Type | Attributes | Description |
|
|
70
|
+
| --------------- | ------ | ---------- | ------------------------------------------------------------ |
|
|
71
|
+
| sdkAppId | string | 必填 | 从控制台获得,你的sdkAppId |
|
|
72
|
+
| userId | string | 必填 | 上行用户ID, 自行决定,与downlinkUserId不一致,与用于生成userSig的userId一致 |
|
|
73
|
+
| userSig | string | 必填 | userSig 签名,由sdkAppId,userId,sdkSecretKey作为参数生成,生产环境由向服务器请求生成,参考:[UserSig](https://trtc.io/document/35166) |
|
|
74
|
+
| downlinkUserId | string | 选填 | 下行用户ID, 自行决定,与userId不一致,与用于生成downlinkUserSig的userId一致。填写 downlinkUserId 和 downlinkUserSig将进行下行网络测试 |
|
|
75
|
+
| downlinkUserSig | string | 选填 | userSig 签名,由sdkAppId,downlinkUserId,sdkSecretKey作为参数生成,生产环境由向服务器请求生成,参考:[UserSig](https://trtc.io/document/35166) |
|
|
76
|
+
| roomId | number | 选填 | 选填,默认为8080,数字类型的房间号,取值要求为 [1, 4294967294] 的整数 |
|
|
77
|
+
|
|
78
|
+
##### startPlugin 返回结果
|
|
79
|
+
|
|
80
|
+
| Name | Type | Description |
|
|
81
|
+
| -------------- | -------- | ------------------------------------------------------------ |
|
|
82
|
+
| **camera** | `object` | { isSuccess: boolean, device: { deviceId: string, groupId: string, kind: "videoinput", label: string }} |
|
|
83
|
+
| **microphone** | `object` | { isSuccess: boolean, device: { deviceId: string, groupId: string, kind: "audioinput", label: string }} |
|
|
84
|
+
| **speaker** | `object` | { isSuccess: boolean, device: { deviceId: string, groupId: string, kind: "audiooutput", label: string }} |
|
|
85
|
+
| **network** | `object` | 网络检测结果(startPlugin传入networkDetect才检测返回)<br />{ isSuccess: boolean, result: { quality: number , rtt: number}} <br />quality为网络质量,默认为上行网络质量,传入下行userId和userSig时为上下行网络质量中较差值<br />**网络质量**<br />0:网络状况未知,表示当前 TRTC 实例还没有建立上行/下行连接 <br />1:网络状况极佳 <br />2:网络状况较好 <br />3:网络状况一般 <br />4:网络状况差 <br />5:网络状况极差 <br />6:网络连接已断开 注意:若下行网络质量为此值,则表示所有下行连接都断开了 |
|
|
86
|
+
|
|
87
|
+
#### 插件 Demo
|
|
88
|
+
|
|
89
|
+
<iframe allow="microphone; camera; display-capture;" height="700" style="width:100%" scrolling="no" title="Device Detector" src="https://codepen.io/TRTC/embed/eYwVVja?default-tab=" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
|
|
90
|
+
See the Pen <a href="https://codepen.io/TRTC/pen/eYwVVja">
|
|
91
|
+
Device Detector</a> by TRTC (<a href="https://codepen.io/TRTC">@TRTC</a>)
|
|
92
|
+
on <a href="https://codepen.io">CodePen</a>.
|
|
93
|
+
</iframe>
|
|
94
|
+
|
|
95
|
+
### 方案二:基于 SDK API 自行实现设备检测(自定义 UI)
|
|
96
|
+
|
|
97
|
+
若方案一的设备检测插件的默认 UI 不符合您的需求,你可以选择方案二来自定义 UI。
|
|
98
|
+
|
|
99
|
+
#### 1. 检查设备权限
|
|
100
|
+
|
|
101
|
+
从 v5.13.0+ 开始,SDK 提供了 `TRTC.getPermissions` 接口,用于检查、请求和监听设备权限。
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
const { camera, microphone } = await TRTC.getPermissions({
|
|
105
|
+
request: true, // 如果为 true,调用该接口可能会短暂打开摄像头来获取摄像头权限,以保证正常获取摄像头列表,随后 SDK 会自动释放采集。
|
|
106
|
+
types: ['camera', 'microphone'] // 请求获取的设备类型。
|
|
107
|
+
});
|
|
108
|
+
console.log(camera, microphone); // 'granted' | 'denied' | 'prompt' | null. null 表示不支持查询。
|
|
109
|
+
|
|
110
|
+
// 监听设备权限变化
|
|
111
|
+
trtc.on(TRTC.EVENT.PERMISSION_STATE_CHANGE, event => {
|
|
112
|
+
console.log(event.camera, event.microphone);
|
|
113
|
+
});
|
|
114
|
+
// 释放监听
|
|
115
|
+
trtc.off(TRTC.EVENT.PERMISSION_STATE_CHANGE);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### 2. 设备连接
|
|
119
|
+
|
|
120
|
+
设备连接的目的是检测用户使用的机器是否有摄像头、麦克风或扬声器,是否在联网状态。如果有摄像头,麦克风或扬声器设备,尝试获取音视频流并引导用户授予摄像头,麦克风的访问权限。
|
|
121
|
+
|
|
122
|
+
+ 判断设备是否有摄像头,麦克风或扬声器
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
import TRTC from 'trtc-sdk-v5';
|
|
126
|
+
|
|
127
|
+
const cameraList = await TRTC.getCameraList();
|
|
128
|
+
const micList = await TRTC.getMicrophoneList();
|
|
129
|
+
const hasCameraDevice = cameraList.some(camera => camera.deviceId !== '');
|
|
130
|
+
const hasMicrophoneDevice = micList.some(mic => mic.deviceId !== '');
|
|
131
|
+
// 移动端设备不支持获取扬声器设备,移动端检测扬声器可以不获取扬声器
|
|
132
|
+
const speakerList = await TRTC.getSpeakerList();
|
|
133
|
+
const hasSpeakerDevice = speakerList.some(speaker => speaker.deviceId !== '');
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### 3. 摄像头检测
|
|
137
|
+
|
|
138
|
+
检测原理:打开摄像头,并在页面中渲染摄像头画面。您可以在页面中提供 2 个按钮,让用户确认是否能看到摄像头画面。
|
|
139
|
+
|
|
140
|
+
+ 打开摄像头
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
trtc.startLocalVideo({ view: 'camera-video', publish: false });
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
+ 切换摄像头
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
trtc.updateLocalVideo({ option: { cameraId } });
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
+ 检测完成后关闭摄像头
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
trtc.stopLocalVideo();
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### 4. 麦克风检测
|
|
159
|
+
|
|
160
|
+
检测原理:打开麦克风,并获取麦克风音量。监听麦克风音量事件,并将实时音量渲染到页面中,引导用户说话,确认是否能看到音量条变化。
|
|
161
|
+
|
|
162
|
+
+ 打开麦克风
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
trtc.on(TRTC.EVENT.AUDIO_VOLUME, event => {
|
|
166
|
+
event.result.forEach(({ userId, volume }) => {
|
|
167
|
+
const isMe = userId === ''; // 当 userId 为空串时,代表本地麦克风音量。
|
|
168
|
+
if (isMe) {
|
|
169
|
+
console.log(`my volume: ${volume}`);
|
|
170
|
+
// 将麦克风音量渲染到页面中
|
|
171
|
+
}
|
|
172
|
+
})
|
|
173
|
+
});
|
|
174
|
+
// 开启音量回调,并设置每 200ms 触发一次事件
|
|
175
|
+
trtc.enableAudioVolumeEvaluation(200);
|
|
176
|
+
trtc.startLocalAudio({ publish: false });
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
+ 切换麦克风
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
trtc.updateLocalAudio({ option: { microphoneId }});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
+ 检测完成后释放麦克风占用
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
trtc.stopLocalAudio();
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### 5. 扬声器检测
|
|
192
|
+
|
|
193
|
+
检测原理:通过 audio 标签播放一个 mp3 媒体文件
|
|
194
|
+
|
|
195
|
+
+ 创建 audio 标签,提醒用户调高播放音量,播放 mp3 确认扬声器设备是否正常。
|
|
196
|
+
|
|
197
|
+
```html
|
|
198
|
+
<audio id="audio-player" src="xxxxx" controls></audio>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
+ 检测结束后停止播放
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
const audioPlayer = document.getElementById('audio-player');
|
|
205
|
+
if (!audioPlayer.paused) {
|
|
206
|
+
audioPlayer.pause();
|
|
207
|
+
}
|
|
208
|
+
audioPlayer.currentTime = 0;
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### 6. 网络检测
|
|
212
|
+
|
|
213
|
+
参考:[通话前的网络质量检测](./tutorial-24-advanced-network-quality.html)
|
|
214
|
+
|
|
215
|
+
## TRTC 能力检测页面
|
|
216
|
+
|
|
217
|
+
您可以在当前使用 TRTC SDK 的地方,使用 [TRTC 检测页面](https://web.sdk.qcloud.com/trtc/webrtc/demo/detect/index.html) ,可用于探测当前环境,还可以点击生成报告按钮,得到当前环境的报告,用于环境检测,或者问题排查。
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
在进房之前或在通话过程中,检测用户的网络质量,可以判断用户当下的网络质量情况。若用户网络质量太差,应建议用户检查网络或尝试更换网络,以保证正常通话质量。
|
|
2
|
+
|
|
3
|
+
本文主要介绍如何基于 [NETWORK_QUALITY](./module-EVENT.html#.NETWORK_QUALITY) 事件实现通话过程及通话前网络质量检测。
|
|
4
|
+
|
|
5
|
+
## 通话过程中的网络质量检测
|
|
6
|
+
|
|
7
|
+
参考: {@link module:EVENT.NETWORK_QUALITY NETWORK_QUALITY}
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
const trtc = TRTC.create();
|
|
11
|
+
trtc.on(TRTC.EVENT.NETWORK_QUALITY, event => {
|
|
12
|
+
console.log(`network-quality, uplinkNetworkQuality:${event.uplinkNetworkQuality}, downlinkNetworkQuality: ${event.downlinkNetworkQuality}`)
|
|
13
|
+
console.log(`uplink rtt:${event.uplinkRTT} loss:${event.uplinkLoss}`)
|
|
14
|
+
console.log(`downlink rtt:${event.downlinkRTT} loss:${event.downlinkLoss}`)
|
|
15
|
+
})
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 通话前的网络质量检测
|
|
19
|
+
|
|
20
|
+
通话前的网络质量检测需要借助 {@link module:EVENT.NETWORK_QUALITY NETWORK_QUALITY} 事件实现。
|
|
21
|
+
|
|
22
|
+
### 实现流程
|
|
23
|
+
|
|
24
|
+
1. 调用 [TRTC.create](./TRTC.html#.createTRTC) 创建两个 trtc 对象,分别称为 uplinkTRTC 和 downlinkTRTC。
|
|
25
|
+
2. 这两个 TRTC 都进入同一个房间。
|
|
26
|
+
3. 使用 uplinkTRTC 进行推流,监听 [NETWORK_QUALITY](./module-EVENT.html#.NETWORK_QUALITY) 事件来检测上行网络质量。
|
|
27
|
+
4. 使用 downlinkTRTC 进行拉流,监听 [NETWORK_QUALITY](./module-EVENT.html#.NETWORK_QUALITY) 事件来检测下行网络质量。
|
|
28
|
+
5. 整个过程可持续 15s 左右,最后取平均网络质量,从而大致判断出上下行网络情况。
|
|
29
|
+
|
|
30
|
+
> !
|
|
31
|
+
> - 检测过程将产生少量的[基础服务费用](https://cloud.tencent.com/document/product/647/17157#.E5.9F.BA.E7.A1.80.E6.9C.8D.E5.8A.A1)。如果未指定推流分辨率,则默认以 640*480 的分辨率推流。
|
|
32
|
+
|
|
33
|
+
### API 调用时序
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
### 代码示例
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
let uplinkTRTC = null; // 用于检测上行网络质量
|
|
41
|
+
let downlinkTRTC = null; // 用于检测下行网络质量
|
|
42
|
+
let localStream = null; // 用于测试的流
|
|
43
|
+
let testResult = {
|
|
44
|
+
// 记录上行网络质量数据
|
|
45
|
+
uplinkNetworkQualities: [],
|
|
46
|
+
// 记录下行网络质量数据
|
|
47
|
+
downlinkNetworkQualities: [],
|
|
48
|
+
average: {
|
|
49
|
+
uplinkNetworkQuality: 0,
|
|
50
|
+
downlinkNetworkQuality: 0
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 1. 检测上行网络质量
|
|
55
|
+
async function testUplinkNetworkQuality() {
|
|
56
|
+
uplinkTRTC = TRTC.create();
|
|
57
|
+
|
|
58
|
+
uplinkTRTC.enterRoom({
|
|
59
|
+
roomId: 8080,
|
|
60
|
+
sdkAppId: 0, // 填写 sdkAppId
|
|
61
|
+
userId: 'user_uplink_test',
|
|
62
|
+
userSig: '', // uplink_test 的 userSig
|
|
63
|
+
scene: 'rtc'
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
uplinkTRTC.on(TRTC.EVENT.NETWORK_QUALITY, event => {
|
|
67
|
+
const { uplinkNetworkQuality } = event;
|
|
68
|
+
testResult.uplinkNetworkQualities.push(uplinkNetworkQuality);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
uplinkTRTC.startLocalVideo();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 2. 检测下行网络质量
|
|
75
|
+
async function testDownlinkNetworkQuality() {
|
|
76
|
+
downlinkTRTC = TRTC.create();
|
|
77
|
+
downlinkTRTC.enterRoom({
|
|
78
|
+
roomId: 8080,
|
|
79
|
+
sdkAppId: 0, // 填写 sdkAppId
|
|
80
|
+
userId: 'user_downlink_test',
|
|
81
|
+
userSig: '', // userSig
|
|
82
|
+
scene: 'rtc',
|
|
83
|
+
autoReceiveVideo: true
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
downlinkTRTC.on(TRTC.EVENT.NETWORK_QUALITY, event => {
|
|
87
|
+
const { downlinkNetworkQuality } = event;
|
|
88
|
+
testResult.downlinkNetworkQualities.push(downlinkNetworkQuality);
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 3. 开始检测
|
|
93
|
+
testUplinkNetworkQuality();
|
|
94
|
+
testDownlinkNetworkQuality();
|
|
95
|
+
|
|
96
|
+
// 4. 15s 后停止检测,计算平均网络质量
|
|
97
|
+
setTimeout(() => {
|
|
98
|
+
// 计算上行平均网络质量
|
|
99
|
+
const validUplinkNetworkQualitiesList = testResult.uplinkNetworkQualities.filter(value => value >= 1 && value <= 5);
|
|
100
|
+
if (validUplinkNetworkQualitiesList.length > 0) {
|
|
101
|
+
testResult.average.uplinkNetworkQuality = Math.ceil(
|
|
102
|
+
validUplinkNetworkQualitiesList.reduce((value, current) => value + current, 0) / validUplinkNetworkQualitiesList.length
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const validDownlinkNetworkQualitiesList = testResult.uplinkNetworkQualities.filter(value => value >= 1 && value <= 5);
|
|
107
|
+
if (validDownlinkNetworkQualitiesList.length > 0) {
|
|
108
|
+
// 计算下行平均网络质量
|
|
109
|
+
testResult.average.downlinkNetworkQuality = Math.ceil(
|
|
110
|
+
validDownlinkNetworkQualitiesList.reduce((value, current) => value + current, 0) / validDownlinkNetworkQualitiesList.length
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 检测结束,清理相关状态。
|
|
115
|
+
uplinkTRTC.exitRoom();
|
|
116
|
+
downlinkTRTC.exitRoom();
|
|
117
|
+
}, 15 * 1000);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 结果分析
|
|
121
|
+
|
|
122
|
+
经过上述步骤,可以拿到上行平均网络质量、下行平均网络质量。网络质量的枚举值如下所示:
|
|
123
|
+
|
|
124
|
+
| 数值 | 含义 |
|
|
125
|
+
| :--- | :----------------------------------------------------------- |
|
|
126
|
+
| 0 | 网络状况未知,表示当前 TRTC 实例还没有建立上行/下行连接 |
|
|
127
|
+
| 1 | 网络状况极佳 |
|
|
128
|
+
| 2 | 网络状况较好 |
|
|
129
|
+
| 3 | 网络状况一般 |
|
|
130
|
+
| 4 | 网络状况差 |
|
|
131
|
+
| 5 | 网络状况极差 |
|
|
132
|
+
| 6 | 网络连接已断开 注意:若下行网络质量为此值,则表示所有下行连接都断开了 |
|
|
133
|
+
|
|
134
|
+
> 建议:当网络质量大于3时,应引导用户检查网络并尝试更换网络环境,否则难以保证正常的音视频通话。
|
|
135
|
+
> 也可通过下述策略来降低带宽消耗:
|
|
136
|
+
> - 若上行网络质量大于3,则可通过 [TRTC.updateLocalVideo()](./TRTC.html#updateLocalVideo) 接口降低码率 或 [TRTC.stopLocalVideo()](./TRTC.html#stopLocalVideo) 方式关闭视频,以降低上行带宽消耗。
|
|
137
|
+
> - 若下行网络质量大于3,则可通过订阅小流(参考:[开启大小流传输](./tutorial-27-advanced-small-stream.html))或者只订阅音频的方式,以降低下行带宽消耗。
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
## 功能描述
|
|
2
|
+
|
|
3
|
+
本文主要介绍如何检测用户的设备插入、拔出、启动的行为。以及如何处理设备采集异常。
|
|
4
|
+
|
|
5
|
+
> **关于 SDK 自动恢复采集**<br>
|
|
6
|
+
> SDK 会检测摄像头、麦克风的插拔行为,并在恰当时机,自动恢复采集。具体逻辑如下:
|
|
7
|
+
> 1. 若当前正在推流的摄像头/麦克风被拔出,SDK 会尝试使用剩余可用的媒体设备,恢复采集。
|
|
8
|
+
> 2. 若摄像头/麦克风被拔出后,没有可用的媒体设备。SDK 会检测设备插入行为,若插入了新的可用的媒体设备,SDK 会尝试使用新插入的媒体设备,恢复采集并推流。
|
|
9
|
+
> 3. 若恢复失败,则会抛出错误 [TRTC.ERROR_CODE.DEVICE_ERROR](./module-ERROR_CODE.html#.DEVICE_ERROR),extraCode 为 5308,5309。
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## 实现流程
|
|
13
|
+
|
|
14
|
+
### 检测设备插入、拔出、启动
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
trtc.on(TRTC.EVENT.DEVICE_CHANGED, (event) => {
|
|
18
|
+
// 设备插入
|
|
19
|
+
if (event.action === 'add') {
|
|
20
|
+
// 摄像头插入
|
|
21
|
+
if (event.type === 'camera') {}
|
|
22
|
+
} else if (event.action === 'remove') {
|
|
23
|
+
// 设备拔出
|
|
24
|
+
} else if (event.action === 'active') {
|
|
25
|
+
// 设备启动
|
|
26
|
+
}
|
|
27
|
+
console.log(`${event.type}(${event.device.label}) ${event.action}`);
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 判断是否当前正在使用的设备被拔出
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
trtc.on(TRTC.EVENT.DEVICE_CHANGED, (event) => {
|
|
35
|
+
if (event.action === 'remove') {
|
|
36
|
+
if (event.type === 'camera') {
|
|
37
|
+
const currentCameraId = trtc.getVideoTrack()?.getSettings()?.deviceId;
|
|
38
|
+
if (event.device.deviceId === currentCameraId) {
|
|
39
|
+
// 当前正在使用的摄像头被拔出。
|
|
40
|
+
}
|
|
41
|
+
} else if (event.type === 'microphone') {
|
|
42
|
+
const currentMicId = trtc.getAudioTrack()?.getSettings()?.deviceId;
|
|
43
|
+
if (event.device.deviceId === currentMicId) {
|
|
44
|
+
// 当前正在使用的麦克风被拔出。
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 在用户插入新设备时,自动切换到使用新设备。
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
trtc.on(TRTC.EVENT.DEVICE_CHANGED, (event) => {
|
|
55
|
+
if (event.action === 'add') {
|
|
56
|
+
if (event.type === 'camera') {
|
|
57
|
+
// 插入摄像头后,自动切换到新的摄像头
|
|
58
|
+
trtc.updateLocalVideo({ option: { cameraId: event.device.deviceId }});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 处理设备采集异常
|
|
65
|
+
|
|
66
|
+
监听设备采集异常事件
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
trtc.on(TRTC.EVENT.VIDEO_PLAY_STATE_CHANGED, event => {
|
|
70
|
+
// 本地摄像头采集异常,此时 SDK 会尝试自动恢复采集,您可以引导用户检查摄像头是否正常。
|
|
71
|
+
if (event.userId === '' && event.streamType === TRTC.TYPE.STREAM_TYPE_MAIN && (event.reason === 'mute' || event.reason === 'ended')) {}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
trtc.on(TRTC.EVENT.AUDIO_PLAY_STATE_CHANGED, event => {
|
|
75
|
+
// 本地麦克风采集异常,此时 SDK 会尝试自动恢复采集,您可以引导用户检查麦克风是否正常。
|
|
76
|
+
if (event.userId === '' && (event.reason === 'mute' || event.reason === 'ended')) {}
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
监听 SDK 自动恢复采集失败事件
|
|
81
|
+
```js
|
|
82
|
+
trtc.on(TRTC.EVENT.ERROR, error => {
|
|
83
|
+
if (error.code === TRTC.ERROR_CODE.DEVICE_ERROR) {
|
|
84
|
+
// 摄像头恢复采集失败
|
|
85
|
+
if (error.extraCode === 5308) {
|
|
86
|
+
// 引导用户检查设备后,调用 updateLocalVideo 传入 cameraId 重新采集。
|
|
87
|
+
trtc.updateLocalVideo({ option: { cameraId: '' }});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 麦克风恢复采集失败
|
|
91
|
+
if (error.extraCode === 5309) {
|
|
92
|
+
// 引导用户检查设备后,调用 updateLocalAudio 传入 microphoneId 重新采集。
|
|
93
|
+
trtc.updateLocalAudio({ option: { microphoneId: '' }});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
```
|