@tencent-rtc/mcp 1.6.8 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +53 -39
- package/knowledge/build-index.js +30 -6
- package/knowledge/chunker.js +82 -14
- package/knowledge/chunking-policy.js +100 -0
- package/knowledge/content-loader.js +3 -3
- package/knowledge/frontmatter-meta.js +167 -0
- package/knowledge/path-meta.js +28 -6
- package/knowledge/search/exact-lookup.js +9 -227
- package/knowledge/search/filter-pool.js +12 -29
- package/knowledge/search/framework-fallback.js +22 -0
- package/knowledge/search/intent-router.js +13 -0
- package/knowledge/search/query-normalizer.js +56 -3
- package/knowledge/search/search-core.js +391 -0
- package/knowledge/search/search-knowledge.js +292 -363
- package/knowledge/search/search-message.js +87 -0
- package/knowledge/search/search-pass.js +428 -0
- package/knowledge/search/search-types.js +1 -0
- package/knowledge/search/url-row-scorer.js +258 -0
- package/package.json +1 -1
- package/resource/_schema/feature-aliases.yaml +1 -1
- package/resource/index/manifest.json +1 -1
- package/resource/knowledge/callkit/best-practice/callkit-miniprogram/uniapp-shrink.md +60 -0
- package/resource/knowledge/callkit/best-practice/common/call-autoplay-blocked.md +77 -0
- package/resource/knowledge/callkit/best-practice/common/call-message-in-chat.md +78 -0
- package/resource/knowledge/callkit/best-practice/common/call-vs-calls.md +110 -0
- package/resource/knowledge/callkit/best-practice/common/callengine-call-flow.md +123 -0
- package/resource/knowledge/callkit/best-practice/common/callengine-log-level.md +67 -0
- package/resource/knowledge/callkit/best-practice/common/callkit-get-engine-instance.md +81 -0
- package/resource/knowledge/callkit/best-practice/common/callkit-get-roomid.md +78 -0
- package/resource/knowledge/callkit/best-practice/common/callkit-limitations.md +37 -0
- package/resource/knowledge/callkit/best-practice/common/callkit-user-register-and-kicked.md +98 -0
- package/resource/knowledge/chat/best-practice/common/avchatroom-message-loss-diagnosis.md +65 -0
- package/resource/knowledge/chat/best-practice/common/group-conversation-cleanup-on-system-notice.md +62 -0
- package/resource/knowledge/chat/best-practice/common/image-message-url-lifecycle.md +59 -0
- package/resource/knowledge/chat/best-practice/common/login-repeat-2025-diagnosis.md +61 -0
- package/resource/knowledge/chat/best-practice/common/message-read-report-and-receipt.md +64 -0
- package/resource/knowledge/chat/best-practice/common/message-receive-event.md +65 -0
- package/resource/knowledge/chat/best-practice/common/message-risk-error-and-render.md +65 -0
- package/resource/knowledge/chat/best-practice/common/message-unread-count.md +71 -0
- package/resource/knowledge/chat/best-practice/miniprogram/audio-message-send.md +113 -0
- package/resource/knowledge/chat/best-practice/miniprogram/login-timeout-2801-diagnosis.md +63 -0
- package/resource/knowledge/chat/best-practice/miniprogram/media-upload-fail-diagnosis.md +64 -0
- package/resource/knowledge/chat/best-practice/web/audio-message-send.md +118 -0
- package/resource/knowledge/chat/urls/sdk/web.md +1 -1
- package/resource/knowledge/livekit/best-practice/android/voice-room-anchor-start.md +120 -0
- package/resource/knowledge/livekit/best-practice/common/admin-take-seat.md +73 -0
- package/resource/knowledge/livekit/best-practice/common/audience-leave-live.md +81 -0
- package/resource/knowledge/livekit/best-practice/common/voice-room-no-audio-troubleshoot.md +100 -0
- package/resource/knowledge/livekit/best-practice/common/voice-room-seat-list-change.md +65 -0
- package/resource/knowledge/livekit/best-practice/flutter/voice-room-anchor-start.md +122 -0
- package/resource/knowledge/livekit/best-practice/ios/voice-room-anchor-start.md +126 -0
- package/resource/knowledge/roomkit/best-practice/common/room-ghost-member.md +70 -0
- package/resource/knowledge/roomkit/best-practice/common/room-limit-and-multi.md +83 -0
- package/resource/knowledge/roomkit/best-practice/common/room-screen-share-preview.md +83 -0
- package/resource/knowledge/roomkit/best-practice/common/room-status-after-all-leave.md +69 -0
- package/resource/knowledge/roomkit/best-practice/vue/room-uikit-vs-atomicx.md +111 -0
- package/resource/knowledge/rtcengine/web/plugin/30-advanced-cross-room-link.md +2 -0
- package/resource/knowledge/rtcengine/web/plugin/39-advanced-video-decoder.md +2 -0
- package/server.js +27 -22
- package/tools/common/finalize_answer.js +9 -1
- package/tools/common/search_trtc_knowledge.js +1 -1
- package/tools/definitions/finalize_answer_def.js +2 -2
- package/tools/definitions/integration-boundary.js +2 -1
- package/tools/definitions/search_trtc_knowledge_def.js +1 -1
- package/utils/report-cls-client.js +1 -1
- package/utils/report-es-client.js +1 -1
- package/cursor-setting.png +0 -0
- package/mcp-server-prompt.png +0 -0
- package/resource/knowledge/callkit/best-practice/web/callengine-invitation.md +0 -80
- package/resource/knowledge/callkit/best-practice/web/callengine-log-control.md +0 -24
- package/resource/knowledge/callkit/best-practice/web/callkit-call-vs-calls.md +0 -116
- package/resource/knowledge/callkit/preset/react/uikit-api-reference.md +0 -444
- package/resource/knowledge/callkit/preset/vue/uikit-api-reference.md +0 -464
- package/resource/knowledge/chat/best-practice/web/image-message-url-handling.md +0 -16
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Voice Room Admin Seat-Taking and Seat Locking(语聊房 / 管理员 / 上麦 / takeSeat / lockSeat)"
|
|
3
|
+
product: live
|
|
4
|
+
frameworks: [android, ios, flutter]
|
|
5
|
+
scope: platform_common
|
|
6
|
+
tags: [voice room, admin, take seat, takeSeat, lockSeat, unlockSeat, seatMode, FREE, seat, host seat, owner approval, VoiceRoom]
|
|
7
|
+
version_range: ">=2.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Voice Room Admin Seat-Taking and Seat Locking
|
|
11
|
+
|
|
12
|
+
## 1. Key Takeaways
|
|
13
|
+
|
|
14
|
+
- An admin takes a seat by calling `takeSeat` with the seat index. There is no need to call `applyForSeat` — admins are **not restricted by `seatMode=APPLY`** and do **not need** owner approval.
|
|
15
|
+
- Admins are **not restricted by `lockSeat`** — they can directly `takeSeat` to any seat (including seat 0, the host seat).
|
|
16
|
+
- Regular users can only call `takeSeat` when `seatMode` is `FREE`, and they **are restricted by `lockSeat`**.
|
|
17
|
+
- The seat management API in `LiveSeatStore` is consistent across all three platforms (Android/iOS/Flutter).
|
|
18
|
+
|
|
19
|
+
## 2. Field / API Reference
|
|
20
|
+
|
|
21
|
+
| Field / Capability | Purpose | Notes |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `takeSeat` | Take a seat | Pass the seat index; admins are not restricted by `seatMode`/`lockSeat`; regular users require `seatMode=FREE` and the seat must be unlocked |
|
|
24
|
+
| `lockSeat` | Lock a seat | After locking, regular users cannot `takeSeat`; admins are unaffected |
|
|
25
|
+
| `unlockSeat` | Unlock a seat | After unlocking, regular users can `takeSeat` again |
|
|
26
|
+
| `seatMode` | Seat-taking mode | Regular users can only `takeSeat` in `FREE` mode |
|
|
27
|
+
| `LiveSeatStore` | Seat management | Provides `takeSeat`/`leaveSeat`/`lockSeat`/`unlockSeat` operations |
|
|
28
|
+
| Owner | Room owner | Can lock/unlock seats |
|
|
29
|
+
|
|
30
|
+
## 3. Mechanism & Sequence
|
|
31
|
+
|
|
32
|
+
### Admin Taking a Seat
|
|
33
|
+
|
|
34
|
+
Admin calls `takeSeat(index)` to take a seat directly (passing the target seat index) -> not restricted by `seatMode` -> no owner approval needed -> not restricted by `lockSeat` -> seat taken successfully.
|
|
35
|
+
|
|
36
|
+
## 4. Standard Usage
|
|
37
|
+
|
|
38
|
+
1. **Admin takes a seat**: Call `takeSeat(index)` where `index` is the target seat number (e.g., seat 0 for the host seat). Not restricted by `seatMode`/`lockSeat`.
|
|
39
|
+
2. **Regular user takes a seat**: Confirm `seatMode=FREE` and the target seat is unlocked, then call `takeSeat(index)`.
|
|
40
|
+
3. **Lock a seat**: Admin/owner calls `lockSeat(index)`. After locking, regular users cannot `takeSeat`, but admins are unaffected.
|
|
41
|
+
4. **Unlock then take seat**: First call `unlockSeat(index)` to unlock, then the regular user can `takeSeat(index)`.
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
// API is consistent across all three platforms (Android Kotlin / iOS Swift / Flutter Dart)
|
|
45
|
+
// 1. 管理员直接上麦(不受 seatMode / lockSeat 限制,无需房主同意)
|
|
46
|
+
liveSeatStore.takeSeat(0); // 上麦到 0 号主持麦位
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 5. Expected Results
|
|
50
|
+
|
|
51
|
+
- Admin `takeSeat(index)` succeeds immediately, not restricted by `seatMode`, no owner approval needed.
|
|
52
|
+
- After `lockSeat`, an admin can still `takeSeat` on the same seat (admins are not restricted by seat locking).
|
|
53
|
+
- Regular users can only `takeSeat` successfully when `seatMode=FREE`; if the seat is locked, it fails — `unlockSeat` must be called first.
|
|
54
|
+
|
|
55
|
+
## 6. Common Pitfalls
|
|
56
|
+
|
|
57
|
+
- Pitfall 1: Admin calls `applyForSeat` to take a seat (admins should call `takeSeat` directly — no application needed).
|
|
58
|
+
- Pitfall 2: Assuming admin `takeSeat` requires owner approval (admins are not subject to this restriction).
|
|
59
|
+
- Pitfall 3: Assuming `lockSeat` prevents admins from calling `takeSeat` on the same seat (admins are not restricted by seat locking — only regular users are).
|
|
60
|
+
|
|
61
|
+
## 7. Problem Definition (retrieval hint)
|
|
62
|
+
|
|
63
|
+
How a voice room admin directly takes a specified seat (including seat 0, the host seat), whether admins are restricted by `seatMode`/`lockSeat`, and the `seatMode` and locking conditions for regular users to take a seat.
|
|
64
|
+
|
|
65
|
+
## 8. Alternative Queries (retrieval recall)
|
|
66
|
+
|
|
67
|
+
- How does a voice room admin take seat 0?
|
|
68
|
+
- Does admin `takeSeat` require owner approval?
|
|
69
|
+
- Is admin seat-taking restricted by `seatMode`?
|
|
70
|
+
- Can an admin `takeSeat` after `lockSeat`?
|
|
71
|
+
- When can a regular user `takeSeat`?
|
|
72
|
+
- Can a regular user take a seat when `seatMode=FREE`?
|
|
73
|
+
- How to unlock a locked seat and take it?
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Voice Room Audience Leaving and Seat State(语聊房 / 观众 / 上麦 / 下麦 / leaveLive)"
|
|
3
|
+
product: live
|
|
4
|
+
frameworks: [android, ios, flutter]
|
|
5
|
+
scope: platform_common
|
|
6
|
+
tags: [voice room, audience, take seat, leave seat, leaveLive, leaveSeat, exit, seat, re-take seat, VoiceRoom]
|
|
7
|
+
version_range: ">=2.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Voice Room Audience Leaving and Seat State
|
|
11
|
+
|
|
12
|
+
## 1. Key Takeaways
|
|
13
|
+
|
|
14
|
+
- When a seated audience member calls `leaveLive` to exit the voice room, they are automatically removed from the seat.
|
|
15
|
+
- After exiting and re-entering the room, the user is **not seated** and must take a seat again.
|
|
16
|
+
- The method for taking a seat depends on `seatMode`:
|
|
17
|
+
- `seatMode = FREE`: Call `takeSeat` directly.
|
|
18
|
+
- `seatMode = APPLY`: Call `applyForSeat` to submit a seat request; the owner/admin must approve before the user is seated.
|
|
19
|
+
- `leaveLive` does **not require** calling `leaveSeat` first — exiting automatically removes the user from the seat.
|
|
20
|
+
- Behavior is consistent across all three platforms (Android/iOS/Flutter).
|
|
21
|
+
|
|
22
|
+
## 2. Field / API Reference
|
|
23
|
+
|
|
24
|
+
| Field / Capability | Purpose | Notes |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| `leaveLive` | Exit the voice room | Exits the room and automatically leaves the seat |
|
|
27
|
+
| `leaveSeat` | Manually leave a seat | Used for explicit seat departure; not required before `leaveLive` since exiting auto-leaves the seat |
|
|
28
|
+
| `takeSeat` | Take a seat freely (`seatMode = FREE`) | Call directly after re-entering the room in free mode |
|
|
29
|
+
| `applyForSeat` | Apply to take a seat (`seatMode = APPLY`) | Submit a request; owner/admin approval is required |
|
|
30
|
+
| `seatMode` | Seat mode | `FREE`: free seat-taking; `APPLY`: requires approval |
|
|
31
|
+
| Seat state | Whether the user is seated | Cleared after `leaveLive`; user must re-take a seat after re-entering |
|
|
32
|
+
|
|
33
|
+
## 3. Mechanism & Sequence
|
|
34
|
+
|
|
35
|
+
Seated audience calls `leaveLive` -> automatically leaves seat (no need to call `leaveSeat` first) -> exits room -> re-enters room -> seat state is empty, user is not seated -> choose seat-taking method based on `seatMode`:
|
|
36
|
+
|
|
37
|
+
- `seatMode = FREE`: Call `takeSeat(seatIndex)` to take a seat directly.
|
|
38
|
+
- `seatMode = APPLY`: Call `applyForSeat(seatIndex)` to submit a request and wait for owner/admin approval.
|
|
39
|
+
|
|
40
|
+
## 4. Standard Usage
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
// API is consistent across all three platforms (Android Kotlin / iOS Swift / Flutter Dart)
|
|
44
|
+
// 1. 直接退出语聊房(会自动下麦,无需先 leaveSeat)
|
|
45
|
+
liveListStore.leaveLive();
|
|
46
|
+
|
|
47
|
+
// 2. 重新进房后,根据 seatMode 选择上麦方式
|
|
48
|
+
// seatMode = FREE 时:直接上麦
|
|
49
|
+
liveSeatStore.takeSeat(seatIndex);
|
|
50
|
+
|
|
51
|
+
// seatMode = APPLY 时:申请上麦(需房主/管理员同意)
|
|
52
|
+
liveSeatStore.applyForSeat(seatIndex);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 5. Expected Results
|
|
56
|
+
|
|
57
|
+
- After `leaveLive`, the user is automatically removed from the seat.
|
|
58
|
+
- After re-entering the room, `LiveSeatStore.seatList` does not contain the user.
|
|
59
|
+
- `seatMode = FREE`: Calling `takeSeat` succeeds and the user is seated again.
|
|
60
|
+
- `seatMode = APPLY`: After calling `applyForSeat`, the user waits for approval; once approved, the user is seated again.
|
|
61
|
+
|
|
62
|
+
## 6. Common Pitfalls
|
|
63
|
+
|
|
64
|
+
- Pitfall 1: Calling `leaveSeat` before exiting (not necessary — `leaveLive` automatically leaves the seat).
|
|
65
|
+
- Pitfall 2: Assuming the user is still seated after re-entering the room (they must take a seat again).
|
|
66
|
+
- Pitfall 3: Worrying that `leaveLive` does not leave the seat, causing a stale seat entry (it auto-leaves — no stale entries).
|
|
67
|
+
- Pitfall 4: Calling `takeSeat` directly when `seatMode = APPLY` (use `applyForSeat` instead — otherwise it will fail or have no effect).
|
|
68
|
+
|
|
69
|
+
## 7. Problem Definition (retrieval hint)
|
|
70
|
+
|
|
71
|
+
Whether a seated audience member is automatically removed from the seat after calling `leaveLive`, whether the user is still seated after re-entering, whether `leaveLive` requires calling `leaveSeat` first, and how to re-take a seat under different `seatMode` values (FREE/APPLY) using `takeSeat` vs `applyForSeat`.
|
|
72
|
+
|
|
73
|
+
## 8. Alternative Queries (retrieval recall)
|
|
74
|
+
|
|
75
|
+
- Does a voice room audience member leave the seat after exiting?
|
|
76
|
+
- Do I need to take a seat again after re-entering?
|
|
77
|
+
- Do I need to call `leaveSeat` before `leaveLive`?
|
|
78
|
+
- Is the seat cleared when a voice room audience member exits?
|
|
79
|
+
- How to re-take a seat after entering the room?
|
|
80
|
+
- How to take a seat when `seatMode = APPLY`?
|
|
81
|
+
- When to use `takeSeat` vs `applyForSeat`?
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Voice Room Audience Cannot Hear Anchor — Troubleshooting Guide(语聊房 / 观众听不到声音 / 没声音)"
|
|
3
|
+
product: live
|
|
4
|
+
frameworks: [android, ios, flutter]
|
|
5
|
+
scope: platform_common
|
|
6
|
+
tags: [voice room, no audio, no sound, troubleshoot, LiveSeatStore, DeviceStore, takeSeat, openLocalMicrophone, unmuteMicrophone, LoginStore, joinLive, seatList, microphoneStatus, LiveSeatState, DeviceState]
|
|
7
|
+
version_range: ">=2.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Voice Room Audience Cannot Hear Anchor — Troubleshooting Guide
|
|
11
|
+
|
|
12
|
+
## 1. Key Takeaways
|
|
13
|
+
|
|
14
|
+
- When the audience cannot hear the anchor, troubleshoot in order from anchor side to audience side: room → seat → microphone → mute → login → room entry — checking state at each layer.
|
|
15
|
+
- Anchor side: confirm the anchor is seated (`seatList`), microphone is open (`DeviceStore.microphoneStatus`), and not muted (`userInfo.microphoneStatus`).
|
|
16
|
+
- Audience side: confirm login status (`loginStatus == LOGIN`), room entry (`currentLive`), and device volume is normal.
|
|
17
|
+
- API and state structures are consistent across all three platforms (Android/iOS/Flutter); the troubleshooting flow is universal.
|
|
18
|
+
|
|
19
|
+
## 2. Field / API Reference
|
|
20
|
+
|
|
21
|
+
| Field / Capability | Purpose | Notes |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `LiveSeatStore` | Seat management | Provides `seatList`; check whether anchor info is present to determine if the anchor is seated |
|
|
24
|
+
| `LiveSeatStore.seatList` | Seat list | Check for anchor info; the anchor item's `userInfo.microphoneStatus` indicates mute state |
|
|
25
|
+
| `takeSeat` | Take a seat | Called when the anchor is not seated |
|
|
26
|
+
| `DeviceStore` | Device management | Provides `DeviceState`; check `microphoneStatus` to determine if the microphone is open |
|
|
27
|
+
| `DeviceState.microphoneStatus` | Microphone on/off state | Determines whether the anchor's microphone is open |
|
|
28
|
+
| `openLocalMicrophone` | Open microphone | Called when the microphone is closed |
|
|
29
|
+
| `unmuteMicrophone` | Resume audio publishing | Called when the anchor is muted |
|
|
30
|
+
| `LoginStore` | Login management | Provides `loginState.loginStatus`; `LOGIN` means logged in |
|
|
31
|
+
| `LiveListStore` | Live room management | Provides `LiveListState.currentLive`; determines if room entry succeeded |
|
|
32
|
+
| `joinLive` | Enter room | Called when the audience has not entered the room |
|
|
33
|
+
|
|
34
|
+
## 3. Mechanism & Sequence
|
|
35
|
+
|
|
36
|
+
### Anchor-Side Troubleshooting (in order)
|
|
37
|
+
|
|
38
|
+
1. Is the anchor seated? Check whether `LiveSeatStore.seatList` contains anchor info; if not, call `takeSeat`.
|
|
39
|
+
2. Is the microphone open? Check `DeviceState.microphoneStatus`; if closed, call `openLocalMicrophone`.
|
|
40
|
+
3. Is the anchor muted? Check the anchor item's `userInfo.microphoneStatus` in `seatList`; if muted, call `unmuteMicrophone`.
|
|
41
|
+
|
|
42
|
+
### Audience-Side Troubleshooting (in order)
|
|
43
|
+
|
|
44
|
+
1. Is the user logged in? Check whether `loginState.loginStatus` is `LOGIN`.
|
|
45
|
+
2. Has the user entered the room? Check whether `LiveListState.currentLive` matches the current live room; if not, call `joinLive`.
|
|
46
|
+
3. Is the device volume normal? Verify the system volume is audible.
|
|
47
|
+
|
|
48
|
+
## 4. Standard Usage
|
|
49
|
+
|
|
50
|
+
Follow this flow step by step — check the state and handle accordingly:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
观众听不到主播说话
|
|
54
|
+
│
|
|
55
|
+
├── 主播侧排查
|
|
56
|
+
│ ├── 1. 是否在麦上? → 否 → takeSeat 上麦
|
|
57
|
+
│ │ 查看 LiveSeatStore.seatList
|
|
58
|
+
│ ├── 2. 麦克风是否打开? → 否 → openLocalMicrophone
|
|
59
|
+
│ │ 查看 DeviceState.microphoneStatus
|
|
60
|
+
│ └── 3. 是否静音? → 是 → unmuteMicrophone
|
|
61
|
+
│ 查看 seatList 主播 userInfo.microphoneStatus
|
|
62
|
+
│
|
|
63
|
+
└── 观众侧排查
|
|
64
|
+
├── 1. 是否已登录? → 否 → 登录
|
|
65
|
+
│ 查看 loginState.loginStatus == LOGIN
|
|
66
|
+
├── 2. 是否进房? → 否 → joinLive 进房
|
|
67
|
+
│ 查看 LiveListState.currentLive
|
|
68
|
+
└── 3. 手机音量正常? → 否 → 调整音量
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 5. Expected Results
|
|
72
|
+
|
|
73
|
+
- Anchor's `LiveSeatStore.seatList` contains anchor info: anchor is seated and can publish audio.
|
|
74
|
+
- `DeviceState.microphoneStatus` is open: microphone is capturing audio.
|
|
75
|
+
- `userInfo.microphoneStatus` is open: not muted, audio is being published normally.
|
|
76
|
+
- Audience `loginStatus == LOGIN`: logged in.
|
|
77
|
+
- `LiveListState.currentLive` matches the current live room: room entry succeeded.
|
|
78
|
+
- If all conditions above are met and the audience still cannot hear audio: check device volume or contact the development team.
|
|
79
|
+
|
|
80
|
+
## 6. Common Pitfalls
|
|
81
|
+
|
|
82
|
+
- Pitfall 1: Only troubleshooting the audience side while ignoring the anchor's seat/microphone/mute state.
|
|
83
|
+
- Pitfall 2: Confusing `DeviceState.microphoneStatus` (device on/off) with `userInfo.microphoneStatus` (mute state) — the former is local device capture, the latter is the remote-visible state.
|
|
84
|
+
- Pitfall 3: Anchor publishes audio without taking a seat (taking a seat is a prerequisite for publishing).
|
|
85
|
+
- Pitfall 4: Audience has not entered the room (`currentLive` is incorrect) but assumes the anchor has no audio.
|
|
86
|
+
- Pitfall 5: Skipping login status check and directly troubleshooting the audio pipeline.
|
|
87
|
+
|
|
88
|
+
## 7. Problem Definition (retrieval hint)
|
|
89
|
+
|
|
90
|
+
When a voice room audience member cannot hear the anchor, how to troubleshoot layer by layer on the anchor side (seat/microphone/mute) and audience side (login/room entry/volume) to locate the issue.
|
|
91
|
+
|
|
92
|
+
## 8. Alternative Queries (retrieval recall)
|
|
93
|
+
|
|
94
|
+
- What to do when voice room audience cannot hear the anchor?
|
|
95
|
+
- How to troubleshoot no sound from the microphone in a voice room?
|
|
96
|
+
- Anchor is seated but audience cannot hear audio?
|
|
97
|
+
- How to check if the anchor is muted using `microphoneStatus`?
|
|
98
|
+
- No sound after entering a voice room?
|
|
99
|
+
- How to determine if the anchor is seated in a voice room?
|
|
100
|
+
- What to check first when audience cannot hear audio?
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Voice Room Seat Microphone Status Synchronization(语聊房 / 麦位 / 麦克风状态更新同步)"
|
|
3
|
+
product: live
|
|
4
|
+
frameworks: [android, ios, flutter]
|
|
5
|
+
scope: platform_common
|
|
6
|
+
tags: [voice room, seat, microphone status, mic on, mic off, userMicrophoneStatus, SeatListChanged, muteMicrophone, unmuteMicrophone, closeMicrophone, openMicrophone, sync]
|
|
7
|
+
version_range: ">=2.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Voice Room Seat Microphone Status Synchronization
|
|
11
|
+
|
|
12
|
+
## 1. Key Takeaways
|
|
13
|
+
|
|
14
|
+
- Both the anchor side and the audience side listen for seat microphone status (`userMicrophoneStatus`) changes via **`SeatListChanged`**.
|
|
15
|
+
- `userMicrophoneStatus` values: `0` = mic on; `1` = mic off (self-muted, can be re-opened by self); `2` = mic off (muted by admin, cannot be re-opened by self).
|
|
16
|
+
- `userMicrophoneStatus` can only be changed by **the anchor or a seated audience member** through `mute/unmute` or `close/open` APIs.
|
|
17
|
+
- The audience side only listens for status changes and does **not need** to call `mute/unmute` or `close/open` to modify `userMicrophoneStatus`.
|
|
18
|
+
|
|
19
|
+
## 2. Field / API Reference
|
|
20
|
+
|
|
21
|
+
| Field / Capability | Purpose | Notes |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `userMicrophoneStatus` | Seat microphone on/off state | `0` = mic on; `1` = mic off (self-muted, can reopen); `2` = mic off (admin-muted, cannot reopen) |
|
|
24
|
+
| `SeatListChanged` | Seat list change event | Both anchor and audience listen to this for `userMicrophoneStatus` changes; SDK syncs automatically |
|
|
25
|
+
| `muteMicrophone` / `unmuteMicrophone` | Mute / unmute | Called by anchor or seated audience; triggers `userMicrophoneStatus` change |
|
|
26
|
+
| `closeMicrophone` / `openMicrophone` | Close / open microphone | Called by anchor or seated audience; triggers `userMicrophoneStatus` change |
|
|
27
|
+
| Audience side | Read-only state | Only listens for status; does not call `mute/unmute` or `close/open` |
|
|
28
|
+
|
|
29
|
+
## 3. Mechanism & Sequence
|
|
30
|
+
|
|
31
|
+
Anchor or seated audience calls `mute/unmute` or `close/open` API -> triggers `userMicrophoneStatus` change -> SDK fires `SeatListChanged`, automatically syncing to all clients -> both anchor and audience receive the updated seat state via `SeatListChanged`.
|
|
32
|
+
|
|
33
|
+
`userMicrophoneStatus` can only be changed by the anchor or a seated audience member via `mute/unmute` or `close/open` APIs; the audience side only listens for status and does not actively modify it.
|
|
34
|
+
|
|
35
|
+
## 4. Standard Usage
|
|
36
|
+
|
|
37
|
+
Both anchor and audience listen for `SeatListChanged` and update the UI based on `userMicrophoneStatus`.
|
|
38
|
+
The anchor or a seated audience member changes the microphone state via `mute/unmute` or `close/open` APIs, and the SDK automatically syncs to all clients.
|
|
39
|
+
|
|
40
|
+
## 5. Expected Results
|
|
41
|
+
|
|
42
|
+
- After the anchor or seated audience calls `mute/unmute` or `close/open`, `userMicrophoneStatus` in `SeatListChanged` is updated on all clients.
|
|
43
|
+
- `userMicrophoneStatus = 0`: mic is on.
|
|
44
|
+
- `userMicrophoneStatus = 1`: mic is off (self-muted; can be re-opened by self).
|
|
45
|
+
- `userMicrophoneStatus = 2`: mic is off (admin-muted; cannot be re-opened by self).
|
|
46
|
+
- Audience side does not need to call `mute/unmute` or `close/open`; status is synced automatically by the SDK.
|
|
47
|
+
|
|
48
|
+
## 6. Common Pitfalls
|
|
49
|
+
|
|
50
|
+
- Pitfall 1: Audience calls `mute/unmute` or `close/open` to modify `userMicrophoneStatus` (not needed — status is auto-synced by SDK; audience side is read-only).
|
|
51
|
+
- Pitfall 2: Assuming `userMicrophoneStatus = 1` and `2` mean the same thing (`1` = self-muted and can reopen; `2` = admin-muted and cannot reopen).
|
|
52
|
+
- Pitfall 3: Assuming `userMicrophoneStatus` can be changed from the audience side (it can only be triggered by the anchor or a seated audience member via `mute/unmute` or `close/open`).
|
|
53
|
+
|
|
54
|
+
## 7. Problem Definition (retrieval hint)
|
|
55
|
+
|
|
56
|
+
The meaning of each `userMicrophoneStatus` value in a voice room seat, how it syncs to both anchor and audience via `SeatListChanged`, and which roles can change it through which APIs.
|
|
57
|
+
|
|
58
|
+
## 8. Alternative Queries (retrieval recall)
|
|
59
|
+
|
|
60
|
+
- Audience cannot see anchor's mic-on status in a voice room — what to do?
|
|
61
|
+
- What do `userMicrophoneStatus` values 0/1/2 mean?
|
|
62
|
+
- How does `SeatListChanged` sync seat microphone status?
|
|
63
|
+
- Who can change `userMicrophoneStatus`?
|
|
64
|
+
- Does the audience need to call `muteMicrophone` to update mic status?
|
|
65
|
+
- After admin mutes a user, can the user reopen their mic?
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Voice Room Anchor Creates Room and Starts Streaming (Flutter)(语聊房 / 房主 / 开播 / createLive)"
|
|
3
|
+
product: live
|
|
4
|
+
frameworks: [flutter]
|
|
5
|
+
scope: platform_specific
|
|
6
|
+
tags: [voice room, anchor, start streaming, publish audio, createLive, openLocalMicrophone, muteMicrophone, unmuteMicrophone, LiveListStore, AudioSalon, keepOwnerOnSeat, seatMode, TakeSeatMode, Flutter, AtomicXCore]
|
|
7
|
+
version_range: ">=2.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Voice Room Anchor Creates Room and Starts Streaming (Flutter)
|
|
11
|
+
|
|
12
|
+
## 1. Key Takeaways
|
|
13
|
+
|
|
14
|
+
- Voice room streaming flow: construct `LiveInfo` (with `liveID`, `seatTemplate`, `seatMode`, `keepOwnerOnSeat`), call `createLive` to create the room; on success, call `openLocalMicrophone` to capture and publish audio so other users in the room can hear the anchor.
|
|
15
|
+
- `liveID` is required; setting `keepOwnerOnSeat` to `true` makes the anchor automatically take a seat upon entering (taking a seat is a prerequisite for publishing audio — only seated users can publish audio streams in the room).
|
|
16
|
+
- `seatTemplate` should be set to the voice room template `AudioSalon(n)`, where n is the maximum seat count supported by the plan or a value less than it.
|
|
17
|
+
- `seatMode` sets the seat-taking mode (e.g., `TakeSeatMode.apply` for apply-to-take-seat).
|
|
18
|
+
- `muteMicrophone` pauses publishing local audio; `unmuteMicrophone` resumes publishing local audio.
|
|
19
|
+
|
|
20
|
+
## 2. Field / API Reference
|
|
21
|
+
|
|
22
|
+
| Field / Capability | Purpose | Notes |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `LiveInfo` | Room information | Dart constructor `LiveInfo({liveID, liveName, seatTemplate, seatMode, keepOwnerOnSeat})` |
|
|
25
|
+
| `liveID` | Room ID | Required parameter for `createLive` |
|
|
26
|
+
| `liveName` | Room name | Display name of the room |
|
|
27
|
+
| `seatTemplate` | Seat layout template | Use `AudioSalon(n)` for voice rooms, where n ≤ max seats in plan |
|
|
28
|
+
| `seatMode` | Seat-taking mode | e.g., `TakeSeatMode.apply` for apply-to-take-seat |
|
|
29
|
+
| `keepOwnerOnSeat` | Auto-seat the owner | Set to `true` so the anchor automatically takes a seat upon entering |
|
|
30
|
+
| `createLive(liveInfo)` | Create room (start streaming) | Pass `LiveInfo`, returns `Future<result>` for async handling |
|
|
31
|
+
| `result.isSuccess` | Success flag | `true` means creation succeeded |
|
|
32
|
+
| `result.message` | Error message | Returns error description on failure |
|
|
33
|
+
| `openLocalMicrophone` | Capture and publish audio | Opens local microphone and publishes audio stream to the room |
|
|
34
|
+
| `muteMicrophone` | Pause audio publishing | Pauses local audio stream while microphone remains open |
|
|
35
|
+
| `unmuteMicrophone` | Resume audio publishing | Resumes local audio stream while microphone remains open |
|
|
36
|
+
|
|
37
|
+
## 3. Mechanism & Sequence
|
|
38
|
+
|
|
39
|
+
Construct `LiveInfo` (`liveID` required, `seatTemplate=AudioSalon(n)`, `seatMode` as needed, `keepOwnerOnSeat=true`) -> `await createLive(liveInfo)` -> `result.isSuccess` is `true`, anchor is auto-seated -> call `openLocalMicrophone` to capture and publish audio -> other users in the room hear the anchor.
|
|
40
|
+
|
|
41
|
+
Taking a seat is a prerequisite for streaming: `keepOwnerOnSeat=true` ensures the anchor takes a seat before publishing audio. `muteMicrophone` / `unmuteMicrophone` are used to pause/resume during streaming.
|
|
42
|
+
|
|
43
|
+
## 4. Standard Usage
|
|
44
|
+
|
|
45
|
+
1. Construct `LiveInfo`: set `liveID`, `seatTemplate`, `seatMode`, `keepOwnerOnSeat`.
|
|
46
|
+
2. Call `await _liveListStore.createLive(liveInfo)` to start streaming.
|
|
47
|
+
3. Check `result.isSuccess`; on success, call `openLocalMicrophone` to capture and publish audio.
|
|
48
|
+
4. Call `muteMicrophone` / `unmuteMicrophone` to pause/resume streaming as needed.
|
|
49
|
+
|
|
50
|
+
```dart
|
|
51
|
+
class _YourAnchorPageState extends State<YourAnchorPage> {
|
|
52
|
+
// ... 其他代码 ...
|
|
53
|
+
final String _liveID = "test_voice_room_001";
|
|
54
|
+
|
|
55
|
+
@override
|
|
56
|
+
void initState() {
|
|
57
|
+
super.initState();
|
|
58
|
+
// ... 其他代码 ...
|
|
59
|
+
|
|
60
|
+
// 开始语聊
|
|
61
|
+
_startLive();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
Future<void> _startLive() async {
|
|
65
|
+
// 1. 准备 LiveInfo 对象
|
|
66
|
+
final liveInfo = LiveInfo(
|
|
67
|
+
// 2. 设置房间 id
|
|
68
|
+
liveID: _liveID,
|
|
69
|
+
// 3. 设置房间名称
|
|
70
|
+
liveName: "test 语聊房",
|
|
71
|
+
// 4. 设置语聊房布局模板(传入 9 即代表有 9 个麦位)
|
|
72
|
+
seatTemplate: AudioSalon(9),
|
|
73
|
+
// 5. 设置上麦模式,例如申请上麦
|
|
74
|
+
seatMode: TakeSeatMode.apply,
|
|
75
|
+
// 6. 设置主播开播后自动上麦
|
|
76
|
+
keepOwnerOnSeat: true,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// 7. 调用 createLive 开始直播
|
|
80
|
+
final result = await _liveListStore.createLive(liveInfo);
|
|
81
|
+
|
|
82
|
+
if (result.isSuccess) {
|
|
83
|
+
debugPrint("Response startLive onSuccess");
|
|
84
|
+
// 8. 房主创建成功后默认自动上麦,此时调用 openLocalMicrophone 采集并发布音频
|
|
85
|
+
_liveSeatStore.openLocalMicrophone();
|
|
86
|
+
} else {
|
|
87
|
+
debugPrint("Response startLive onError: ${result.message}");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 5. Expected Results
|
|
94
|
+
|
|
95
|
+
- `result.isSuccess == true`: room created successfully, anchor is auto-seated.
|
|
96
|
+
- After `openLocalMicrophone`: other users in the room can hear the anchor.
|
|
97
|
+
- After `muteMicrophone`: local audio publishing is paused; after `unmuteMicrophone`: publishing resumes.
|
|
98
|
+
- If `keepOwnerOnSeat` is not set to `true`: the anchor is not auto-seated and cannot publish audio.
|
|
99
|
+
- `result.isSuccess == false`: streaming failed, `result.message` contains the error description.
|
|
100
|
+
|
|
101
|
+
## 6. Common Pitfalls
|
|
102
|
+
|
|
103
|
+
- Pitfall 1: Calling `openLocalMicrophone` without calling `createLive` first (cannot publish audio without creating a room).
|
|
104
|
+
- Pitfall 2: Not setting `keepOwnerOnSeat` to `true`, so the anchor is not seated and audio publishing does not work.
|
|
105
|
+
- Pitfall 3: Not setting `seatTemplate` or setting n beyond the plan's maximum seat count.
|
|
106
|
+
- Pitfall 4: Confusing `muteMicrophone` (pauses audio stream publishing) with closing the microphone (stops audio capture).
|
|
107
|
+
- Pitfall 5: Reusing `liveID` (it must be globally unique; otherwise creation fails).
|
|
108
|
+
- Pitfall 6: `AudioSalon(9)` is a constructor form (not an enum); `seatMode` uses `TakeSeatMode.apply` (Dart enum lowercase).
|
|
109
|
+
|
|
110
|
+
## 7. Problem Definition (retrieval hint)
|
|
111
|
+
|
|
112
|
+
A Flutter voice room anchor needs to create a room and start audio streaming in the correct order, understanding the call timing and parameter meanings of `createLive`, `openLocalMicrophone`, `muteMicrophone`, and `unmuteMicrophone`.
|
|
113
|
+
|
|
114
|
+
## 8. Alternative Queries (retrieval recall)
|
|
115
|
+
|
|
116
|
+
- How does a Flutter voice room anchor start streaming?
|
|
117
|
+
- What is the call order of `createLive` and `openLocalMicrophone` in Flutter?
|
|
118
|
+
- How does a Flutter anchor take a seat and publish audio?
|
|
119
|
+
- What does the `keepOwnerOnSeat` parameter do?
|
|
120
|
+
- How to set the `AudioSalon` template for `seatTemplate`?
|
|
121
|
+
- What is the difference between `muteMicrophone` and `unmuteMicrophone` in Flutter?
|
|
122
|
+
- How to publish audio after creating a voice room?
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Voice Room Anchor Creates Room and Starts Streaming (iOS)(语聊房 / 房主 / 开播 / createLive)"
|
|
3
|
+
product: live
|
|
4
|
+
frameworks: [ios]
|
|
5
|
+
scope: platform_specific
|
|
6
|
+
tags: [voice room, anchor, start streaming, publish audio, createLive, openLocalMicrophone, muteMicrophone, unmuteMicrophone, LiveListStore, AudioSalon, keepOwnerOnSeat, seatMode, iOS, Swift, AtomicXCore]
|
|
7
|
+
version_range: ">=2.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Voice Room Anchor Creates Room and Starts Streaming (iOS)
|
|
11
|
+
|
|
12
|
+
## 1. Key Takeaways
|
|
13
|
+
|
|
14
|
+
- Voice room streaming flow: construct `LiveInfo` (with `liveID`, `seatTemplate`, `keepOwnerOnSeat`, `seatMode`), call `createLive` to create the room; on success, call `openLocalMicrophone` to capture and publish audio so other users in the room can hear the anchor.
|
|
15
|
+
- `liveID` is required; setting `keepOwnerOnSeat` to `true` makes the anchor automatically take a seat upon entering (taking a seat is a prerequisite for publishing audio — only seated users can publish audio streams in the room).
|
|
16
|
+
- `seatTemplate` should be set to `SeatLayoutTemplate.AudioSalon(seatCount: n)`, where n is the maximum seat count supported by the plan or a value less than it.
|
|
17
|
+
- `seatMode` sets the seat-taking mode (e.g., `.apply` for apply-to-take-seat).
|
|
18
|
+
- `muteMicrophone` pauses publishing local audio; `unmuteMicrophone` resumes publishing local audio.
|
|
19
|
+
|
|
20
|
+
## 2. Field / API Reference
|
|
21
|
+
|
|
22
|
+
| Field / Capability | Purpose | Notes |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `LiveInfo` | Room information | Contains `liveID`, `liveName`, `seatTemplate`, `keepOwnerOnSeat`, `seatMode`, etc. |
|
|
25
|
+
| `liveID` | Room ID | Required parameter for `createLive` |
|
|
26
|
+
| `liveName` | Room name | Display name of the room |
|
|
27
|
+
| `seatTemplate` | Seat layout template | Use `SeatLayoutTemplate.AudioSalon(seatCount: n)` for voice rooms, where n ≤ max seats in plan |
|
|
28
|
+
| `keepOwnerOnSeat` | Auto-seat the owner | Set to `true` so the anchor automatically takes a seat upon entering |
|
|
29
|
+
| `seatMode` | Seat-taking mode | e.g., `.apply` for apply-to-take-seat |
|
|
30
|
+
| `createLive(liveInfo)` | Create room (start streaming) | Pass `LiveInfo`, returns `Result` for async handling |
|
|
31
|
+
| `openLocalMicrophone` | Capture and publish audio | Opens local microphone and publishes audio stream to the room |
|
|
32
|
+
| `muteMicrophone` | Pause audio publishing | Pauses local audio stream while microphone remains open |
|
|
33
|
+
| `unmuteMicrophone` | Resume audio publishing | Resumes local audio stream while microphone remains open |
|
|
34
|
+
|
|
35
|
+
## 3. Mechanism & Sequence
|
|
36
|
+
|
|
37
|
+
Construct `LiveInfo` (`liveID` required, `seatTemplate=AudioSalon(n)`, `keepOwnerOnSeat=true`, `seatMode` as needed) -> call `createLive` to create the room -> `case .success` callback fires, anchor is auto-seated -> call `openLocalMicrophone` to capture and publish audio -> other users in the room hear the anchor.
|
|
38
|
+
|
|
39
|
+
Taking a seat is a prerequisite for streaming: `keepOwnerOnSeat=true` ensures the anchor takes a seat before publishing audio. `muteMicrophone` / `unmuteMicrophone` are used to pause/resume during streaming.
|
|
40
|
+
|
|
41
|
+
## 4. Standard Usage
|
|
42
|
+
|
|
43
|
+
1. Construct `LiveInfo`: set `liveID`, `seatTemplate`, `keepOwnerOnSeat`, `seatMode`.
|
|
44
|
+
2. Call `createLive(liveInfo)` and handle success/failure in `switch result`.
|
|
45
|
+
3. In `case .success`, call `openLocalMicrophone` to capture and publish audio.
|
|
46
|
+
4. Call `muteMicrophone` / `unmuteMicrophone` to pause/resume streaming as needed.
|
|
47
|
+
|
|
48
|
+
```swift
|
|
49
|
+
import UIKit
|
|
50
|
+
import AtomicXCore
|
|
51
|
+
|
|
52
|
+
class YourAnchorViewController: UIViewController {
|
|
53
|
+
// ... 其他代码 ...
|
|
54
|
+
private let liveID = "test_voice_room_001"
|
|
55
|
+
|
|
56
|
+
override func viewDidLoad() {
|
|
57
|
+
super.viewDidLoad()
|
|
58
|
+
// ... 其他代码 ...
|
|
59
|
+
|
|
60
|
+
// 开始语聊
|
|
61
|
+
startLive()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private func startLive() {
|
|
65
|
+
// 1. 准备 LiveInfo 对象
|
|
66
|
+
var liveInfo = LiveInfo()
|
|
67
|
+
|
|
68
|
+
// 2. 设置房间 id
|
|
69
|
+
liveInfo.liveID = liveID
|
|
70
|
+
// 3. 设置房间名称
|
|
71
|
+
liveInfo.liveName = "test 语聊房"
|
|
72
|
+
// 4. 设置语聊房布局模板(传入 9 即代表有 9 个麦位)
|
|
73
|
+
liveInfo.seatTemplate = SeatLayoutTemplate.AudioSalon(seatCount: 9)
|
|
74
|
+
|
|
75
|
+
// 5. 设置主播开播后自动上麦
|
|
76
|
+
liveInfo.keepOwnerOnSeat = true
|
|
77
|
+
|
|
78
|
+
// 6. 设置上麦模式,例如申请上麦
|
|
79
|
+
liveInfo.seatMode = .apply
|
|
80
|
+
|
|
81
|
+
// 7. 调用 createLive 开始直播
|
|
82
|
+
liveListStore.createLive(liveInfo) { [weak self] result in
|
|
83
|
+
guard let self = self else { return }
|
|
84
|
+
switch result {
|
|
85
|
+
case .success(let liveInfo):
|
|
86
|
+
print("Response startLive onSuccess")
|
|
87
|
+
// 8. 房主创建成功后默认自动上麦,此时调用 openLocalMicrophone 采集并发布音频
|
|
88
|
+
liveSeatStore.openLocalMicrophone(completion: nil)
|
|
89
|
+
case .failure(let errorInfo):
|
|
90
|
+
print("Response startLive onError: \(errorInfo.message)")
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 5. Expected Results
|
|
98
|
+
|
|
99
|
+
- `case .success` callback fires: room created successfully, anchor is auto-seated.
|
|
100
|
+
- After `openLocalMicrophone`: other users in the room can hear the anchor.
|
|
101
|
+
- After `muteMicrophone`: local audio publishing is paused; after `unmuteMicrophone`: publishing resumes.
|
|
102
|
+
- If `keepOwnerOnSeat` is not set to `true`: the anchor is not auto-seated and cannot publish audio.
|
|
103
|
+
- `case .failure(let errorInfo)` callback fires: streaming failed, `errorInfo.message` contains the error description.
|
|
104
|
+
|
|
105
|
+
## 6. Common Pitfalls
|
|
106
|
+
|
|
107
|
+
- Pitfall 1: Calling `openLocalMicrophone` without calling `createLive` first (cannot publish audio without creating a room).
|
|
108
|
+
- Pitfall 2: Not setting `keepOwnerOnSeat` to `true`, so the anchor is not seated and audio publishing does not work.
|
|
109
|
+
- Pitfall 3: Not setting `seatTemplate` or setting `seatCount` beyond the plan's maximum seat count.
|
|
110
|
+
- Pitfall 4: Confusing `muteMicrophone` (pauses audio stream publishing) with closing the microphone (stops audio capture).
|
|
111
|
+
- Pitfall 5: Reusing `liveID` (it must be globally unique; otherwise creation fails).
|
|
112
|
+
- Pitfall 6: Forgetting `[weak self]` (to avoid retain cycles causing memory leaks); both `success` and `failure` branches of `switch result` must be handled.
|
|
113
|
+
|
|
114
|
+
## 7. Problem Definition (retrieval hint)
|
|
115
|
+
|
|
116
|
+
An iOS voice room anchor needs to create a room and start audio streaming in the correct order, understanding the call timing and parameter meanings of `createLive`, `openLocalMicrophone`, `muteMicrophone`, and `unmuteMicrophone`.
|
|
117
|
+
|
|
118
|
+
## 8. Alternative Queries (retrieval recall)
|
|
119
|
+
|
|
120
|
+
- How does an iOS voice room anchor start streaming?
|
|
121
|
+
- What is the call order of `createLive` and `openLocalMicrophone` on iOS?
|
|
122
|
+
- How does an iOS anchor take a seat and publish audio?
|
|
123
|
+
- What does the `keepOwnerOnSeat` parameter do?
|
|
124
|
+
- How to set the `AudioSalon` template for `seatTemplate`?
|
|
125
|
+
- What is the difference between `muteMicrophone` and `unmuteMicrophone` on iOS?
|
|
126
|
+
- How to publish audio after creating a voice room?
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Why Abnormally Exited Members Still Appear in TUIRoomKit Member List and How to Clean Up(TUIRoomKit / 异常退出 / 幽灵成员 / 心跳检测 / 离线检测)"
|
|
3
|
+
product: room
|
|
4
|
+
frameworks: [react, vue, web, android, ios, flutter]
|
|
5
|
+
scope: platform_common
|
|
6
|
+
tags: [TUIRoomKit, abnormal exit, ghost member, heartbeat detection, offline detection, kick from room, kick_user_out, disconnect callback, member list, room cleanup]
|
|
7
|
+
version_range: ">=2.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Why Abnormally Exited Members Still Appear in TUIRoomKit Member List and How to Clean Up
|
|
11
|
+
|
|
12
|
+
## 1. Key Takeaways
|
|
13
|
+
|
|
14
|
+
- When a user exits abnormally (process killed, network disconnected, page closed without calling leave), the member still appears in the remote member list. This is the expected behavior of the **video conferencing SDK backend heartbeat offline detection**.
|
|
15
|
+
- Current rule: the backend removes an abnormally exited user from the room approximately **5–6 minutes** after heartbeat loss. Only then do remote participants receive the leave notification and update the member list.
|
|
16
|
+
- **The heartbeat interval cannot be set very short by default**: short heartbeat intervals increase the risk of false kicks during network jitter, disrupting normal meeting experience.
|
|
17
|
+
- If your business requires faster ghost member cleanup: Option 1 (submit a ticket to shorten heartbeat to ~2 minutes) or Option 2 (use IM disconnect callback + `kick_user_out` to kick immediately).
|
|
18
|
+
|
|
19
|
+
## 2. Field / API Reference
|
|
20
|
+
|
|
21
|
+
| Field / Capability | Purpose | Notes |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| Heartbeat offline detection | Detects user online status | Backend checks whether user heartbeat is lost |
|
|
24
|
+
| Heartbeat loss | Signal of abnormal exit | Heartbeat stops when process is killed / network disconnected / page closed without leave |
|
|
25
|
+
| Ghost member | Abnormally exited user still displayed | Removed from room after ~5–6 minutes |
|
|
26
|
+
| `kick_user_out` | Kick a room member | Business backend calls this to immediately clean up |
|
|
27
|
+
| `disconnect` callback | Disconnection callback | IM server detects user offline |
|
|
28
|
+
| Heartbeat interval adjustment | Backend configuration | Can be shortened to ~2 minutes via support ticket |
|
|
29
|
+
|
|
30
|
+
## 3. Mechanism & Sequence
|
|
31
|
+
|
|
32
|
+
User exits abnormally (process killed, network disconnected, page closed without leave) -> Backend detects heartbeat loss -> After ~5–6 minutes, removes user from room -> Remote participants receive leave notification and update member list.
|
|
33
|
+
|
|
34
|
+
The default heartbeat interval cannot be too short to avoid false kicks caused by network jitter. If the business requires faster cleanup:
|
|
35
|
+
|
|
36
|
+
- **Option 1**: Submit a support ticket to shorten the backend heartbeat detection interval to ~2 minutes.
|
|
37
|
+
- **Option 2**: Business backend listens for the IM `disconnect` callback to detect offline status, then calls `kick_user_out` to immediately remove the ghost member.
|
|
38
|
+
|
|
39
|
+
## 4. Standard Usage
|
|
40
|
+
|
|
41
|
+
1. **Option 1 (adjust heartbeat interval)**: Submit a support ticket to have the backend heartbeat detection interval shortened to ~2 minutes.
|
|
42
|
+
2. **Option 2 (server-side proactive cleanup)**:
|
|
43
|
+
- Business backend listens for the IM server `disconnect` (disconnection) callback.
|
|
44
|
+
- Upon receiving the offline signal, calls `kick_user_out` to kick the room member.
|
|
45
|
+
|
|
46
|
+
## 5. Expected Results
|
|
47
|
+
|
|
48
|
+
- Abnormally exited users are removed from the room after ~5–6 minutes, and remote member list updates accordingly.
|
|
49
|
+
- After adjusting heartbeat to ~2 minutes via support ticket, cleanup is faster.
|
|
50
|
+
- Option 2 using `disconnect` callback + `kick_user_out` immediately removes ghost members.
|
|
51
|
+
- Setting heartbeat too short increases the risk of false kicks during network jitter.
|
|
52
|
+
|
|
53
|
+
## 6. Common Pitfalls
|
|
54
|
+
|
|
55
|
+
- Pitfall 1: Expecting abnormally exited users to disappear from the member list immediately (heartbeat detection takes ~5–6 minutes).
|
|
56
|
+
- Pitfall 2: Assuming the heartbeat interval can be set arbitrarily short (network jitter causes false kicks, disrupting normal meetings).
|
|
57
|
+
- Pitfall 3: Overlooking that the business side can proactively kick members (`disconnect` callback + `kick_user_out`).
|
|
58
|
+
|
|
59
|
+
## 7. Problem Definition (retrieval hint)
|
|
60
|
+
|
|
61
|
+
Why an abnormally exited user still appears in the remote member list in TUIRoomKit, and how to clean up ghost members faster.
|
|
62
|
+
|
|
63
|
+
## 8. Alternative Queries (retrieval recall)
|
|
64
|
+
|
|
65
|
+
- What to do when an abnormally exited user still shows in the member list?
|
|
66
|
+
- How to clean up ghost members in TUIRoomKit?
|
|
67
|
+
- How long until a disconnected user is removed from the room?
|
|
68
|
+
- Can the heartbeat detection interval be shortened?
|
|
69
|
+
- Abnormally exited user keeps showing in the list?
|
|
70
|
+
- How to kick an offline user?
|