功能模块 | -功能 | -功能细分/描述 | -接口文档 | -精简版 SDK | -标准版 SDK | -
消息管理 | -发送和接收消息 | -发送和接收消息 | -- | ✅ | -✅ | -
接收消息 | -✅ | -✅ | -|||
发送和接收附件类型的消息 | -✅ | -✅ | -|||
发送和接收位置消息 | -✅ | -✅ | -|||
发送和接收透传消息 | -✅ | -✅ | -|||
发送自定义类型消息 | -✅ | -✅ | -|||
发送和接收合并消息 | -❌ | -✅ | -|||
发送和接收定向消息 | -✅ | -✅ | -|||
使用消息扩展字段 | -✅ | -✅ | -|||
管理本地消息 | -管理本地消息 | -- - - - | -❌ | -✅ | -|
管理服务端消息 | -管理服务端消息 | -- | -✅ | -✅ | -|
管理消息回执 | -消息送达回执 | -- | ✅ | -✅ | -|
消息已读回执 | -- | ❌ | -✅ | -||
撤回消息 | -撤回消息 -设置消息撤回监听 |
- - | ✅ | -✅ | -|
修改消息 | -单聊会话中已经发送成功的文本消息进行修改 | -- | ❌ | -✅ | -|
获取消息流量统计 | -获取消息流量统计 | -获取消息流量统计 | -- | - | |
翻译 | -消息翻译 | -- | ❌ | -✅ | -|
会话管理 | -会话列表 | -获取本地会话 | -获取本地会话 | -❌ | -✅ | -
从服务器分页获取会话列表 | -- | ✅ | -✅ | -||
会话未读数 | -获取或清零本地会话的未读数 | -- |
- ❌ | -✅ | -|
置顶会话 | -置顶会话 | -置顶会话 | -✅ | -✅ | -|
删除会话 | -单向删除服务端会话及本地会话 | -单向删除服务端会话和本地会话及其历史消息 | -✅ | -✅ | -|
删除本地会话及历史消息 | -删除本地会话及历史消息 | -❌ | -✅ | -||
管理用户属性 | -设置和获取用户属性 | -用户属性指实时消息互动用户的信息,如用户昵称、头像、邮箱、电话、性别、签名、生日等 | -管理用户属性 | -❌ | -✅ | -
管理用户关系 | -好友列表管理和黑名单管理 | -添加、删除好友; -设置和获取好友备注; -从服务器获取好友列表; -将用户添加到或移除黑名单 -从服务器获取黑名单列表 |
- 管理用户关系 | -❌ | -✅ | -
群组管理 | -群组为多人聊天,有稳定的成员关系。 | -创建、管理群组; -管理群成员; -管理群成员属性 |
- 群组管理 | -❌ | -✅ | -
聊天室管理 | -聊天室为多人聊天,没有固定的成员关系。 | -聊天室概述 |
- 聊天室概述 | -- | - |
创建和管理聊天室 | -创建聊天室 | -创建和管理聊天室 | -❌ | -✅ | -|
加入聊天室 | -✅ | -✅ | -|||
获取聊天室详情 | -✅ | -✅ | -|||
退出聊天室 | -✅ | -✅ | -|||
解散聊天室 | -❌ | -✅ | -|||
监听聊天室事件 | -✅ | -✅ | -|||
管理聊天室成员 | -获取聊天室成员列表 | -管理聊天室成员 | -✅ | -✅ | -|
将成员移出聊天室 | -❌ | -✅ | -|||
管理聊天室黑名单 | -❌ | -✅ | -|||
管理聊天室白名单 | -❌ | -✅ | -|||
管理聊天室禁言列表 | -❌ | -✅ | -|||
开启和关闭聊天室全员禁言 | -❌ | -✅ | -|||
管理聊天室所有者和管理员 | -❌ | -✅ | -|||
管理聊天室基本属性 | -获取聊天室公告 | -管理聊天室基本属性 | -✅ | -✅ | -|
更新聊天室公告 | -❌ | -✅ | -|||
修改聊天室名称 | -❌ | -✅ | -|||
修改聊天室描述 | -❌ | -✅ | -|||
管理聊天室自定义属性 | -管理聊天室自定义属性 | -管理聊天室自定义属性 | -❌ | -✅ | -|
进阶功能 | -离线推送 | -集成第三方消息推送服务 | -离线推送 | -❌ | -✅ | -
登录多个设备 | -支持同一账号在多个设备上登录并接收消息 | -- | ✅ | -✅ | -|
多设备管理 | -多设备登录 | -❌ | -✅ | -||
管理在线状态订阅 | -管理在线状态订阅 | -在线状态订阅 | -❌ | -✅ | -|
消息表情回复 Reaction | -对单聊和群聊中的消息通过表情回复 | -消息表情回复 | -❌ | -✅ | -|
子区管理 | -子区是群组成员的子集 | -子区管理 | -❌ | -✅ | -|
消息举报 | -开发者可以在客户端调用该接口举报违规消息 | -消息举报 | -❌ | -✅ | -
功能模块 | -功能 | -功能细分/描述 | -接口文档 | -精简版 SDK | -标准版 SDK | -
消息管理 | -发送和接收消息 | -发送和接收消息 | -- | ✅ | -✅ | -
接收消息 | -✅ | -✅ | -|||
发送和接收附件类型的消息 | -✅ | -✅ | -|||
发送和接收位置消息 | -✅ | -✅ | -|||
发送和接收透传消息 | -✅ | -✅ | -|||
发送自定义类型消息 | -✅ | -✅ | -|||
发送和接收合并消息 | -❌ | -✅ | -|||
发送和接收定向消息 | -✅ | -✅ | -|||
使用消息扩展字段 | -✅ | -✅ | -|||
管理本地消息 | -管理本地消息 | -- - - - | -❌ | -✅ | -|
管理服务端消息 | -管理服务端消息 | -- | -✅ | -✅ | -|
管理消息回执 | -消息送达回执 | -- | ✅ | -✅ | -|
消息已读回执 | -- | ❌ | -✅ | -||
撤回消息 | -撤回消息 -设置消息撤回监听 |
- - | ✅ | -✅ | -|
修改消息 | -单聊会话中已经发送成功的文本消息进行修改 | -- | ❌ | -✅ | -|
获取消息流量统计 | -获取消息流量统计 | -获取消息流量统计 | -- | - | |
翻译 | -消息翻译 | -- | ❌ | -✅ | -|
会话管理 | -会话列表 | -获取本地会话 | -获取本地会话 | -❌ | -✅ | -
从服务器分页获取会话列表 | -- | ✅ | -✅ | -||
会话未读数 | -获取或清零本地会话的未读数 | -- |
- ❌ | -✅ | -|
置顶会话 | -置顶会话 | -置顶会话 | -✅ | -✅ | -|
删除会话 | -单向删除服务端会话及本地会话 | -单向删除服务端会话和本地会话及其历史消息 | -✅ | -✅ | -|
删除本地会话及历史消息 | -删除本地会话及历史消息 | -❌ | -✅ | -||
管理用户属性 | -设置和获取用户属性 | -用户属性指实时消息互动用户的信息,如用户昵称、头像、邮箱、电话、性别、签名、生日等 | -管理用户属性 | -❌ | -✅ | -
管理用户关系 | -好友列表管理和黑名单管理 | -添加、删除好友; -设置和获取好友备注; -从服务器获取好友列表; -将用户添加到或移除黑名单 -从服务器获取黑名单列表 |
- 管理用户关系 | -❌ | -✅ | -
群组管理 | -群组为多人聊天,有稳定的成员关系。 | -创建、管理群组; -管理群成员; -管理群成员属性 |
- 群组管理 | -❌ | -✅ | -
聊天室管理 | -聊天室为多人聊天,没有固定的成员关系。 | -聊天室概述 |
- 聊天室概述 | -- | - |
创建和管理聊天室 | -创建聊天室 | -创建和管理聊天室 | -❌ | -✅ | -|
加入聊天室 | -✅ | -✅ | -|||
获取聊天室详情 | -✅ | -✅ | -|||
退出聊天室 | -✅ | -✅ | -|||
解散聊天室 | -❌ | -✅ | -|||
监听聊天室事件 | -✅ | -✅ | -|||
管理聊天室成员 | -获取聊天室成员列表 | -管理聊天室成员 | -✅ | -✅ | -|
将成员移出聊天室 | -❌ | -✅ | -|||
管理聊天室黑名单 | -❌ | -✅ | -|||
管理聊天室白名单 | -❌ | -✅ | -|||
管理聊天室禁言列表 | -❌ | -✅ | -|||
开启和关闭聊天室全员禁言 | -❌ | -✅ | -|||
管理聊天室所有者和管理员 | -❌ | -✅ | -|||
管理聊天室基本属性 | -获取聊天室公告 | -管理聊天室基本属性 | -✅ | -✅ | -|
更新聊天室公告 | -❌ | -✅ | -|||
修改聊天室名称 | -❌ | -✅ | -|||
修改聊天室描述 | -❌ | -✅ | -|||
管理聊天室自定义属性 | -管理聊天室自定义属性 | -管理聊天室自定义属性 | -❌ | -✅ | -|
进阶功能 | -离线推送 | -集成第三方消息推送服务 | -离线推送 | -❌ | -✅ | -
登录多个设备 | -支持同一账号在多个设备上登录并接收消息 | -- | ✅ | -✅ | -|
多设备管理 | -多设备登录 | -❌ | -✅ | -||
管理在线状态订阅 | -管理在线状态订阅 | -在线状态订阅 | -❌ | -✅ | -|
消息表情回复 Reaction | -对单聊和群聊中的消息通过表情回复 | -消息表情回复 | -❌ | -✅ | -|
子区管理 | -子区是群组成员的子集 | -子区管理 | -❌ | -✅ | -|
消息举报 | -开发者可以在客户端调用该接口举报违规消息 | -消息举报 | -❌ | -✅ | -
安装包名称 | -适配环境要求 | -下载安装包 | -下载部署手册 | -
环信私有化即时通讯服务安装包(单机版) | -操作系统:Linux、ubuntu 20 及以上、centos 7 及以上 CPU 架构:X86、ARM |
- 立即下载(X86) 立即下载(ARM) |
-立即下载 | -
平台 | 应用端 | 下载地址 | 备注 |
访客端 | iOS | 联系商务获取 | 下载后选择【用户模块】注册与登录 |
Android | 下载体验 | 下载后选择【用户模块】注册与登录 | |
客服&运管人员 | iOS | 联系商务获取 | 下载后选择【运管模块】,使用客服预置账号登录 |
Android | 下载体验 | 下载后选择【运管模块】,使用客服预置账号登录 | |
Web | 点击体验 | 下载后选择【运管模块】,使用客服预置账号登录 |
- SDK 类型 - |
-
- 平台 - |
-
- 版本号 - |
-
- 下载地址 - |
-
- 开发指南 - |
-
- - 客户端 SDK - |
-
- Android - |
-- - | -- - | -- - | -
- Web - |
-- - | -
- • React: 下载 SDK 及 Demo 体验 Demo |
-- - | -|
- iOS - |
-- - | -- - | -- - | -|
- Windows(C++) - |
-
- 3.9.1 - |
-- - | -- - | -|
- Windows(C#) - |
-- - | -- - | -- - | -|
- Linux - |
-- - | -- - | -- - | -|
- Electron - |
-- - | -- - | -- - | -|
- uni-app - |
-- - | -- - | -- - | -|
- 小程序 - |
-- - | -- - | -- - | -|
- Unity - |
-
- 3.9.0 - |
-- - | -- | |
- Flutter - |
-- - | -- - | -- - | -|
- - 服务端 SDK - |
-
- Java - |
-- - | -- - | -- - | -
- PHP - |
-
- 0.1.0 - |
-- - | -- - | -
方案 | 平台 | 说明 | 下载SDK及Demo | 下载应用 | -
音视频SDK | Android | SDK 兼容 android 5.0及以上版本,easeUI 兼容 android 5.0及以上版本 | 下载代码 | 体验Demo | -
iOS | SDK 兼容 iOS 10及以上版本 | 下载代码 | 体验Demo | -|
Web | 环信 WebIM SDK 为 PC /移动 Web 应用,提供完善的即时通信与音视频功能 | 下载代码 | 体验Demo | -|
小程序端 | 环信小程序 SDK提供全平台小程序解决方案,支持平台包括微信小程序、QQ小程序、百度小程序、抖音以及Uniapp编译的原生应用 | 下载代码 | \ | -
方案 | 说明 | 平台 | 下载SDK及Demo | 下载应用 | -
视频会议 | 音视频会议可以支持创建会议、加入会议等功能 | Android | 下载代码 | 体验Demo | -
iOS | 下载代码 | \ | -||
Web | 下载代码 | 体验Demo | -||
桌面端 | 下载代码 | 体验Windows Demo 体验MAC Demo |
-
方案 | 说明 | 平台 | 下载SDK及Demo | 下载应用 | -
视频会议 | 音视频会议可以支持创建会议、加入会议等功能 | Android | 下载代码 | 体验Demo | -
iOS | 下载代码 | \ | -||
Web | 下载代码 | 体验Demo | -||
桌面端 | 下载代码 | 体验Windows Demo 体验MAC Demo |
-
-//有新的数据流上传
-- (void)streamDidUpdate:(EMCallConference *)aConference
- addStream:(EMCallStream *)aStream
-{
- // aStream中包含了流信息,此时应该订阅流
-}
-```
-
-### 11. 订阅流
-
-成员收到有数据流加入的通知后,可以订阅该流,订阅后可以接收到流内的音视频,订阅过程如下:
-
-```
-// remoteView用于在UI上展示对方的视频
- EMCallRemoteView *remoteView = [[EMCallRemoteView alloc] init];
- //订阅其他人的数据流,,即订阅当前会议上麦主播的数据流
- [[EMClient sharedClient].conferenceManager subscribeConference:[EMDemoOption sharedOptions].conference streamId:aStream.streamId remoteVideoView:remoteView completion:^(EMError *aError) {
- // 若订阅成功,aError应为nil,否则为失败信息。
- // 订阅成功后,应把remoteView展示到UI上
- }];
-```
-
-### 12. 退出会议
-
-用户退出会议的过程如下:
-
-```
-[[EMClient sharedClient].conferenceManager leaveConference:[EMDemoOption sharedOptions].conference completion:nil];
-```
-
-用户退出会议后,会议中的其他成员会收到以下回调通知:
-
-```
-- (void)memberDidLeave:(EMCallConference *)aConference
- member:(EMCallMember *)aMember
-{
- // aMember为退出的成员信息
-}
-```
-
-## 进阶功能
-
-### 会议管理
-
-#### **取日志**
-
-SDK会写入日志文件到本地。日志文件路径如下:沙箱Documents/HyphenateSDK/easemoblog,以真机为例,获取过程如下:
-
-- 打开Xcode连接设备,前往Xcode –> Window –> Devices and Simulators
-- 进入Devices选项卡,在左侧选择目标设备,界面如下:
-
-[![img](https://docs-im.easemob.com/_media/rtc/one2one/fetchlogfile.png?w=400&tok=6c005b)](https://docs-im.easemob.com/_detail/rtc/one2one/fetchlogfile.png?id=rtc%3Aconference%3Aios)
-
-日志文件easemob.log文件在下载包内容的AppData/Library/Application Support/HyphenateSDK/easemobLog目录下。
-
-#### **创建会议并加入**
-
-除根据房间名和房间密码加入会议的api外,SDK还提供了直接创建并加入会议的api,接口如下:
-
-```
-//Objective-C
-- (void)createAndJoinConference
-{
- __weak typeof(self) weakself = self;
- void (^block)(EMCallConference *aCall, NSString *aPassword, EMError *aError) = ^(EMCallConference *aCall, NSString *aPassword, EMError *aError) {
- if (aError) {
- //错误提示
- return ;
- }
-
- //更新页面显示
- };
-
- EMConferenceType type = EMConferenceTypeCommunication;
- // record 与 mergeStream、isSupportWechatMiniProgram 根据自己场景需求设置
- [[EMClient sharedClient].conferenceManager createAndJoinConferenceWithType:type password:@"password" record:NO mergeStream:NO isSupportWechatMiniProgram:NO completion:block];
-}
-```
-
-调用该接口后,将拥有一个会议实例Conference,同时成员将成为该Conference的管理员。
-
-用户创建会议时可以设置参数指定是否支持小程序音视频,是否需要在服务器端录制,录制时是否合并流、是否支持微信小程序。
-
-创建会议成功以后,默认超时时间为三分钟,超过三分钟没有人加入,会议会自动销毁;另外当会议中所有人离开2分钟后,会议也会被销毁。
-
-如果想在创建会议时指定会议中的最大视频数、最大主播数,或开启cdn推流,可以使用带RoomCofnig参数的创建会议接口,此时roomconfig中指定的会议类型无效。接口如下:
-
-```
-/*!
- * \~chinese
- * 创建并加入会议
- *
- * @param aType 会议类型
- * @param aPassword 会议密码
- * @param aConfrConfig 会议属性配置
- * @param aCompletionBlock 完成的回调
- */
-- (void)createAndJoinConferenceWithType:(EMConferenceType)aType
- password:(NSString *)aPassword
- confrConfig:(RoomConfig*)aConfrConfig
- completion:(void (^)(EMCallConference *aCall, NSString *aPassword, EMError *aError))aCompletionBlock;
-```
-
-#### **邀请成员加入会议**
-
-SDK没有提供邀请接口,可以自己实现,比如使用环信IM通过发消息邀请,比如通过发邮件邀请等等。
-
-至于需要发送哪些邀请信息,可以参照SDK中的join接口,可以发送Conference的confrId和password,如果是用joinRoom接口创建的会议,也可以发送房间名和房间密码。
-
-比如用环信IM发消息邀请
-
-```
-//Objective-C
-- (void)inviteUser:(NSString *)aUserName
-{
- NSString *confrId = self.conference.confId;
- NSString *password = self.password;
- EMConferenceType type = self.type;
- NSString *currentUser = [EMClient sharedClient].currentUsername;
- EMTextMessageBody *textBody = [[EMTextMessageBody alloc] initWithText:[[NSString alloc] initWithFormat:@"%@ 邀请你加入会议: %@", currentUser, confrId]];
- EMMessage *message = [[EMMessage alloc] initWithConversationID:aUserName from:currentUser to:aUserName body:textBody ext:@{@"em_conference_op":@"invite", @"em_conference_id":confrId, @"em_conference_password":password, @"em_conference_type":@(type)}];
- message.chatType = EMChatTypeChat;
- [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:nil];
-}
-```
-:::tip
- 使用环信IM邀请多个人时,建议使用群组消息。如果使用单聊发消息请注意每条消息中间的时间间隔,以防触发环信的垃圾消息防御机制。
-
- 被邀请人解析出邀请消息中带的confrId和password,调用SDK的join接口加入会议,成为会议成员且角色是Speaker。
-:::
-```
-//Objective-C
-- (void)joinConferenceWithConfrId:(NSString *)aConfrId password:(NSString *)aPassword
-{
- __weak typeof(self) weakself = self;
- void (^block)(EMCallConference *aCall, EMError *aError) = ^(EMCallConference *aCall, EMError *aError) {
- if (aError) {
- //错误提示
- return ;
- }
-
- //更新页面显示
- };
-
- [[EMClient sharedClient].conferenceManager joinConferenceWithConfId:aConfrId password:aPassword completion:block];
-}
-```
-
-用户B成功加入会议后,会议中其他成员会收到回调[EMConferenceManagerDelegate memberDidJoin:member:]
-
-#### **管理员销毁会议**
-
-会议中的管理员可以主动销毁会议,销毁会议过程如下:
-
-```
-[[EMClient sharedClient].conferenceManager destroyConferenceWithId:self.conference.confId completion:nil];
-```
-
-会议销毁后,会议中的其他成员将收到会议结束的回调通知。
-
-```
-- (void)conferenceDidEnd:(EMCallConference *)aConference
- reason:(EMCallEndReason)aReason
- error:(EMError *)aError
-{
-}
-```
-
-#### **设置会议人数限制**
-
-使用createAndJoinConference接口创建会议或者第一个使用joinRoom接口加入的成员为会议创建者,会议创建者在创建会议时可以设置会议中的最大视频数、主播数、观众数、共享桌面数的上限。
-默认最大视频数12,最大主播数100,最大观众数600,最大共享桌面数2。创建会议时使用RoomConfig参数指定人数限制,过程如下:
-
-```
-RoomConfig* roomConfig = [[RoomConfig alloc] init];
- roomConfig.maxVideoCount = 6;
- roomConfig.maxTalkerCount = 9;
- roomConfig.maxAudienceCount = 30;
- roomConfig.maxPubDesktopCount = 1;
- [[[EMClient sharedClient] conferenceManager] joinRoom:roomName password:pswd role:role roomConfig:roomConfig completion:block];
-```
-
-若加入会议时,超过最大主播数上限,加入会议返回失败,error为EMErrorCallSpeakerFull
-
-若发视频流时,超过最大视频数上限,将收到如下回调通知:
-
-```
-- (void)streamPubDidFailed:(EMCallConference *)aConference error:(EMError*)aError
-{
-}
-```
-
-若发共享桌面流时,超过最大数上限,将收到如下回调通知:
-
-```
-- (void)DesktopStreamDidPubFailed:(EMCallConference *)aConference error:(EMError*)aError
-{
-}
-```
-
-#### **获取会议信息**
-
-在会议进行中,可以通过getConference 方法来查询会议信息,从而可以拿到主播列表,观众人数等信息。
-
-```
-/*!
- * \~chinese
- * 获取会议信息
- *
- * @param aConfId 会议ID(EMCallConference.confId)
- * @param aPassword 会议密码
- * @param aCompletionBlock 完成的回调
- */
-- (void)getConference:(NSString *)aConfId
- password:(NSString *)aPassword
- completion:(void (^)(EMCallConference *aCall, EMError *aError))aCompletionBlock;
-```
-
-#### **会议属性**
-
-会议属性是会议的状态信息,由一组(key,value)组成。会议中的所有角色成员(管理员、主播、观众)都可以设置/删除会议频道属性,设置的会议属性会通知给会议中的所有人。
-
-设置会议属性的api方法如下:
-
-```
-/**
- * \~chinese
- * 设置频道属性,该会议中的所有人(包括自己)都会收到
- * {@link EMConferenceManagerDelegate#conferenceAttributeUpdated:attributeAction:attributeKey:}回调.
- * 该方法需要在加入会议后调用.
- *
- * @param attrKey
- * @param attrValue
- * @param aCompletionBlock
- */
-- (void)setConferenceAttribute:(NSString *)attrKey
- value:(NSString *)attrValue
- completion:(void(^)(EMError *aError))aCompletionBlock;
-```
-
-删除会议属性的api方法如下:
-
-```
-/**
- * \~chinese
- * 删除频道属性,该会议中的所有人(包括自己)都会收到
- * {@link EMConferenceManagerDelegate#conferenceAttributeUpdated:attributeAction:attributeKey:}回调.
- * 该方法需要在加入会议后调用.
- *
- * @param aKey
- * @param aCompletionBlock
- */
-- (void)deleteAttributeWithKey:(NSString *)aKey
- completion:(void(^)(EMError *aError))aCompletionBlock;
-```
-
-当会议属性信息改变时,会议中的成员会收到以下通知。
-
-```
-- (void)conferenceAttributeUpdated:(EMCallConference *)aConference
- attributes:(NSArray *)attrs
-```
-
-每一个EMConferenceAttribute包括了会议属性中的key,value,以及本次修改的action,action包括ADD、UPDATE、DELETE。
-
-#### **cdn合流推流**
-
-多人音视频支持将会议中的音视频流合并成一个流,推送到第三方的cdn直播服务器。整个合流推流过程包括开启cdn推流,更新推流布局,停止推流。
-
-##### **开启cdn推流**
-
-会议的创建者在创建会议时使用RoomConfig的接口,可以决定是否开启cdn推流,推流配置LiveConfig是RoomConfig的一个参数,可设置cdn推流的相关信息。开启过程如下:
-
-```
-LiveConfig* liveconfig = [[LiveConfig alloc] init];
-CDNCanvas* canvas = [[CDNCanvas alloc] init];
-canvas.fps = 18;
-canvas.kbps = 900;
-canvas.codec = @"H264";
-canvas.bgclr = 0x0000ff;
-canvas.width = [EMDemoOption sharedOptions].liveWidth;
-canvas.height = [EMDemoOption sharedOptions].liveHeight;
-liveconfig.canvas = canvas;
-liveconfig.cdnUrl = [EMDemoOption sharedOptions].cdnUrl;
-liveconfig.layoutStyle = CUSTOM;
-liveconfig.record = YES; //是否录制推流到cdn的音视频
-roomConfig.liveConfig = liveconfig;
-```
-
-当canvas设置的width、height为0时,cdn推流为**纯音频推流**。
-
-推流成功后,可以在EMConference对象中查看liveId,如果只有一路推流,可直接使用EMConference对象的liveId;如果存在多路推流,可访问EMConference对象的liveCfgs对象,liveCfgs存储了所有的推流信息。
-
-LiveConfig可设置的参数如下:
-
-```
-/*!
-* \~chinese
-* cdn 画布设置,创建会议时使用
-*/
-@interface CDNCanvas : NSObject
- /*! \~chinese 画布宽度 */
-@property (nonatomic) NSInteger width;
-/*! \~chinese 画布高度 */
-@property (nonatomic) NSInteger height;
-/*! \~chinese 画布的背景色,格式为 RGB 定义下的 Hex 值,不要带 # 号,如 0xFFB6C1 表示浅粉色。默认0x000000,黑色。
-*/
-@property (nonatomic) NSInteger bgclr;
-/*! \~chinese 推流帧率,可设置范围10-30 */
-@property (nonatomic) NSInteger fps;
-/*! \~chinese 推流码率,单位kbps,width和height较大时,码率需要提高,可设置范围1-5000 */
-@property (nonatomic) NSInteger kbps;
-/*! \~chinese 推流编码格式,目前只支持"H264" */
-@property (nonatomic) NSString* codec;
-
-@end
-
-/*!
-* \~chinese
-* cdn推流使用的画布类型
-*/
-typedef NS_ENUM(NSInteger, LayoutStyle) {
- CUSTOM,
- DEMO,
- GRID
-};
-/*!
-* \~chinese
-* cdn推流设置
-*/
-@interface LiveConfig : NSObject
-
-/*! \~chinese 推流url地址*/
-@property (nonatomic,strong) NSString *cdnUrl;
-
-/*! \~chinese 推流画布的配置*/
-@property (nonatomic) CDNCanvas* canvas;
-
-/*! \~chinese 推流方式,GRID或者CUSTOM,GRID将由服务器设置位置信息,CUSTOM将由用户自定义流的位置信息*/
-@property (nonatomic) LayoutStyle layoutStyle;
-
-/*! \~chinese 是否开启自定义录制*/
-@property (nonatomic) BOOL record;
-
-/*! \~chinese 音频录制参数*/
-@property (nonatomic) AudioConfig* audioCfg;
-
-@end
-```
-
-##### **更新布局**
-
-当用户调用更新布局接口后,cdn推流方式将强制变成CUSTOM模式,所有流的位置信息都由用户自己定义。 更新布局的接口如下:
-
-```
-/*!
-* \~chinese
-* 修改会议的cdn推流位置
-*
-* @param aCall 会议实例(自己创建的无效)
-* @param aReagionList 媒体流的位置信息
-* @param aLiveId 推流Id
-* @param aCompletionBlock 回调函数
-*/
-- (void)updateConference:(EMCallConference*)aCall
- liveId:(NSString*)aLiveId
- setRegions:(NSArray*)aReagionList
- completion:(void(^)(EMError *aError))aCompletionBlock;
-```
-
-LiveRegion的结构如下:
-
-```
-/*!
-* \~chinese
-* cdn推流的每一路流的模式
-*/
-typedef NS_ENUM(NSInteger, LiveRegionStyle) {
- /*! \~chinese FIt模式 */
- LiveRegionStyleFit,
- /*! \~chinese FIll模式 */
- LiveRegionStyleFill
-};
-
-/*!
-* \~chinese
-* cdn推流的每一路流的区域位置信息
-*/
-@interface LiveRegion : NSObject
-
-/*! \~chinese 流ID */
-@property (nonatomic) NSString* streamId;
-
-/*! \~chinese 流的左上角在x轴坐标 */
-@property (nonatomic) NSInteger x;
-
-/*! \~chinese 流的左上角在y轴坐标 */
-@property (nonatomic) NSInteger y;
-
-/*! \~chinese 流的宽度 */
-@property (nonatomic) NSInteger w;
-
-/*! \~chinese 流的高度 */
-@property (nonatomic) NSInteger h;
-
-/*! \~chinese 流的图层顺序,越小越在底层,从1开始 */
-@property (nonatomic) NSInteger z;
-
-/*! \~chinese 流的显示模式,Fit或Fill */
-@property (nonatomic) LiveRegionStyle style;
-
-@end
-```
-
-使用方法如下:
-
-```
-NSMutableArray* regionsList = [NSMutableArray array];
-LiveRegion* region = [[LiveRegion alloc] init];
-region.streamId = _streamId;
-region.style = LiveRegionStyleFill;
-region.x = 80;
-region.y = 60;
-region.w = 320;
-region.h = 240;
-region.z = 9;
-[regionsList addObject:region];
-[[[EMClient sharedClient] conferenceManager] updateConference:[EMDemoOption sharedOptions].conference liveId:aLiveId setRegions:regionsList completion:^(EMError *aError) {
- }];
-```
-
-##### **多路推流**
-
-多人音视频支持加入会议后,增加一路推流,只有管理员权限可进行次操作。增加一路推流的api方法如下:
-
-```
-/*!
-* \~chinese
-* 添加一路推流
-*
-* @param aCall 会议实例(自己创建的无效)
-* @param aLiveConfig 推流配置
-* @param aCompletionBlock 回调函数
-*/
-- (void)addConferenceLive:(EMCallConference*)aCall
- LiveCfg:(LiveConfig*)aLiveConfig
- completion:(void(^)(EMError *aError))aCompletionBlock;
-```
-
-##### **停止推流**
-
-管理员可以控制停止某一路推流,停止推流接口如下:
-
-```
-/*!
-* \~chinese
-* 删除一路推流
-*/
-- (void)deleteConferenceLive:(EMCallConference*)aCall
- liveId:(NSString*)aLiveId
- completion:(void(^)(EMError *aError))aCompletionBlock;
-```
-
-#### **云端录制**
-
-多人音视频会议支持云端录制功能,包括服务器默认录制以及自定义布局录制两种
-
-##### **服务器默认录制**
-
-服务器默认录制为九宫格布局,在会议创建时,由创建者指定是否开启,开启方法为创建会议时指定isRecord为YES,如下:
-
-```
-//Objective-C
- RoomConfig* roomConfig = [[RoomConfig alloc] init];
- roomConfig.isMerge = YES;
- roomConfig.isRecord = YES;
- [[[EMClient sharedClient] conferenceManager] joinRoom:roomName password:pswd role:role roomConfig:roomConfig completion:^(EMCallConference *aCall, EMError *aError) {
- self.conference = aCall;
- }];
-```
-
-##### **自定义布局录制**
-
-在推流的LiveConfig设置里,设record为YES,可以开启自定义录制,开启后会把推流到cdn的音视频按照推流布局录制下来。如果推流时未开启,也可以在推流后进行开启/停止自定义录制布局操作。开启/停止自定义录制布局的api如下:
-
-```
-/*!
-* \~chinese
-* 启动/停止自定义录制
-*
-* @param aCall 会议实例(自己创建的无效)
-* @param aLiveId 推流/录制Id
-* @param aEnabled 操作,启动/停止
-* @param aCompletionBlock 回调函数
-*/
-- (void)enableRecordLiveStream:(EMCallConference*)aCall
- liveId:(NSString*)aLiveId
- enabled:(BOOL)aEnabled
- completion:(void(^)(EMError *aError))aCompletionBlock;
-```
-
-#### **设置昵称,头像解决方案**
-
-多人音视频通话提供设置昵称的接口,在加入会议时设置;不直接提供头像设置接口,但提供头像设置方案,在加入会议时将头像url设置到RoomConfig的ext中,过程如下:
-
-```
-//Objective-C
- RoomConfig* roomConfig = [[RoomConfig alloc] init];
- roomConfig.nickName = @"昵称";
- NSMutableDictionary* extDic = [NSMutableDictionary dictionary];
- NSString* headImage = [EMDemoOption sharedOptions].headImage;
- [extDic setObject:headImage forKey:@"headImage"];
- NSError *jsonError = nil;
- NSData *jsonData = [NSJSONSerialization dataWithJSONObject:extDic options:NSJSONWritingPrettyPrinted error:&jsonError];
- NSString *jsonStr = @"";
- if (jsonData && !jsonError) {
- jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
- }
- roomConfig.ext = jsonStr;
- [[[EMClient sharedClient] conferenceManager] joinRoom:roomName password:pswd role:role roomConfig:roomConfig completion:^(EMCallConference *aCall, EMError *aError) {
- self.conference = aCall;
- }];
-```
-
-#### 私有部署
-
-私有部署设置方法参见[私有云sdk集成配置](../im/uc_iOS_private.md)
-
-### 音视频管理
-
-#### **设置通话参数**
-
-通话之前,可以设置音频通话的最大音频码率,最小视频码率、最大视频码率、分辨率和是否清晰度优先,设置方法如下:
-
-```
-EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
-options.maxAudioKBps = 32;
-options.maxVideoKBps = 3000;
-options.minVideoKBps = 500;
-options.maxVideoFrameRate = 20;
-options.videoResolution = EMCallVideoResolution352_288;
-options.isClarityFirst = YES;//若设为清晰度优先,将在弱网环境下保证视频的分辨率
-```
-
-#### **停止发布流**
-
-成员A可以调用unpublish接口取消自己已经发布的数据流,操作成功后,会议中的其他成员会收到回调[EMConferenceManagerDelegate streamDidUpdate:removeStream:] ,将对应的数据流信息移除。
-
-```
-//Objective-C
-- (void)unpubStream
-{
- [[EMClient sharedClient].conferenceManager unpublishConference:self.conference
- streamId:self.pubStreamId completion:^(EMError *aError)
- {
- //code
- }];
-}
-```
-
-#### **停止订阅流**
-
-成员B如果不想再看成员A的音视频,可以调用SDK接口unsubscribe。
-
-```
-//Objective-C
-- (void)unsubStream
-{
- __weak typeof(self) weakself = self;
- [[EMClient sharedClient].conferenceManager unsubscribeConference:self.conference streamId:self.pubStreamId completion:^(EMError *aError) {
- //code
- }];
-}
-```
-
-#### **操作自己订阅的流**
-
-对于订阅成功的流,可以有以下操作:
-
-```
-/**
- * \~chinese
- * mute远端音频
- *
- * @param aStreamId 要操作的Steam id
- * @param isMute 是否静音
- */
-- (void)muteRemoteAudio:(NSString *)aStreamId mute:(BOOL)isMute;
-
-/**
- * \~chinese
- * mute远端视频
- *
- * @param aStreamId 要操作的Steam id
- * @param isMute 是否关闭
- */
-- (void)muteRemoteVideo:(NSString *)aStreamId mute:(BOOL)isMute;
-```
-
-#### **通话中音视频控制**
-
-成员发布了自己的音视频流后,在会议过程中,可以进行以下操作:
-
-- 切换前后摄像头,调用如下
-
-```
-[[[EMClient sharedClient] conferenceManager] updateConferenceWithSwitchCamera:self.conference];
-```
-
-- 开关静音
-
-```
-[[[EMClient sharedClient] conferenceManager] updateConference:self.conference isMute:YES];
-```
-
-- 开关视频
-
-```
-[[[EMClient sharedClient] conferenceManager] updateConference:self.conference enableVideo:YES];
-```
-
-当成员对自己的数据流做开关静音/视频时,会议中的其他成员会收到回调[EMConferenceManagerDelegate streamDidUpdate:stream:]
-
-```
-//Objective-C
-- (void)streamDidUpdate:(EMCallConference *)aConference stream:(EMCallStream *)aStream
-{
- if ([aConference.callId isEqualToString:self.conference.callId] && aStream != nil) {
- //判断本地缓存的EMCallStream实例与aStream有哪些属性不同,并做相应更新
- }
-}
-```
-
-#### **音视频首帧回调**
-
-当成员发布流成功,发送第一帧音视频数据时,成员收到以下通知:
-
-```
-/*!
- * \~chinese
- * 发送第一帧音视频数据时,收到此回调
- *
- * @param aConference 会议
- * @param aType 流类型,音频或视频
- * @param streamId 流ID
-*/
-- (void)streamDidFirstFrameSended:(EMCallConference*)aConference type:(EMMediaType)aType streamId:(NSString*)streamId;
-```
-
-当成员订阅流成功,收到第一帧音视频数据时,成员会收到以下通知:
-
-```
-/*!
- * \~chinese
- * 接收流第一帧音视频数据时,收到此回调
- *
- * @param aConference 会议
- * @param aType 流类型,音频或视频
- * @param streamId 流ID
-*/
-- (void)streamDidFirstFrameReceived:(EMCallConference*)aConference type:(EMMediaType)aType streamId:(NSString*)streamId;
-```
-
-#### **音视频无数据回调**
-
-当会议中的成员A因断网或异常退出,而无音视频数据上传时,订阅该流的其他成员会收到下面的回调通知。
-
-```
-/*!
- * \~chinese
- * 下行音频流无数据时,收到此回调
- *
- * @param aConference 会议
- * @param aType 流类型,音频或视频
- * @param streamId 流ID
-*/
-- (void)streamStateUpdated:(EMCallConference*)aConference type:(EMMediaType)aType state:(EMMediaState)state streamId:(NSString*)streamId;
-```
-
-该功能需要会议中开启质量统计(必须在创建或者加入会议成功之后,在调用此方法)
-
-```
-[[EMClient sharedClient].conferenceManager enableStatistics:YES];
-```
-
-#### **弱网检测**
-
-SDK提供多人音视频会议的网络连接状态检测,当本地网络断开、重连、质量差时收到以下回调。该功能需要会议中开启质量统计。
-
-```
-- (void)conferenceNetworkDidChange:(EMCallConference *)aSession
- status:(EMCallNetworkStatus)aStatus
- {
- }
-```
-
-#### **通话质量**
-
-使用[conferenceManager enableStatistics:YES]开启视频质量统计后,用户会周期性收到视频质量数据的回调,回调函数定义如下:
-
-```
-/*!
- * \~chinese
- * 当前会议的媒体流质量报告回调
- *
- * @param aConference 会议
- * @param streamId 流ID
- * @param aReport 会议的质量参数
-*/
-- (void)conferenceDidUpdate:(EMCallConference*)aConference streamId:(NSString*)streamId statReport:(EMRTCStatsReport *)aReport;
-```
-
-[查看EMRTCStatsReport详细信息](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_r_t_c_stats_report.html)
-
-#### **监听谁在说话**
-
-多人音视频会议可以实时监听谁在说话,该功能需要开启,启动/停止控制如下:
-
-```
-// 开始监听说话者,参数为间隔时间
- [[[EMClient shareClient] conferenceManager] startMonitorSpeaker:(EMCallConference *)aCall
- timeInterval:(long long)aTimeMillisecond
- completion:(void (^)(EMError *aError))aCompletionBlock];
-
- // 停止监听说话者
- [[[EMClient shareClient] conferenceManager] stopMonitorSpeaker:(EMCallConference *)aCall];
-```
-
-有人说话时,会议成员会收到如下回调通知
-
-```
-- (void)conferenceSpeakerDidChange:(EMCallConference *)aConference
- speakingStreamIds:(NSArray *)aStreamIds
-{
-}
-```
-
-#### **mute远端音视频流**
-
-会议成员可以对自己订阅的远端音视频流进行mute操作,操作后自己不接收远端的音视频流,不影响会议中的其他人。操作接口如下:
-
-```
-/**
- * \~chinese
- * mute远端音频
- *
- * @param aStreamId 要操作的Steam id
- * @param isMute 是否静音
- */
-- (void)muteRemoteAudio:(NSString *)aStreamId mute:(BOOL)isMute;
-
-/**
- * \~chinese
- * mute远端视频
- *
- * @param aStreamId 要操作的Steam id
- * @param isMute 是否显示
- */
-- (void)muteRemoteVideo:(NSString *)aStreamId mute:(BOOL)isMute;
-```
-
-#### **变声/自定义音频**
-
-用户可以通过自己采集音频数据,使用外部输入音频数据的接口进行通话,从而实现变声等音频数据加工功能。
-
-##### **配置属性**
-
-用户使用自定义音频数据时,需要配置外部输入音频数据的开关,以及音频采样率,通道数(当前通道数只支持1),配置方法如下:
-
-```
-EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
-options.enableCustomAudioData = YES;
-options.audioCustomSamples = 48000;
-options.audioCustomChannels = 1;
-//这里调用加入会议接口
-```
-
-##### **输入音频数据**
-
-音频数据采集可参考1v1音视频通话Demo中的AudioRecord类实现,音频数据的输入必须在加入会议成功的回调后开始,否则会导致网络阻塞,影响通话质量。
-
-```
-[[[EMClient sharedClient] conferenceManager] joinRoom:roomName password:pswd role:role roomConfig:roomConfig completion:^(EMCallConference *aCall, EMError *aError) {
- self.conference = aCall;
- EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
- if(options.enableCustomAudioData){
- [self audioRecorder].channels = options.audioCustomChannels;
- [self audioRecorder].samples = options.audioCustomSamples;
- [[self audioRecorder] startAudioDataRecord];
- }
- }];
-```
-
-音频采集过程开始后,在音频数据的回调里调用外部输入音频数据接口
-
-```
-[[[EMClient sharedClient] conferenceManager] inputCustomAudioData:data];
-```
-
-会话挂断时,停止音频采集及输入过程。
-
-```
-//多人会议挂断触发事件
-- (void)hangupAction
-{
- EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
- if(options.enableCustomAudioData) {
- [[self audioRecorder] stopAudioDataRecord];
- }
-}
-```
-
-#### **美颜/自定义视频**
-
-如果用户需要自己采集特定的数据或者对于数据需要先进行一些处理,如滤镜、美颜等,可以使用SDK的外部输入视频数据的方法进行。
-
-##### **配置属性**
-
-使用外部输入视频数据接口前,需要先进行配置,配置参数为EMStreamParam中的enableCustomizeVideoData,设为YES可开启外部输入视频功能,开启后需要在publishConference的成功回调中开始视频数据采集。
-
-```
-__block NSString *publishId = @"";
-EMStreamParam *streamParam = [[EMStreamParam alloc] init];
-streamParam.enableCustomizeVideoData = YES; // 开启自定义视频流
-
-[[EMClient sharedClient].conferenceManager publishConference:self.conference
- streamParam:streamParam
- completion:^(NSString *aPubStreamId, EMError*aError) {
- if(!aError) {
- publishId = aPubStreamId;
- // **TODO:这里开启视频数据采集过程**
- [self startCapture]
- }
-}];
-```
-
-在视频数据采集的回调中调用外部输入视频数据接口inputVideoSampleBuffer。
-
-```
-- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
-{
- if ([self.delegate respondsToSelector:@selector(videoCaptureDataCallback:)])
- {
- // 输入视频流
- [[EMClient sharedClient].conferenceManager inputVideoSampleBuffer:sampleBuffer
- rotation:orientation
- conference:self.conference
- publishedStreamId:publishId
- completion:^(EMError *aError) {
- }];
- }
-}
-```
-
-在关闭视频传输或会议结束的回调中,停止视频数据的采集。
-
-```
-//多人会议挂断触发事件
-- (void)hangupAction
-{
- [self stopCapture];
-}
-```
-
-#### **共享桌面**
-
-使用sdk共享桌面,只能共享指定的view。
-
-```
-EMStreamParam *streamParam = [[EMStreamParam alloc] init];
-streamParam.type = EMStreamTypeDesktop;
-streamParam.desktopView = self.view;
-[[EMClient sharedClient].conferenceManager publishConference:self.conference
- streamParam:streamParam
- completion:^(NSString *aPubStreamId, EMError *aError) {
-
-}];
-```
-
-因为上面方法的实现原理是不停的截取指定view的快照,并转换成流发送,这种方式的效率并不高,ios10以上用户建议使用系统的replaykit + 自定义输入流的方式实现共享桌面,具体replaykit使用可以参考[官方文档](https://developer.apple.com/documentation/replaykit?language=objc)
-
-(需要集成3.6.3或以上版本的sdk)
-
-特别指出,如果需要在共享桌面时输入自己的流,需要修改上一步中的设置:
-
-```
-EMStreamParam *streamParam = [[EMStreamParam alloc] init];
-streamParam.type = EMStreamTypeDesktop;
-streamParam.desktopView = nil; // 使用自定义输入流,此处需要传nil
-streamParam.videoResolution = EMCallVideoResolution_Custom;//为了防止共享桌面被裁剪,需要使用自定义分辨率
-CGFloat screenX = [UIScreen mainScreen].bounds.size.width;
-CGFloat screenY = [UIScreen mainScreen].bounds.size.height;
-streamParam.videoWidth = screenY*[UIScreen mainScreen].scale;
-streamParam.videoHeight = screenX*[UIScreen mainScreen].scale;
-
-[[EMClient sharedClient].conferenceManager publishConference:self.conference
- streamParam:streamParam
- completion:^(NSString *aPubStreamId, EMError *aError) {
- if(!aError) {
- publishId = aPubStreamId;
- }
-}];
-
-// 输入视频流
-[[EMClient sharedClient].conferenceManager inputVideoSampleBuffer:sampleBuffer
- rotation:orientation
- conference:self.conference
- publishedStreamId:publishId
- completion:^(EMError *aError) {
-
-}];
-```
-
-#### **水印**
-
-视频通话时,可以添加图片作为水印,添加时使用[IEMConferenceManager addVideoWatermark]接口,需要指定水印图片的NSUrl,添加位置参见[EMWaterMarkOption](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_water_mark_option.html)。
-
-清除水印使用[IEMConferenceManager clearVideoWatermark]接口。
-
-显示remoteVideo需要使用EMCallViewScaleModeAspectFit模式,否则对方的水印设在边缘位置可能显示不出来。
-
-```
-/*!
-* \~chinese
-* 开启水印功能
-*
-* @param option 水印配置项,包括图片URL,marginX,marginY以及起始点
-*/
-- (void)addVideoWatermark:(EMWaterMarkOption*)option;
-/*!
-* \~chinese
-* 取消水印功能
-*
-*/
-- (void)clearVideoWatermark;
-// 添加水印
-NSString * imagePath = [[NSBundle mainBundle] pathForResource:@"watermark" ofType:@"png"];
-EMWaterMarkOption* option = [[EMWaterMarkOption alloc] init];
-option.marginX = 60;
-option.startPoint = LEFTTOP;
-option.marginY = 40;
-option.enable = YES;
-option.url = [NSURL fileURLWithPath:imagePath];
-[[EMClient sharedClient].conferenceManager addVideoWatermark:option];
-
-// 清除水印
-[[EMClient sharedClient].conferenceManager clearVideoWatermark];
-```
-
-### 角色管理
-
-#### **观众申请主播**
-
-会议中的观众角色可以向管理员发申请成为主播,管理员可以选择同意或者拒绝。观众申请主播的接口需要管理员的memId,先通过获取会议属性接口获取到管理员的memName,然后根据memName以及成员加入的回调中获取到的EMCallMember,获取到memId。接口如下:
-
-```
-/*!
-* \~chinese
-* 观众申请连麦成为主播,观众角色调用
-*
-* @param aCall 会议实例(自己创建的无效)
-* @param aAdminId 管理员的memId
-* @param aCompletionBlock 回调函数
-*/
-- (void)requestTobeSpeaker:(EMCallConference *)aCall adminId:(NSString *)aAdminId completion:(void (^)(EMError *aError))aCompletionBlock;
-```
-
-观众发出申请后,管理员将会收到以下回调:
-
-```
-/*!
- * \~chinese
- * 收到观众申请主播的请求,只有管理员会触发
- *
- * @param aConference 会议
- * @param aMemId 申请人memId
- * @param aNickName 申请人昵称
- * @param aMemName 申请人memName
-*/
-- (void)conferenceReqSpeaker:(EMCallConference*)aConference memId:(NSString*)aMemId nickName:(NSString*)aNickName memName:(NSString*)aMemName;
-```
-
-在回调中,管理员可以选择同意或者拒绝,如果同意,需要调用接口changeMemberRoleWithConfId授权,然后回复申请人;如果拒绝,则直接调用回复接口。回复接口如下:
-
-```
-/*!
-* \~chinese
-* 管理员同意/拒绝观众的上麦申请,管理员调用
-*
-* @param aCall 会议实例(自己创建的无效)
-* @param aMemId 上麦申请的观众的memId
-* @param aResult 操作结果,0为同意,1为拒绝
-* @param aCompletionBlock 回调函数
-*/
-- (void)responseReqSpeaker:(EMCallConference *)aCall
- memId:(NSString *)aMemId
- result:(NSInteger)aResult
- completion:(void (^)(EMError *aError))aCompletionBlock;
-```
-
-#### **主播申请管理员**
-
-会议中的主播角色可以向管理员发申请成为管理员,管理员可以选择同意或者拒绝,成为管理员后,各管理员之间的权限是相同的。主播申请管理员的接口需要管理员的memId,先通过获取会议属性接口获取到管理员的memName,然后根据memName以及成员加入的回调中获取到的EMCallMember,获取到管理员memId,调用接口changeMemberRoleWithConfId授权,然后回复申请人,接口如下:
-
-```
-/*!
-* \~chinese
-* 主播申请成为管理员,主播角色调用
-*
-* @param aCall 会议实例(自己创建的无效)
-* @param aAdminId 管理员的memId
-* @param aCompletionBlock 回调函数
-*/
-- (void)requestTobeAdmin:(EMCallConference *)aCall adminId:(NSString *)aAdminId completion:(void (^)(EMError *aError))aCompletionBlock;
-```
-
-主播发出申请后,管理员将会收到以下回调:
-
-```
-/*!
- * \~chinese
- * 收到主播申请管理员的请求,只有管理员会触发
- *
- * @param aConference 会议
- * @param aMemId 申请人memId
- * @param aNickName 申请人昵称
- * @param aMemName 申请人memName
-*/
-- (void)conferenceReqAdmin:(EMCallConference*)aConference memId:(NSString*)aMemId nickName:(NSString*)aNickName memName:(NSString*)aMemName;
-```
-
-在回调中,管理员可以选择同意或者拒绝,如果同意,需要调用改变用户权限的接口changeMemberRoleWithConfId,然后调用回复接口;如果拒绝,则直接调用回复接口。回复接口如下:
-
-```
-/*!
-* \~chinese
-* 管理员同意/拒绝主播的申请管理员请求,管理员调用
-*
-* @param aCall 会议实例(自己创建的无效)
-* @param aMemId 申请管理员的主播的memId
-* @param aResult 操作结果,0为同意,1为拒绝
-* @param aCompletionBlock 回调函数
- */
-- (void)responseReqAdmin:(EMCallConference *)aCall memId:(NSString *)aMemId result:(NSInteger)aResult completion:(void (^)(EMError *aError))aCompletionBlock;
-```
-
-管理员对其他观众、主播的角色进行升级、降级处理的接口如下:
-
-aMemberName 是appkey拼接环信id,例如:easemob-demo#chatdemoui_lulu1
-
-**管理员/主播也可以直接使用该接口对自己进行降级**
-
-```
-/*!
-* \~chinese
-* 改变成员角色,需要管理员权限
-* 用户角色: Admin > Talker > Audience
-* 当角色升级时,用户需要给管理员发送申请,管理通过该接口改变用户接口.
-* 当角色降级时,用户直接调用该接口即可.
-*
-* @param aConfId 会议ID(EMCallConference.confId)
-* @param aMemberName 成员在会议中的memName
-* @param aRole 成员角色
-* @param aCompletionBlock 完成的回调
-*/
-- (void)changeMemberRoleWithConfId:(NSString *)aConfId
- memberName:(NSString *)aMemberName
- role:(EMConferenceRole)toRole
- completion:(void (^)(EMError *aError))aCompletionBlock;
-```
-
-#### **管理员踢人**
-
-管理员可以强制会议成员离开会议,使用接口:
-
-```
-/*!
- * \~chinese
- * 踢人,需要管理员权限
- *
- * @param aConfId 会议ID(EMCallConference.confId)
- * @param aMemberNameList 成员名列表
- * @param aCompletionBlock 完成的回调
- */
-- (void)kickMemberWithConfId:(NSString *)aConfId
- memberNames:(NSArray *)aMemberNameList
- completion:(void (^)(EMError *aError))aCompletionBlock;
-```
-
-#### 全体静音/指定成员静音
-
-该系列接口调用需要加入会议后,先获取一下会议信息,调用getConference接口。
-
-##### **全体静音**
-
-管理员可以对会议进行全体静音/解除全体静音设置,设置后,会议中的主播都将处于静音状态,新加入的主播也将自动处于静音状态。只有管理员可以调用此接口。 接口API如下:
-
-```
-/**
-* \~chinese
-* 开启/停止全体静音,只有管理员可调用此接口
-*
-* @param enable 是否启用全体静音
-* @param completion 回调
-*/
-- (void)muteAll:(BOOL)mute
- completion:(void(^)(EMError *aError))aCompletionBlock;
-```
-
-管理员调用此接口后,会议中的主播将收到全体静音状态的回调,回调函数如下:
-
-```
-/*!
- * \~chinese
- * 收到全体静音/解除全体静音的回调
- *
- * @param aConference 会议
- * @param aMuteAll 是否全体静音
-*/
-- (void)conferenceDidUpdated:(EMCallConference *)aConference
- muteAll:(BOOL)aMuteAll;
-```
-
-##### **指定成员静音**
-
-管理员可以对会议中的指定成员进行静音/解除静音设置,被指定成员可以是主播也可以是管理员。设置后,被指定成员将静音/解除静音。只有管理员可以调用此接口。 接口API如下:
-
-```
-/*!
-* \~chinese
-* 将指定成员静音/解除静音,管理员调用
-*
-* @param aCall 会议实例(自己创建的无效)
-* @param aMemId 指定成员的memId
-* @param aMute 操作,YES为静音,NO为解除静音
-* @param aCompletionBlock 回调函数
-*/
-- (void)setMuteMember:(EMCallConference *)aCall
- memId:(NSString *)aMemId
- mute:(BOOL)aMute
- completion:(void (^)(EMError *aError))aCompletionBlock;
-```
-
-管理员调用此接口后,被指定的成员将收到静音状态的回调,回调函数如下:
-
-```
-/*!
- * \~chinese
- * 收到静音/解除静音的回调
- *
- * @param aConference 会议
- * @param aMute 是否静音
-*/
-- (void)conferenceDidUpdated:(EMCallConference*)aConference
- mute:(BOOL)aMute;
-```
-
-#### **本身角色变更回调**
-
-当成员本身的角色发生变化时,收到以下回调:
-
-```
-/*!
- * \~chinese
- * 自己的角色发生变化
- *
- * @param aConference 会议实例
- */
-- (void)roleDidChanged:(EMCallConference *)aConference;
-```
-
-#### **管理员变更回调**
-
-当会议中的普通成员成为管理员,或管理员降级为普通成员时,会议中的其他成员将收到管理员变更的回调。管理员变更回调分为管理员新增和管理员移除,回调接口如下:
-
-```
-/*!
- * \~chinese
- * 管理员新增
- *
- * @param aConference 会议实例
- * @param adminmemid 新的管理员memid
- */
-- (void)adminDidChanged:(EMCallConference *)aConference
- newAdmin:(NSString*)adminmemid;
-
-/*!
- * \~chinese
- * 管理员放弃
- *
- * @param aConference 会议实例
- * @param adminmemid 放弃管理员的memid
- */
-- (void)adminDidChanged:(EMCallConference *)aConference
- removeAdmin:(NSString*)adminmemid;
-```
-
-## 客户端API
-
-多人音视频通话的API包括以下接口:
-
-- EMCallOption 多人音视频通话配置类
-- EMConferenceManager 是多人音视频通话的主要管理类,提供了加入会议、退出、发流、订阅等接口
-- EMConferenceManagerDelegate 是多人音视频通话的监听回调类,多人音视频通话相关的回调
-- EMCallConference 多人音视频通话的会议实例接口
-
-### EMCallOption
-
-| 属性 | 描述 |
-| :----------------------------------------------------------- | :-------------------------------- |
-| [maxAudioKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#aea45547ce623a0fd5d53a36f00334520) | 最大音频码率 |
-| [maxVideoKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a4130c8f7488d6d6f58c3783dc63be5fd) | 最大视频码率 |
-| [minVideoKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#ae070e260597c913634a21c03aa31826a) | 最小视频码率 |
-| [maxVideoFrameRate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a45f020f84b4513fdc0cb3f8a123fe678) | 最大视频帧率 |
-| [videoResolution](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#af49ac4f01b9bca538fbce40e1de5f866) | 视频分辨率 |
-| [enableReportQuality](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#af2129acdd0d3d73a583e8d37dfc087e2) | 是否监听通话质量 |
-| [enableCustomAudioData](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#ae927cb60d05c59b389517648941e7ec8) | 是否使用自定义音频数据 |
-| [audioCustomSamples](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a76482a8e2702e1905c036142e41c8a6d) | 自定义音频数据的采样率,默认48000 |
-| [enableCustomizeVideoData](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a89f38b15e05ed5d6636af5fde628d114) | 是否使用自定义视频数据 |
-| [isClarityFirst](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a38497058ab86b80f156ba3b362100b4e) | 是否清晰度优先 |
-
-### EMConferenceManager
-
-| 方法 | 描述 |
-| :----------------------------------------------------------- | :---------------------------------------------- |
-| [addDelegate:delegateQueue:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a2b985523160a8a9f47346e1065667dfb) | 添加回调代理 |
-| [removeDelegate:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#acc88916806c943608d41c307012d2113) | 移除回调代理 |
-| [setAppkey:username:token:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a16c1d9b53642b97e07e6ae1c55925519) | 设置应用Appkey, 环信ID, 环信ID对应的Token |
-| [getConference:password:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a53da60e7a584697191b52734c4517669) | 获取会议信息 |
-| [createAndJoinConferenceWithType:password:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a838273c88e5264cbf0508de0d0e3aeef) | 创建并加入会议 |
-| [createAndJoinConferenceWithType:password:confrConfig:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a0f5820f9c560ca0a6ccfee963c423185) | 创建并加入会议 |
-| [joinConferenceWithConfId:password:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#acead28618cffee8a9068897bbb238df8) | 加入已有会议 |
-| [joinConferenceWithTicket:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a1a81bcafde9fa0d9a826a80dee15f981) | 加入已有会议 |
-| [joinRoom:password:role:roomConfig:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a9dc56f6f8c505322baff4074964640d8) | 加入房间 |
-| [publishConference:streamParam:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a45cb75e64fd0abd04d71ae7cbaa39668) | 上传音视频数据流 |
-| [unpublishConference:streamId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ab80d817ea9953a75d59284bece48e7ac) | 取消上传本地音视频数据流 |
-| [subscribeConference:streamId:remoteVideoView:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a5bc905bb6427f586c18ea6a3b87fb58a) | 订阅其他人的数据流 |
-| [unsubscribeConference:streamId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#af95a48dc945a95062e868db32615b1d0) | 取消订阅的数据流 |
-| [changeMemberRoleWithConfId:memberName:role:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ac6df4fd1e2b16c98e4f515d45aa08d21) | 改变成员角色,需要管理员权限 |
-| [kickMemberWithConfId:memberNames:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a094785f9b5ee245226399234bd72fe58) | 踢人,需要管理员权限 |
-| [destroyConferenceWithId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ac3c7426a3b6dc1b50bad419d2f722ee8) | 销毁会议,需要管理员权限 |
-| [leaveConference:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ae54239e73e21df83450961a8263a14f7) | 离开会议 |
-| [startMonitorSpeaker:timeInterval:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28726fcdc8ce28006a30d713f40227c0) | 开始监听说话者 |
-| [stopMonitorSpeaker:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#aa67291522b649278e770c7bb1b3ee9b3) | 结束监听说话者 |
-| [updateConference:liveId:setRegions:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a00098d155bc5b6b8a0941f2b7b140b3f) | 修改会议的cdn推流布局 |
-| [addConferenceLive:LiveCfg:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ad36907936af8fcf74f64cd311d6456c7) | 添加一路推流 |
-| [enableRecordLiveStream:liveId:enabled:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a391e86342e05c90345c6f0594008c368) | 启动/停止自定义录制 |
-| [deleteConferenceLive:liveId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ad879b9caafabcfcbc271e5e23937805a) | 删除一路推流 |
-| [requestTobeSpeaker:adminId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a94e5010c1349d40fddde33b7cc489274) | 观众申请连麦成为主播 |
-| [requestTobeAdmin:adminId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#af2e99d266d5d3f67490903b17818b17c) | 主播申请成为管理员, |
-| [responseReqSpeaker:memId:result:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a097c52f9ea833b9ac289290247c25860) | 管理员同意/拒绝观众的上麦申请,管理员调用 |
-| [responseReqAdmin:memId:result:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a34ff57a1a78c507d5118249e4863b8ff) | 管理员同意/拒绝主播的申请管理员请求,管理员调用 |
-| [setMuteMember:memId: mute:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a6432c2f2a68760b1cad2dabb6e9cba6d) | 将指定成员静音/解除静音,管理员调用 |
-| [updateConferenceWithSwitchCamera:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28bd7490cb8e238a07a5aec62d164cea) | 切换前后摄像头 |
-| [updateConference:isMute:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#abc3d1658875a99bdd1f5f1158a74e789) | 设置是否静音 |
-| [updateConference:enableVideo:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a478c1c8b08758a55fdea520d6772ae9e) | 设置视频是否可用 |
-| [updateConference:maxVideoKbps:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ab57a72f199fa779b7b3158712e2d0a0a) | 更新视频最大码率 |
-| [inputVideoSampleBuffer:rotation:conference:publishedStreamId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#af906e2f6de9ca0d9005bf6c46c9d46e8) | 输入自定义本地视频数据 |
-| [inputVideoPixelBuffer:sampleBufferTime:rotation:conference:publishedStreamId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a544a757e0f2a16c9b265243c784f1fd4) | 输入自定义本地视频数据 |
-| [setConferenceAttribute:value:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ae98d762cb6aed35de22da40779455fcb) | 设置会议属性, |
-| [deleteAttributeWithKey:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a226dbe5816201a32fa3850dd1bb3c991) | 删除频道属性 |
-| [startAudioMixing: loop:sendMix:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#aa7e7d1a088f746f98b796d94b3eb631d) | 开启本地伴音功能 |
-| [stopAudioMixing](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a703c15925f723cc3c4ec59f347226a91) | 关闭本地混音功能 |
-| [adjustAudioMixingVolume:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a9b9a168a7e160ff08b5ccf13d2b8ab2f) | 设置伴奏音量 |
-| [muteRemoteAudio: mute:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28f9297ad2411c6aa9bdbb291bb8df26) | mute远端音频 |
-| [muteRemoteVideo: mute:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a870a36303635529c953194b9d240521b) | mute远端视频 |
-| [enableStatistics:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#aa57d7c7aaec58f84fb0f81b38f36a2e4) | 启用统计 |
-| [muteAll:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a0a7340e4fe935143ba0ff529858ad295) | 全体静音 |
-| [inputCustomAudioData:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a2fb9faf9d767ed2e58315c1db354df37) | 输入自定义外部音频数据 |
-| [addVideoWatermark:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a64ed13e19b65e3c8fb06113a96da37c5) | 开启水印功能 |
-| [clearVideoWatermark](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a950faf99db0d40e2a89c62fd8113f34d) | 取消水印功能 |
-
-### EMConferenceManagerDelegate
-
-| 回调事件 | 描述 |
-| :----------------------------------------------------------- | :----------------------------------------------------------- |
-| [memberDidJoin:member:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a35ae6bcf830548162cc9c7e6f6df0cd8) | 有人加入会议 |
-| [memberDidLeave:member:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a2349384a054912620858346dff81eb41) | 有人离开会议 |
-| [roleDidChanged:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ada8c07dac796d492a5165b28b50fb02c) | 自己的角色发生变化 |
-| [adminDidChanged:newAdmin:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a0532f12f9e7ae6cf5f7837793062f4ea) | 管理员新增 |
-| [adminDidChanged:removeAdmin:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a56cc91df21df41aad12e33940bff987c) | 管理员放弃 |
-| [streamPubDidFailed:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a99ce878eb647a0ae04b8de3829e41f9b) | 本地pub流失败 |
-| [DesktopStreamDidPubFailed:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a3d7f3ca91389d95c6fe29f15d3d41fbb) | 发布共享桌面流失败 |
-| [streamUpdateDidFailed:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a0ac987ff2ecb9e34dc786f1da50466df) | 本地update流失败,视频超限 |
-| [streamDidUpdate:addStream:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#aaec86cf13eaa8930fa5261c1f3848785) | 有新的数据流上传 |
-| [streamDidUpdate:stream:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#adee2f6109508e383000d5e99e33b9bde) | 数据流有更新(是否静音,视频是否可用) |
-| [streamDidUpdate:removeStream:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a4a92350f846d00e913c48a3286e9da77) | 有数据流移除 |
-| [conferenceDidEnd:reason:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a9e35574e2e6fcedcc5cf3d4f0f9a26e6) | 会议已经结束 |
-| [streamStartTransmitting:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a37025ed1fda0ff26798c31aabbcf7105) | 数据流已经开始传输数据 |
-| [conferenceDidUpdated:muteAll:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a2db2fd8d67522325ecb8412479842ccd) | 收到全体静音/解除全体静音的回调 |
-| [conferenceSpeakerDidChange:speakingStreamIds:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a0917065a18ca3ce9433d6677288830c3) | 用户A用户B在同一个会议中,用户A开始说话时,用户B会收到该回调 |
-| [conferenceAttributeUpdated:attributes:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a0917065a18ca3ce9433d6677288830c3) | 会议属性变更 |
-| [conferenceReqSpeaker:memId:nickName:memName:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#afca1af08d628fd0be0ddd1bed1bf9138) | 收到观众申请主播的请求,只有管理员会触发 |
-| [conferenceReqAdmin:memId:nickName:memName:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ad90e5d598c1b8cb57a02cd6b81fc929e) | 收到主播申请管理员的请求,只有管理员会触发 |
-| [conferenceDidUpdated: mute:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a2b09dd5dbb6144cc561027378bc3f1e7) | 收到静音/解除静音的回调 |
-| [conferenceReqSpeakerRefused:adminId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ae598e6c668121780573ce2402be3d745) | 收到申请主播请求被拒绝的回调 |
-| [conferenceReqAdminRefused:adminId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#aa285cef35bc14db40ef17be9245798ed) | 收到申请管理员请求被拒绝的回调 |
-| [conferenceDidUpdated:liveCfg:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#acccb25d9f4eef388781be85cfeefb5ff) | 会议开启cdn推流或自定义录制,收到LiveCfg的回调,只有管理员能收到 |
-| [streamIdDidUpdate:rtcId:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#adde6567323a5ffaf249841da585174b8) | 收到本地流streamId的回调,发布流成功后收到此回调 |
-| [streamStateUpdated:type:state:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#aff906c9db5f6be3685a44e5c83d0ca0e) | 下行音频流无数据时,收到此回调 |
-| [streamDidFirstFrameSended:type:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ab7ce7a7c76c5dca0918c8f8b5875b5e9) | 发送第一帧音视频数据时,收到此回调 |
-| [streamDidFirstFrameReceived:type:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a1879f50eea95cdabbf0e265bc1a03fef) | 接收流第一帧音视频数据时,收到此回调 |
-| [confrenceDidUpdated:state:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ac03c8bd548fd6ae0623eb0b6f99f8b80) | 会议状态改变时,收到此回调 |
-| [onferenceDidUpdate:streamId:statReport:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a8940c01890169f6c5a68f8d6787264e9) | 当前会议的媒体流质量报告回调 |
-
-### EMCallConference
-
-参见http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_conference.html
\ No newline at end of file
diff --git a/docs/private/media/conference_pcdesktop.md b/docs/private/media/conference_pcdesktop.md
deleted file mode 100644
index e288e50a..00000000
--- a/docs/private/media/conference_pcdesktop.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# PC桌面集成多人通话
-
-## Demo下载
-
-windows: [下载](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/rtcdemo/%E7%8E%AF%E4%BF%A1%E8%A7%86%E9%A2%91%E4%BC%9A%E8%AE%AE.2.0.1.win.setup.exe)
-
-macOS: [下载](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/rtcdemo/%E7%8E%AF%E4%BF%A1%E8%A7%86%E9%A2%91%E4%BC%9A%E8%AE%AE.2.0.1.mac.dmg)
-
-## 技术实现:
-
-外部使用 [electorn.js教程](http://www.electronjs.org/)包装
-
-内部load web 端页面
-
-参考 [Web集成多人通话](conference_web.html)
\ No newline at end of file
diff --git a/docs/private/media/conference_uniapp.md b/docs/private/media/conference_uniapp.md
deleted file mode 100644
index f1176761..00000000
--- a/docs/private/media/conference_uniapp.md
+++ /dev/null
@@ -1,485 +0,0 @@
-# uni-app集成多人音视频通话
-
-## 前言
-
-[uni-app](https://uniapp.dcloud.io/README)是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台,uni-app需要使用[hbuilderX](https://www.dcloud.io/hbuilderx.html)进行开发。
-
-环信为用户使用uni-app开发原生应用并拥有音视频功能,特别提供了适配uni-app的音视频SDK和[uni-app原生插件](https://ext.dcloud.net.cn/plugin?id=3507),用户可以集成后快速在android和ios原生客户端使用音视频功能。
-
-:::tip
-目前音视频插件仅支持运行在iOS以及Android,暂不支持运行在微信小程序使用。如需运行到微信小程序我们为此提供了小程序音视频SDK,请移步小程序集成多人音视频文档部分。
-:::
-使用 uni-app 集成多人音视频SDK,需要下载环信uni-app原生插件**emlive-pusher**、**emlive-player**配合一起使用。音视频SDK依赖IM SDK, 所以要先集成IM,并把IM SDK实例挂载在全局变量下:uni.WebIM = websdk, 可以参考[uni-app demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webim-uniapp-demo.zip) utils/WebIM 文件。
-
-------
-
-## 运行demo
-
-下载好[uni-app demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webim-uniapp-demo.zip)后,导入hbuilderX,需要检查manifest.json/原生插件配置中是否选中了插件,否则需要自己选择nativeplugins中的EMLiveplugin插件,然后点击hbuilderX的运行→运行到手机或模拟器→制作自定义调试基座。 此时hbuilderX会进行打包,等打包成功后,点击运行→运行到手机或模拟器→运行基座选择→自定义调试基座,选择好后重新点击运行→运行到手机或模拟器→找到自己的设备 等安装好后,就可以在群组聊天中点击电话的icon,发起多人会议。
-
-------
-
-## uniapp音视频插件
-
-### 导入插件
-
-在[插件市场](https://ext.dcloud.net.cn/plugin?id=3507)下载好插件后,放到uniapp工程的nativeplugins目录下,如果没有此目录需要自己创建。导入好插件后需要在工程目录manifest.json中选择:App原生插件配置/本地插件中选择刚导入的插件[EMLivePlugin(适用平台: Android,IOS)],最后需要在hbuilderX上选择: 运行→运行到手机或模拟器→制作自定义调试基座,这样插件就导入成功了,下次运行时在运行→运行到手机或模拟器→运行基座选择中选择自定义调试基座。
-
-### 插件参数说明
-
-**emlive-pusher**插件参数说明:
-
-| 属性名称 | 类型 | 描述 |
-| :-------------- | :---------- | :----------------------------------------------------------- |
-| ref | string | 页面根据ref找到该组件 |
-| style | string | 组件样式,参考原生组件支持样式 |
-| muted | boolean | 是否静音 |
-| enableCamera | boolean | 是否打开摄像头 |
-| devicePosition | string | 默认使用摄像头,front为前置,back为后置 |
-| videoWidth | number | 视频分辨率宽 |
-| videoHeight | number | 视频分辨率高 |
-| minBitrate | number | 最小视频码率 |
-| maxBitrate | number | 最大视频码率 |
-| mirror | boolean | 是否镜像,Android独有,iOS没有 |
-| objectFit | string | 填充方式,fit和fill |
-| isClarityFirst | boolean | 是否清晰度优先 |
-| rtcLogToConsole | boolean | 是否将Rtc日志输出到控制台 |
-| bindstatechange | eventhandle | 状态变化事件,detail={code, info} |
-| bindnetstatus | eventhandle | 网络状态通知,detail={code, info} |
-| callbackData | eventhandle | 数据回调通知,需要将回调出来的数据传给SDK |
-| callbackStats | eventhandle | 通话质量统计,detail={data},data为通话质量数据,包括视频分辨率、码率、丢包率等 |
-
-示例代码:
-
-```
-
- ref="livePlayer"
- style="width:350px;height:300px"
- :muted="false"
- :enable-camera="true"
- object-fit="fill"
- :rtcLogToConsole="true"
- @bindstatechange="onStateChange"
- @bindnetstatus="onNetStatusChange"
- @callbackData="onData"
- @callbackStats="onStats">
-
-```
-
-**emlive-player**插件参数说明:
-
-| 属性名称 | 类型 | 描述 |
-| :-------------- | :---------- | :----------------------------------------------------------- |
-| ref | string | 页面根据ref找到该组件 |
-| style | string | 组件样式,参考原生组件支持样式 |
-| muted | boolean | 是否静音 |
-| enableCamera | boolean | 是否打开视频 |
-| openSpeaker | boolean | 是否打开扬声器 |
-| objectFit | string | 填充方式,fit和fill |
-| rtcLogToConsole | boolean | 是否将Rtc日志输出到控制台 |
-| bindstatechange | eventhandle | 状态变化事件,detail={code, info} |
-| bindnetstatus | eventhandle | 网络状态通知,detail={code, info} |
-| callbackData | eventhandle | 数据回调通知,需要将回调出来的数据传给SDK |
-| callbackStats | eventhandle | 通话质量统计,detail={data},data为通话质量数据,包括视频分辨率、码率、丢包率等 |
-
-示例代码:
-
-```
-
- ref="livePlayer"
- style="width:350px;height:300px"
- :muted="false"
- :enable-camera="true"
- object-fit="fill"
- :rtcLogToConsole="true"
- @bindstatechange="onStateChange"
- @bindnetstatus="onNetStatusChange"
- @callbackData="onData"
- @callbackStats="onStats">
-
-```
-
-**bindstatechange**回调参数说明:
-
-| code值 | info | 描述 |
-| :----- | :-------------------------------- | :----------------- |
-| 2000 | RTCIceConnectionStateNew | 建立流媒体链接 |
-| 2001 | RTCIceConnectionStateChecking | 检测流媒体连接状态 |
-| 2002 | RTCIceConnectionStateConnected | 流媒体连接成功 |
-| 2003 | RTCIceConnectionStateCompleted | 流媒体连接过程完成 |
-| 2004 | RTCIceConnectionStateFailed | 流媒体连接失败 |
-| 2005 | RTCIceConnectionStateDisconnected | 流媒体断开连接 |
-| 2006 | RTCIceConnectionStateClosed | 流媒体关闭连接 |
-| 2102 | receive first audio frame | 接收到音频首帧 |
-| 2102 | receive first audio frame | 接收到音频首帧 |
-| 2103 | receive first video frame | 接收到视频首帧 |
-| 2104 | audio has no data | 音频无数据 |
-| 2105 | video has no data | 视频无数据 |
-
-**bindnetstatus**回调参数说明:
-
-| code值 | info | 描述 |
-| :----- | :--------------- | :--------- |
-| 4000 | net connected | 网络已连接 |
-| 4001 | net poor quality | 网络不稳定 |
-| 4002 | net disconnected | 网络已断开 |
-
-------
-
-## 音视频SDK集成
-
-uniapp音视频SDK的集成和微信小程序音视频SDK的集成类似,主要分为以下几个步骤:
-
-- 1、引入SDK
-- 2、创建会议
-- 3、自己加入会议并发出邀请(邀请方式为:发送携带会议信息的邀请信息,可以是文本消息亦可以是自定义消息等方式。)
-- 4、发布自己的音视频流
-- 5、其他人收到邀请加入会议
-- 6、其他人发布音视频流
-- 7、监听SDK onMemberJoined、onStreamAdded事件,收到其他人的流之后订阅流
-- 8、监听插件 callbackData、bindstatechange事件,将数据传给SDK
-- 9、显示画面
-- 10、退出会议
-
-------
-
-### 引入SDK
-
-SDK下载地址:
-
-- 通过github[仓库地址]()
-
-音视频SDK在emediaSDK/emedia_for_miniProgram.js
-
-引入:
-
-```
-let emedia = uni.emedia = require("./emediaSDK/emedia_for_miniProgram");
- emedia.config({useUniappPlugin: true}) // 设置使用uniapp插件
-```
-
-------
-
-### 创建会议
-
-调用createConference创建会议,示例代码:
-
-```
-/**
- * @param {number} confrType - 会议类型, 建议使用 10
- * @param {string} password - 会议密码
- * @param {boolean} rec - 是否录制
- * @param {boolean} recMerge 是否合并录制
- */
-uni.emedia.mgr.createConference(confrType, password, rec, recMerge).then( (data) => {
- let ticket = data.data.ticket
- let ticketJosn = JSON.parse(ticket)
- let confrId = ticketJosn.confrId
-})
-```
-
-------
-
-### 加入会议
-
-调用joinConference加入会议,示例代码:
-
-```
-/**
- * @param {string} confrId - 会议id
- * @param {string} password - 会议密码
- */
-uni.emedia.mgr.joinConference(confrId, password)
-```
-
-------
-
-### 发布流
-
-调用publish加入会议,示例代码:
-
-```
-/**
- * @param {string} confrId - 会议id
- * @param {object} livePusher - emlivePusher 插件
- */
-uni.emedia.mgr.publish(confrId, this.$refs.livePusher)
-```
-
-------
-
-### 监听有人加入会议
-
-使用onMemberJoined监听有人加入会议,示例代码:
-
-```
-uni.emedia.mgr.onMemberJoined = function(member){
- // member 人员信息
-}
-```
-
-------
-
-### 监听有媒体流加入
-
-使用onStreamAdded回调监听有媒体流加入,示例代码:
-
-```
-uni.emedia.mgr.onStreamAdded = function(stream) {
- // stream 媒体流
-}
-```
-
-------
-
-### 订阅流
-
-调用subscribe订阅媒体流,示例代码:
-
-```
-/**
- * @prama {string} confrId - 会议id
- * @prama {object} stream - 媒体流
- * @prama {object} livePlayer - emlivePlayer 插件
- */
-uni.emedia.mgr.subscribe(confrId, stream, this.$refs.livePlayer)
-```
-
-------
-
-### 将插件数据传给SDK
-
-将插件callbackData 和 bindstatechange 返回的数据传给SDK,示例代码:
-
-```
-
-
- ref="livePusher"
- objectFit="fill"
- :videoWidth="640"
- :videoHeight="480"
- :muted="muted"
- :enableCamera="enableCamera"
- :devicePosition="devicePosition"
- :rtcLogToConsole="true"
- @bindnetstatus="netstatus"
- @bindstatechange="statechange"
- @callbackData="onData"
- >
-
-
-
- ref="livePlayer"
- objectFit="fit"
- @bindstatechange="playerStateChange"
- @bindnetstatus="playerNetChange"
- :muted="false"
- :enableCamera="true"
- :openSpeaker="openSpeaker"
- @callbackData="onPlayerData"
- >
-
-// script
-onData(data){
- uni.emedia.mgr.postMessage(confrId, data, this.$refs.livePusher)
-}
-onPlayerData(data){
- uni.emedia.mgr.postMessage(confrId, data, this.$refs.livePlayer)
-}
-statechange(state){
- uni.emedia.mgr.onStateChange(state)
-}
-```
-
-------
-
-## SDK APIs
-
-### 常量
-
-```
-// 会议类型
-emedia.mgr.ConfrType = {
- COMMUNICATION: 10, //普通会议模式
- COMMUNICATION_MIX: 11, //大会议模式
- LIVE: 12, //直播模式
-};
-
-// 角色
-emedia.mgr.Role = {
- ADMIN: 7, //管理员(可推送视频、可解散会议、可踢人、可变更其他人角色,会议创建者默认为管理员)
- TALKER: 3, // 主播(可发言、可观看)
- AUDIENCE: 1 // 观众(仅可以观看)
-};
-```
-
-### APIs
-
-1、创建会议
-
-```
-/**
- * @method createConference 创建会议
- * @param {string} confrType - 会议类型
- * @param {string} password - 会议密码
- * @param {boolean} rec - 是否录制 默认false
- * @param {boolean} recMerge - 是否合并 默认false
- */
-emedia.mgr.createConference(confrType, password, rec, recMerge)
-```
-
-2、加入会议
-
-```
-/**
- * @method joinConference 加入会议
- * @param {string} confrId - 会议id
- * @param {string} password - 会议密码
- */
-uni.emedia.mgr.joinConference(confrId, password)
-```
-
-3、发布流
-
-```
-/**
- * @method publish 发布流
- * @param {string} confrId - 会议id
- * @param {object} livePusher - emlivePusher 插件
- */
-uni.emedia.mgr.publish(confrId, this.$refs.livePusher)
-```
-
-4、订阅流
-
-```
-/**
- * @method publish 订阅流
- * @param {string} confrId - 会议id
- * @param {object} livePusher - emlivePusher 插件
- */
-uni.emedia.mgr.subscribe(confrId, stream, this.$refs.livePlayer)
-```
-
-5、把插件callbackData返回的数据传给SDK
-
-```
-/**
- * @method postMessage 把插件数据传给SDK
- * @param {string} confrId - 会议id
- * @param {object} data - 插件会烦数据
- * @param {object} emlivePlugin - emlivePusher 或者 emlivePlayer
- */
-uni.emedia.mgr.postMessage(confrId, data, emlivePlugin)
-```
-
-6、将插件bindstatechange返回的数据传给SDK
-
-```
-/**
- * @method onStateChange 把插件state数据传给SDK
- * @param {object} state - 插件状态
- */
-uni.emedia.mgr.postMessage(state)
-```
-
-7、退出会议
-
-```
-/**
- * @method exitConference 退出会议
- * @param {string} confrId - 会议id
- */
-uni.emedia.mgr.exitConference(confrId)
-```
-
-8、解散会议
-
-```
-/**
- * @method destroyConference 解散会议
- * @param {string} confrId - 会议id
- */
-uni.emedia.mgr.destroyConference(confrId)
-```
-
-9、踢人
-
-```
-/**
- * @method kickMembersById 解散会议
- * @param {string} confrId - 会议id
- * @param {Array} memberNames 踢出的人
- */
-uni.emedia.mgr.kickMembersById(confrId, memberNames)
-```
-
-10、改变角色
-
-```
-/**
- * @method grantRole 改变角色
- * @param {string} confrId 会议id
- * @param {Array} memberNames 人员
- * @param {string} role 角色
- */
-emedia.mgr.grantRole(confrId, memberNames, role)
-```
-
-### 回调
-
-1、有人加入会议,已经在会议中的人将会收到回调
-
-```
-emedia.mgr.onMemberJoined = function (member) {};
-```
-
-2、有人退出会议,已经在会议中的人将会收到回调
-
-```
-emedia.mgr.onMemberExited = function (member) {};
-```
-
-3、有媒体流加入,如有人推流之后
-
-```
-emedia.mgr.onStreamAdded = function (stream) {};
-```
-
-4、有媒体流移除,如有人退出之后
-
-```
-emedia.mgr.onStreamRemoved = function (stream) {};
-```
-
-5、角色改变
-
-```
-emedia.mgr.onRoleChanged = function (role) {};
-```
-
-6、媒体流发生变化,比如有人关闭摄像头
-
-```
-emedia.mgr.onMediaChanaged = function (stream) {};
-```
-
-7、会议退出,自己主动退出,服务端主动关闭
-
-```
-emedia.mgr.onConferenceExit = function (reason) {};
-```
-
-## 温馨提示
-
-1、如何排查问题?
-
-- 将插件的rtcLogToConsole设置为true, 在bindstatechange、callbackData可以查看到相关日志
-
-2、demo基于hbuilderX版本?
-
-- demo基于hbuilderX 2.9.10版本
-
-3、使用插件报错?
-
-- 插件是原生插件,需要在nvue页面里使用(uni-app不容许做成组件使用,只容许作为单独页面使用)
\ No newline at end of file
diff --git a/docs/private/media/conference_vxmini.md b/docs/private/media/conference_vxmini.md
deleted file mode 100644
index 28ab3ac3..00000000
--- a/docs/private/media/conference_vxmini.md
+++ /dev/null
@@ -1,404 +0,0 @@
-# 微信小程序集成多人通话
-
-------
-
-**多人音视频SDK**基于微信小程序live-pusher、live-player组件, 音视频SDK依赖IM SDK,所以集成前要先集成IM,把IM SDK放在全局变量wx下,可以参考[demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webim-weixin-xcx.zip)中src/comps/chat/multiEmedia的集成:
let WebIM = wx.WebIM = require('sdk/connection')
-
-**注意:** 小程序创建的会议支持其他端加入(Android,iOS,Web,桌面端), 但是其他端创建的会议要在创建时选择支持小程序,小程序端才可以加入会议,否则无法互通。
-
-## 准备
-
-- 下载微信开发者工具
-- 在微信公众平台配置自己服务器域名(在私有部署后提供)
-- 确保微信小程序符合使用媒体组件相应的类目并开通实时音视频权限
-- 使用微信小程序基础库 1.7.0 及以上版本
-
-## 下载
-
-音视频SDK在src/emedia/emedia_for_miniProgram.js,[下载客户端SDK及Demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webim-weixin-xcx.zip)。
-
-
-## 集成
-
-直接引用js: 拷贝文件 emedia_for_miniProgram 到小程序工程文件夹,使用 require 将 SDK 集成到项目中即可:
-
-```
-var emedia = require("../emedia/emedia_for_miniProgram.js");
-```
-
-### 集成步骤
-#### **发起会议**
-
-1. 调用 createConference,在回调中可以得到confr对象,创建者默认为管理员
-
-```
-emedia.mgr.createConference(confrType, password).then(function(confr){
- //confr 即为创建的会议
- //将ID password 发送给其他人
-})
-```
-
-**请注意:在其他端创建会议时,需要指定支持小程序音视频,才能与小程序互通。**
-
-2. 加入会议,调用加入会议的API joinConferenceWithTicket 加入会议
-
-```
-emedia.mgr.joinConferenceWithTicket(confrId, ticket, ext).then(function(confr){
- //confr 即为创建的会议
-})
-```
-
-调用joinRoom加入房间(会议),可以指定房间的名称,并且在房间不存在时会自动创建,另外可以在加入会议时指定角色。
-
-```
-let params = {
- roomName: 'test',
- password: '',
- role: 7, //admin
- config: {}
-}
-wx.emedia.mgr.joinRoom(params).then((res) => {
- let confrId = res.confrId
-})
-```
-
-3. 发布本地视频流
-
-```
-emedia.mgr.pubStream(rtcId).then(function(res){
- // 将返回的res.data.rtmp 赋值给live-pusher的src就可以推流了
-})
-```
-
-4. sdk调用emedia.mgr.onMemberJoin(member, stream) 告知进入的人
-
-5. sdk调用emedia.mgr.onStreamAdded(member, stream) 告知进入的人发布的流情况,在这个回调里拿到视频流去调subStream订阅流
-
-6. 可根据需要进行订阅emedia.mgr.subStream(streamId)
-
-7. onMemberExited:当有人离开会议,onRoleChanged自己在会议中角色改变;onStreamRemoved某人取消流发布;onConferenceExit会议退出
-
-#### **其他人进入会议**
-
-1. 调用 joinConference,在回调中可以得到confr对象,创建者默认为管理员
-
-```
-emedia.mgr.joinConference(confrId, password, ext).then(function(confr){
- //confr 加入会议
-})
-```
-
-2. sdk调用emedia.mgr.onMemberJoin(member, stream) 告知进入的人
-
-3. sdk调用emedia.mgr.onStreamAdded(member, stream) 告知进入的人发布的流情况
-
-4. 可根据需要进行订阅
-
-```
-emedia.mgr.subStream(streamId).then(function(res){
- //将返回的res.data.rtmp赋值给live-player的src就可以播放了
-})
-```
-
-5. onMemberExited:当有人离开会议,onRoleChanged自己在会议中角色改变;onStreamRemoved某人取消流发布;onConferenceExit会议退出
-
-### SDK回调
-
-1. 有人加入会议,其他人调用joinXX等方法,如果加入成功,已经在会议中的人将会收到
-
-```
-emedia.mgr.onMemberJoined = function (member) {};
-```
-
-2. 有人退出会议
-
-```
-emedia.mgr.onMemberExited = function (member) {};
-```
-
-3. 有媒体流添加,比如有人调用pubStream之后
-
-```
-emedia.mgr.onStreamAdded = function (stream) {};
-```
-
-4. 有媒体流移除
-
-```
-emedia.mgr.onStreamRemoved = function (stream) {};
-```
-
-5. 角色改变
-
-```
-emedia.mgr.onRoleChanged = function (role) {};
-```
-
-6. 媒体流发生变化 (比如有人关闭摄像头)
-
-```
-emedia.mgr.onMediaChanaged = function (stream) {};
-```
-
-7. 会议退出,自己主动退出,服务端主动关闭
-
-```
-emedia.mgr.onConferenceExit = function (reason, failed) {
- reason = (reason || 0);
- switch (reason){
- case 0:
- reason = "正常挂断";
- break;
- case 1:
- reason = "没响应";
- break;
- case 2:
- reason = "服务器拒绝";
- break;
- case 3:
- reason = "对方忙";
- break;
- case 4:
- reason = "失败,可能是网络或服务器拒绝";
- if(failed === -9527){
- reason = "失败,网络原因";
- }
- if(failed === -500){
- reason = "Ticket失效";
- }
- if(failed === -502){
- reason = "Ticket过期";
- }
- if(failed === -504){
- reason = "链接已失效";
- }
- if(failed === -508){
- reason = "会议无效";
- }
- if(failed === -510){
- reason = "服务端限制";
- }
- break;
- case 5:
- reason = "不支持";
- break;
- case 10:
- reason = "其他设备登录";
- break;
- case 11:
- reason = "会议关闭";
- break;
- }
-};
-```
-
-### 接口说明
-
-1. 常量
-
-```
-// 会议类型
-emedia.mgr.ConfrType = {
- COMMUNICATION: 10, //普通会议模式
- COMMUNICATION_MIX: 11, //大会议模式
- LIVE: 12, //直播模式
-};
-
-// 角色
-emedia.mgr.Role = {
- ADMIN: 7, //管理员(可推送视频、可解散会议、可踢人、可变更其他人角色,会议创建者默认为管理员)
- TALKER: 3, // 主播(可发言、可观看)
- AUDIENCE: 1 // 观众(仅可以观看)
-};
-```
-
-2. conference|confr
-
-```
-// 会议对象
-{
- confrId:"TS_X296786295944036352C27",
- id:"TS_X296786295944036352C27",
- password: "password123",
- roleToken:"roleToken",
- ticket:"ticket",
- type:12
-}
-```
-
-3. member
-
-```
-// 成员对象
-{
- "ext":{ //emedia.mgr.joinConference(confrId, password, {role: 'admin'})/* 用户可自定义扩展字段*/);
- "role":"admin"
- },
- "id":"MS_X197721744293023744C19M197756407719972865VISITOR",
- "globalName":"easemob-demo#chatdemoui_yss000@easemob.com",
- "name": "yss000"
-}
-```
-
-4. stream
-
-```
-// 视频流对象
-{
- "id":"RTC2__Of_C19M197756407719972865VISITOR",
- "voff":0, //1 视频关闭
- "aoff":0, //1 音频关闭
- "memId":"MS_X197721744293023744C19M197756407719972865VISITOR",
- "owner": member ,//member对象
- "rtcId":"RTC1"
-}
-```
-
-5. 创建会议
-
-```
-/**
- * @method createConference 创建会议
- * @param {string} confrType 会议类型
- * @param {string} password 会议密码
- * @param {boolean} rec 是否录制 默认false
- * @param {boolean} recMerge 是否合并 默认false
- */
-emedia.mgr.createConference(confrType, password).then(function(confr){
- //confr 即为创建的会议
-})
-```
-
-6. 获取加入会议ticket
-
-```
-/**
- * @method getConferenceTkt 申请tickit
- * @param {string} confrId 会议id
- * @param {string} password 会议密码
- */
-emedia.mgr.getConferenceTkt(confrId, password).then(function(tickit){
-
-})
-```
-
-7. 销毁会议
-
-```
-/**
- * @method destroyConference 解散会议
- * @param {string} confrId 会议id
- */
-emedia.mgr.destroyConference(confrId).then(function(){
-
-})
-```
-
-8. 踢人
-
-```
-/**
- * @method kickMembersById 踢人
- * @param {string} confrId 会议id
- * @param {Array} memberNames 踢出的人
- */
-emedia.mgr.kickMembersById(confrId, memberNames).then(function(){
-
-})
-```
-
-9. 改变角色
-
-```
-/**
- * @method grantRole 改变角色
- * @param {string} confrId 会议id
- * @param {Array} memberNames 人员
- * @param {string} role 角色
- */
-emedia.mgr.grantRole(confrId, memberNames, role).then(function(){
-
-})
-```
-
-10. 使用用户名密码加入会议,可自定义ext,其他会议成员将会看到
-
-```
-/**
- * @method joinConference 加入会议
- * @param {string} confrId 会议id
- * @param {string} password 会议密码
- * @param {Object} ext 扩展
- */
-emedia.mgr.joinConference(confrId, password, ext).then(function(){
-
-})
-```
-
-11. 使用ticket加入会议,可自定义ext,其他会议成员将会看到
-
-```
-/**
- * @method joinConferenceWithTicket 加入会议
- * @param {string} confrId 会议id
- * @param {string} ticket 会议ticket
- * @param {Object} ext 扩展
- */
-emedia.mgr.joinConferenceWithTicket(confrId, ticket, ext).then(function(){
-
-})
-```
-
-12. 调用joinRoom加入房间(会议),可以指定房间的名称,并且在房间不存在时会自动创建。 另外可以在加入会议时指定角色。
-
-```
-/**
- * @method joinRoom 加入房间(会议)
- * @param {Object} option
- * @param {string} option.roomName - 房间名称
- * @param {string} option.password - 房间密码
- * @param {number} option.role - 进入房间时的角色
- * @param {object} option.config - 扩展能力 可设置以下参数
- * @param {string} option.config.nickName - 进入会议的昵称
- * @param {boolean} option.config.rec - 是否开启录制
- * @param {boolean} option.config.recMerge - 是否开启合并
- * @param {number} option.config.maxTalkerCount - 自定义会议最大主播人数
- * @param {number} option.config.maxVideoCount - 自定义会议最大视频数
- * @param {number} option.config.maxAudienceCount - 自定义会议最大观众数
- * @param {number} option.config.maxPubDesktopCount - 自定义会议共享屏幕最大数
- * @param {object} option.config.ext - 扩展字段 用于自定义
- */
-wx.emedia.mgr.joinRoom(option).then((res) => {
- let confrId = res.confrId
-})
-```
-
-13. 退出会议
-
-```
-emedia.mgr.exitConference(confrId);
-```
-
-14. 发布媒体流
-
-```
-/**
- * @method pubStream 发布视频流
- * @param {string} rtcId 视频流id 自己发布流时rtcId = wx.emedia.util.getRtcId()
- */
-emedia.mgr.pubStream(rtcId).then(function(res){
- // res.data.rtmp 为要推流的url
-})
-```
-
-15. 订阅媒体流
-
-```
-/**
- * @method subStream 订阅视频流
- * @param {string} streamId 视频流id 可以在onStreamAdded中获取其他人的视频流id
- */
-emedia.mgr.subStream(streamId).then(function(res){
- // res.data.rtmp 为要播放的src
-})
-```
\ No newline at end of file
diff --git a/docs/private/media/conference_web.md b/docs/private/media/conference_web.md
deleted file mode 100644
index ac19362a..00000000
--- a/docs/private/media/conference_web.md
+++ /dev/null
@@ -1,1164 +0,0 @@
-# Web集成多人通话
-
-## 跑通Demo
-
-### 1. 示例代码
-
-- [下载视频会议Demo代码 ](https://github.com/easemob/videocall-web)
-- [体验Demo](https://zim-rtc.easemob.com:12007/)
-
-或进入环信[客户端下载](common_clientsdk.html#场景demo及源码下载)页面,选择下载Web端视频会议 Demo。
-
-### 2. 前提条件
-
-- 安装一款 Easemob Web SDK [支持的浏览器](common_introduction.html#兼容性说明)
-- 本地安装 node 环境 >= 6.3.0
-- 必须为https+webkit内核浏览器
-
-### 3. 运行 Demo
-
-1. 下载Demo
-2. 进入 videocall-web 文件夹
-3. 安装依赖包
-
-```
-npm install
-```
-
-4. 启动项目
-
-```
-HTTPS=true npm start
-```
-
-## 快速集成
-
-### 1. 环信后台注册 appkey
-
-在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。
-
-### 2. 创建项目
-
-```
-a.可以简单的写一个 html,引入 SDK 测试
-b.或者使用 脚手架搭建一个项目
-```
-
-### 3. 引入 SDK
-
-#### 3.1 通过 scrpit 标签的 src 引入
-
-[获取静态SDK 文件](#_3-4-获取sdk静态资源文件)
-
-```
-
-```
-
-#### 3.2 使用 npm 获取 SDK
-
-```
-npm install easemob-emedia
-```
-
-#### 3.3 在文件内引入 SDK
-
-```
-import emedia from 'easemob-emedia';
-```
-
-#### 3.4 获取SDK静态资源文件
-
-1. 首先 [下载 WebIM Demo 包](common_clientsdk.html#音视频sdk下载)
-![img](/images/privitization/wechatimg_download.png)
-2. 从Demo 中选取 SDK 文件**EMedia_sdk-dev.js**
-![img](/images/privitization/wechatimg_path.png)
-
-
-### 4. 初始化SDK
-
-```
-emedia.config({
- appkey, // 从环信后台 获取的appkey、必填
- consoleLogger: true, // boolean 是否开启打印日志,默认true
- ... 其他的一些配置
-});
-```
-
-### 5. 环信ID注册、登录
-
-在进行音视频通话前,需要首先登录IM账户,登录过程参见[账号登录](http://doc.easemob.com/document/web/overview.html#%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95)。
-若您还没有IM账户,需要先注册账户,注册过程参见[账号注册](http://doc.easemob.com/document/web/overview.html#%E6%B3%A8%E5%86%8C%E7%94%A8%E6%88%B7)。
-
-### 6. 进入会议
-
-:::tip
-加入会议之前必须先要调用 emedia.mgr.setIdentity 方法设置 emedia 对象的memName 、token。
-:::
-```
-emedia.mgr.setIdentity(memName, token); //memName:appkey +'_'+ 环信ID, token: 环信ID登录后返回的access_token
-```
-
-**params** 为进入会议需要的参数
-
-```
-var params = {
- roomName, // string 房间名称 必需
- password, // string 房间密码 必需
- role // number 进入会议的角色 1: 观众 3:主播 必需
- config:{
- rec:false, //是否开启录制会议
- recMerge:false, //是否开启合并录制
- supportWechatMiniProgram: true //是否允许小程序加入会议
- }
-}
-```
-
-调用 **emedia.mgr.joinRoom** 进入会议,若该会议不存在,服务器将会自动创建。
-
-```
-const user_room = await emedia.mgr.joinRoom(params);
-```
-
-返回的参数 **user_room** ,组成如下:
-
-```
-user_room: {
- confrId: "IM3U9Z0AHDYQTF8KNDAAD00C147" 会议ID
- id: "IM3U9Z0AHDYQTF8KNDAAD00C147"
- joinId: "IM3U9Z0AHDYQTF8KNDAAD00C147M2" 在会议中的唯一ID
- role: 1|3|7 //角色 1观众 3主播 7管理员
- roleToken:"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlYXNlbW9iLWRlbW8j..."
- ticket: "{\"tktId\":\"IM3U9Z0AHDYQTF8KNDAAD00C147TK1\",..."
- type: 10 //会议类型
-}
-```
-
-### 7. 发布本地流
-
-加入会议之后 调用 **emedia.publish** 发布流。
-
-```
-var constaints = { // 发布音频流的配置参数, Object 必需。 video或audio属性 至少存在一个
- audio: true, // 是否发布音频
- video: true // 是否发布视频
-}
-var ext = {} // 发布流的扩展信息 Object 非必需。会议其他成员可接收到
-
-const pushedStream = await emedia.mgr.publish(constaints, ext);
-```
-
-发布本地流成功后, 调用 emedia.mgr.streamBindVideo 用于在video标签显示流。
-
-```
-var videoTag = document.getElementById('#xxx') //需要显示本地流的 video 标签
-emedia.mgr.streamBindVideo(pushedStream, videoTag);
-```
-
-### 8. 订阅远端流
-
-当远端流加入频道时,会触发 emedia.mgr.onStreamAdded 方法,我们需要给 emedia.mgr 赋值 onStreamAdded 用来接收 stream
-
-**我们建议项目初始化后,立即设置[常用监听函数](#_10-会议常用监听函数)**
-
-#### 8.1 监听 onStreamAdded 方法
-场景:当有远端流加入时。
-
-:::tip
-自己发布的本地流也会触发 onStreamAdded 方法,
-stream.located() == true 为自己发的本地流,
-也可以在这里绑定 video标签,显示本地流。
-:::
-
-```
-emedia.mgr.onStreamAdded = function(member, stream) {
- // member:发布流人员的信息、stream:流信息
- if(!stream.located()) {
- var option = {
- member: member,
- stream: stream,
- subVideo: true,
- subAudio: true,
- videoTag: document.getElementById('#xxx')
- }
- emedia.mgr.subscribe(option.member, option.stream, option.subVideo, option.subAudio, option.videoTag)
- }
-}
-```
-
-在emedia.mgr.subscribe 方法中注意以下参数的设置:
-
-- option.member:发布流人员的信息,必需。也就是 onStreamAdded 方法的 member
-- option.stream:流信息,必需。也就是 onStreamAdded 方法的 stream
-- option.subVideo: 是否订阅视频,必需
-- option.subAudio: 是否订阅音频,必需
-- option.videotag: 需要显示流的 video 标签,必需
-
-#### 8.2 监听 onStreamRemoved 方法
-场景:当远端流被移除时(例如远端用户调用了 Stream.unpublish), 停止订阅该流并移除它的画面。
-
-```
-emedia.mgr.onStreamRemoved = function(member, stream) {
- // member:发布流人员的信息、stream:流信息
- emedia.mgr.unsubscribe(stream) // 停止订阅流
- removeView(stream.id) // 移除video标签,removeView方法需自己实现
-}
-```
-
-### 9. 退出会议
-
-调用 emedia.mgr.exitConference 方法退出会议。
-
-```
-emedia.mgr.exitConference() //无参数
-```
-
-### 10. 会议常用监听函数
-:::tip
-`强烈建议:` 在加入会议之前定义需要的 SDK 回调函数
-:::
-```
-//有人加入会议
-emedia.mgr.onMemberJoined = function (member) { } // member: 加入会议成员信息
-
-//有人退出会议
-emedia.mgr.onMemberExited = function (member) {} // member: 退出会议成员信息
-
-//有媒体流添加 (自己发布的流也会触发 stream.located() == true )
-emedia.mgr.onStreamAdded = function (member, stream) { }; // member: 发布流的成员信息,stream:流信息
-
-//有媒体流移除
-emedia.mgr.onStreamRemoved = function (member, stream) { } // member: 移除流的成员信息,stream:流信息
-
-//自己角色变更
-emedia.mgr.onRoleChanged = role => {} // role: 变更后的角色
-
-//会议退出;自己主动退 或 服务端主动关闭;
-emedia.mgr.onConferenceExit = function (reason, failed) {
- reason = (reason || 0);
- switch (reason){
- case 0:
- reason = "正常挂断";
- break;
- case 1:
- reason = "没响应";
- break;
- case 2:
- reason = "服务器拒绝";
- break;
- case 3:
- reason = "对方忙";
- break;
- case 4:
- reason = "失败,可能是网络或服务器拒绝";
- if(failed === -9527){
- reason = "失败,网络原因";
- }
- if(failed === -500){
- reason = "Ticket失效";
- }
- if(failed === -502){
- reason = "Ticket过期";
- }
- if(failed === -504){
- reason = "链接已失效";
- }
- if(failed === -508){
- reason = "会议无效";
- }
- if(failed === -510){
- reason = "服务端限制";
- }
- break;
- case 5:
- reason = "不支持";
- break;
- case 10:
- reason = "其他设备登录";
- break;
- case 11:
- reason = "会议关闭";
- break;
- }
-};
-//管理员变更
-emedia.mgr.onAdminChanged = admin => {} //admin 管理员信息
-
-//监听弱网状态
-emedia.mgr.onNetworkWeak = streamId => {} //streamId 会议中的流 ID
-
-//监听断网状态
-emedia.mgr.onNetworkDisconnect = streamId => {} //streamId 会议中的流 ID
-```
-
-## 进阶功能
-
-### 会议管理
-
-#### **1. 创建会议并加入**
-
-这里的创建会议 不同于快速集成中的加入会议,这里的是属于另一套逻辑,建议使用快速集成中的加入会议
-
-:::tip
-如果只单纯的创建,没进行操作,则创建者不是会议的成员,没有相应的角色,不能进行其他操作。
-:::
-##### **1.1 调用 emedia.mgr.createConference 方法创建会议**
-
-```
-let params = {
- confrType,
- password,
- rec,
- recMerge,
- supportWechatMiniProgram
- ... 其他参数
-}
-
-const confr = await emedia.mgr.createConference(params);
-```
-
-在 emedia.mgr.createConference 方法中,注意以下参数的设置:
-
-- confrType 会议类型 10:普通会议模式、11:大会议模式、12:直播模式。number 必需
-- password 会议密码 string 必需
-- rec 是否开启通话录制 boolean 非必需
-- recMerge 是否开启通话录制合并 boolean 非必需
-- supportWechatMiniProgram 会议是否支持小程序端 boolean 非必需, 默认不支持
-
-创建会议成功后,返回的参数 confr 结构如下:
-
-```
-confr:{
- error: 0,
- confrId: "LBJ13H9WJJEVJTGL1U1PIQ00C2", // 会议id
- password: "xxxx", // 创建会议时设置的密码
- role: 7, // 在会议中的角色 这里因为是创建者,所以是 7: 管理员
- roleToken:"eyJ0eXAiOiJKV1QiLCJhbG *** f1gg_QJWxhs-jqmuFok", //创建者的token
- type: 10 // 会议类型
-}
-```
-
-##### **1.2 调用 emedia.mgr.joinUsePassword 方法加入会议**
-
-```
-const join_result = await this.emedia.joinUsePassword(confrId, password) // 参数为 创建会议成功后返回的 confrId和password
-```
-
-加入会议成功后返回的结果,结构如下:
-
-```
-join_result: {
- confrId: "LBJ13H9WJJEVJTGL1U1PIQ00C7", // 会议id
- joinId: "LBJ13H9WJJEVJTGL1U1PIQ00C7M9", //创建会议时设置的密码
- password: "0.010568535799199363", // 会议成员在会议中的身份id(唯一)
- role, // 在会议中的角色 创建者加入会议永远是 7: 管理员,其他人加入返回的是 3: 主播
- roleToken: "eyJ0eXAiOiJK *** FaXuMVlqPOTofRRdE", // 加入会议者的token
- type: 10 // 会议类型
- }
-```
-
-#### **2. 开启录制、录制合并**
-
-##### **2.1 调用 emedia.mgr.createConference 创建会议时配置**
-
-```
-let params = {
- ...
- rec: true,
- recMerge: true,
- ... 其他参数
-}
-
-const confr = await emedia.mgr.createConference(params);
-```
-
-##### **2.2 调用 emedia.mgr.joinRoom 加入会议时配置**
-:::tip
-只有第一个加入会议的人,配置的才有效,参数需要放到 config 对象中。
-:::
-```
-let params = {
- ... 其他参数
- config: {
- rec: true,
- recMerge: true
- }
-}
-
-const confr = await emedia.mgr.createConference(params);
-```
-
-- rec: 是否开启录制,默认 false
-- recMerge: 是否开启录制合并,默认false
-
-#### **3. 邀请成员加入会议**
-
-```
-SDK 不提供邀请接口。邀请的形式,完全可以由用户自行定义,可以是条文本消息,也可以是个控制消息等等。SDK 不做限制。实现方式可以参考官方 demo,通过群组消息邀请,具体代码 可查询 demo/src/components/webrtc/AddAVMemberModal.js 中的 70-89 行。
-```
-
-##### **3.1 成员收到邀请加入会议**
-
-解析出邀请消息中带的 confrId 和 password ,调用 **emedia.mgr.joinUsePassword** 加入会议
-
-#### **4. 管理员销毁会议**
-
-调用 emedia.mgr.destroyConference 方法, **注意:只有管理员有权限,其他角色调用不生效**
-
-```
-await emedia.mgr.destroyConference(confrId); //confrId: 会议Id
-```
-
-其他人会收到会议结束的回调。
-
-```
-emedia.mgr.onConferenceExit = reason => {} // reason:退出会议的原因,因为会议被销毁了,所以这里应为 11: "会议关闭"
-```
-
-#### **5. 设置会议人数限制**
-
-##### **5.1 在 emedia.mgr.joinRoom 方法中设置**
-只有第一个加入房间的人员(也就是管理员),设置的才能生效
-
-```
-var params = {
- ... 其他参数,
- config:{ // 在 config 中指定字段
- maxTalkerCount:3,
- maxAudienceCount:100,
- maxVideoCount:2,
- maxPubDesktopCount: 1
- }
-}
-
-const user_room = await emedia.mgr.joinRoom(params);
-```
-
-##### **5.2 在 emedia.mgr.createConference(创建会议) 方法中设置**
-
-```
-var params = {
- ... 其他参数,
- maxTalkerCount:3
- maxVideoCount:2
- maxAudienceCount:100
- maxPubDesktopCount: 1
-
-}
-const confr = await emedia.mgr.createConference(params);
-```
-
-以上设置会议参数的注意事项如下:
-
-- maxTalkerCount:自定义会议最大主播人数,默认 100
-- maxAudienceCount:自定义会议最大观众数 默认 600
-- maxVideoCount:自定义会议最大视频数, 默认 9
-- maxPubDesktopCount: 自定义会议共享屏幕最大数 默认 2
-
-#### **6. 设置会议昵称**
-
-在 emedia.mgr.joinRoom 方法中设置
-
-```
-var params = {
- ... 其他参数,
- config:{
- ... 其他参数,
- nickName: xxx, // string
- }
-}
-const user_room = await emedia.mgr.joinRoom(params);
-```
-
-#### **7. 获取会议信息**
-
-调用 **emedia.mgr.selectConfr** 方法获取会议信息
-
-```
-const confr_info = await emedia.mgr.selectConfr(confrId, password); // confrId:会议id、password:会议密码
-// 返回的参数 confr_info 结构如下:
-confr_info: {
- confr: {
- id: "LBJ13H05522QATGIJKXUF800C45639", // 会议id
- type: 10, // 会议类型
- memTotal: 1, // 会议中总人数 主播和观众
- audienceTotal: 0, // 观众人数
- talkers: ["018ae39 *** 663282d7495"] // 主播的memName集合
- }
- error: 0
-}
-```
-
-#### **8. CDN合流推流**
-
-CDN推流是指将会议画面,合并到一张画布推送到远程CDN,其他人可以从CDN拉流而不用加入会议。
-
-##### **8.1 开启CDN推流**
-
-CDN推流参数 **liveCfg为必需** 结构如下:
-
-```
-let liveCfg = {
- cdn:'', //推流地址、字符串;必需
- layoutStyle: 'GRID' | 'CUSTOM', // 格子显示 | 自定义,必需
- canvas :{// canvas 参数在 layoutStyle == 'CUSTOM' 必填
- bgclr : 0x980000,//背景色 980000 为 十六进制色值
- w : 640, //宽度
- h : 480, //高度
- fps: 20, //输出帧率
- bps: 1200000, //输出码率
- codec: "H264" //视频编码,现在必须是H264
- }
-}
-```
-
-**1.创建会议时指定 CDN推流**
-
-```
-let option = {
- ...
- liveCfg // 创建CDN推流参数
-}
-emedia.mgr.createConference(option)
-```
-
-**2.加入房间时 指定CDN推流**
-
-```
-// 只有第一个加入房间的人才能创建 CDN、以后加入的人指定CDN也无效
-let params = {
- config:{
- ...
- liveCfg // 创建CDN推流参数
- }
-}
-emedia.mgr.joinRoom(params);
-```
-
-##### **8.2 多路推流**
-
-通过 **emedia.mgr.addLive** 方法指定一路推流CDN,需要几路CDN,就调用几次方法
-**注意:只有管理员,可创建 CDN**
-
-```
-// confrId: 会议id, 必需
-// liveCfg: cdn 配置,必需
-media.mgr.addLive(confrId, liveCfg);
-```
-
-##### **8.3 更新CDN布局**
-
-```
-// 只有管理员才能 更新布局。更新布局会 将layoutStyle 变为 CUSTOM 而且不可逆
-emedia.mgr.updateLiveLayout(confrId, liveId, regions)
-
-// confrId 会议id 必需
-// liveId 推流CDN id, 必需 可通过 emedia.config.liveCfgs 获取 Array
-
-regions:[ // 希望定义视频流 显示的配置集合
- {
- "sid": stream_id,//视频流的id
- "x": 320,//距离 x 轴的距离 Number
- "y": 240,//距离 y 轴的距离 Number
- "w": 960,//宽度 Number
- "h": 720,//高度 Number
- "style": "fill" | "AspectFit" //视频显示模式 fill:铺满、AspectFit:原比例显示
- },
- .... 其他视频流配置(数组有几个项,就显示几个视频流)
-]
-```
-
-##### **8.4 删除CDN**
-
-```
-// 只有管理员可操作
-//confrId 会议id 必需
-// liveId 推流CDN id, 必需 可通过 emedia.config.liveCfgs 获取 Array
-emedia.mgr.deleteLive(confrId, liveId)
-```
-
-
-#### **9. 取日志**
-
-在浏览器控制台,输入 **emedia.fileReport** ,敲下回车键会下载下一份日志文件
-
-```
-emedia.fileReport() //无参数
-```
-
-#### **10. 会议属性**
-
-```
-// 用来自定义一些属性,广播给会议中的成员
- // 有人设置会议属性,所有的成员都能收到
- let options = {
- key:username,
- val:'request_tobe_speaker'
- }
- // a. 设置会议属性
- emedia.mgr.setConferenceAttrs(options)
- // b. 删除会议属性
- emedia.mgr.deleteConferenceAttrs(options)
- // c. 会议属性变更回调
- emedia.mgr.onConfrAttrsUpdated = attrs => {} //attrs 会议属性集合 Array
-```
-
-#### **11. 私有部署**
-
-私有部署设置方法参见[私有云sdk集成配置](../im/uc_Web_private.md)。
-
-### 音视频管理
-
-#### **1. 设置通话参数**
-
-发布本地媒体流时,可指定音视频的码率和分辨率非必需。 **共享桌面不可指定**
-
-```
-var constaints = {
- audio: {bitrate: 100},// 指定音频码率
- video: {
- width: { // 指定视频分辨率宽度
- exact: 1280
- },
- height: { // 指定视频分辨率高度
- exact: 720
- },
- bitrate: 200,// 指定视频码率
- }
-}
-emedia.mgr.publish(constaints)
-```
-
-#### **2. 指定设备打开音视频**
-
-```
-const devices = await emedia.mgr.mediaDevices(); //获取设备列表
-
- // 设备信息
- device: Object {
- deviceId: "529a6fe76467d****9498ab22f5f362cd" // 设备ID
- groupId: "2b74c9b9ab99*****d513fbabc1e86b3c5d99f7f8a0c16"
- kind: "audioinput" | audiooutput | videoinput | videooutput // 设备类型
- label: "Internal Microphone (Built-in)"
- }
- constraints: { // 选择设备, 然后指定设备(只需要传入设备信息中的deviceId属性,为String类型,其他的属性在推流时暂时用不到)
- audio: {deviceId: deviceId ? {exact: deviceId} : undefined}, //判断如果deviceId存在那么就传入对象。
- video: {deviceId: deviceId ? {exact: deviceId} : undefined}
- },
-
-const stream = await emedia.mgr.publish(constraints) // 推流
-```
-
-#### **3. 停止发布流**
-
-调用 **emedia.mgr.unpublish** 方法停止自己已经发布的流。
-
-```
-emedia.mgr.unpublish(pushedStream); // pushedStream:自己发布的流
-```
-
-会议中人员(包括自己)会收到 流被移除的回调函数 **emedia.mgr.onStreamRemoved**。
-
-```
-emedia.mgr.onStreamRemoved = function (member, stream) {
- // member: 停止发布流人员信息
- // stream:流的信息,stream.located() == true 代表是自己的流,false则为其他人的流
-};
-```
-
-#### **4. 停止订阅流**
-
-调用 **emedia.mgr.unsubscribe** 方法停止订阅别人的流。
-
-```
-emedia.mgr.unsubscribe(stream); // stream:已经订阅的流
-```
-
-#### **5. 通话过程中音视频控制**
-
-##### **5.1 打开/关闭自己的视频**
-
-```
-const res_stream = await emedia.mgr.pauseVideo(own_stream) //关闭视频
-const res_stream = await emedia.mgr.resumeVideo(own_stream) //开启视频
-```
-
-##### **5.2 打开/关闭自己的音频**
-
-```
-const res_stream = await emedia.mgr.pauseAudio(own_stream) // 关闭音频
-const res_stream = await emedia.mgr.resumeAudio(own_stream) // 开启音频
-执行开启/关闭音视频方法时,
-* own_stream:自己已经发布的媒体流(不能是桌面流)
-* res_stream:设置音视频成功后返回的流对象
-```
-
-**执行上述操作后,会议中其他人员会收到流变化的回调 emedia.mgr.onMediaChanaged**
-emedia.mgr.onMediaChanaged 应该在流变化之前监听。
-
-```
-var videoTag = document.getElementById('#xxx') // 获取 video 标签
-emedia.mgr.onMediaChanaged(videoTag, function(constaints, stream) {
-
-});
-// 回调函数中 constaints、stream
-constaints: {
- audio: true // true: 开启了音频,false:关闭了音频
- video: true // true: 开启了视频,false:关闭了视频
-}
-stream:媒体流变化后的 stream 对象
-```
-
-##### **5.3 切换摄像头**
-
-```
-// 随机切换摄像头
-emedia.mgr.changeCamera(confrId).then(function(){
- // 无参数
-}).catch(function(){
-
-})
-// 切换手机前后摄像头
-emedia.mgr.switchMobileCamera(confrId).then(function(){
- // 无参数
-}).catch(function(){
-
-})
-```
-
-#### **6. 音视频网络状态监听**
-
-:::tip
-建议进入会议之前绑定网络状态监听函数
-:::
-```
-//监听弱网状态
-emedia.mgr.onNetworkWeak = streamId => {} //streamId 会议中的流 ID
-
-//监听断网状态
-emedia.mgr.onNetworkDisconnect = streamId => {} //streamId 会议中的流 ID
-```
-
-#### 7. 监听谁在说话
-
-这是监听的video标签。
-:::tip
-建议:在将video标签与stream绑定时(emedia.mgr.streamBindVideo), 调用 emedia.mgr.onSoundChanaged 方法。
-:::
-```
-var videoTag = getElementById('#xxx');
-emedia.mgr.onSoundChanaged(videoTag,, function (meterData) {});
-
-// 返回的参数 meterData 结构如下:
-meterData: {
- instant: 0.26280892641627845 // instant 大约每50毫秒变化一次, 小于1的浮点数
- slow: 0.06802768487276245 // slow大约是一秒钟内的平均音量,小于1的浮点数
- clip: 0
-}
-```
-
-#### **8. 共享桌面**
-
-仅支持PC Chrome浏览器或electron平台。
-
-**>>SDK 3.2.1 版本 文档**
-##### **8.1 无插件共享**
-
-需要 SDK 3.2.1 版本开始支持,并且 Chrome 72 或以上版本。
-
-```
-const screenStream = await emedia.mgr.shareDesktopWithAudio({
- confrId: confrId, // 会议ID, 必须
- audio: false,
-});
-```
-
-##### **8.2 有插件共享**
-
-```
-//在 sdk 内部会自动判断,浏览器是否含有 navigator.mediaDevices.getDisplayMedia API,
-//如果没有,将会跳转至 使用 插件的 API,如果没有安装插件将给出提示
-```
-
-##### **8.3 分享音频**
-
-```
-//1. 版本起支持在 Windows 平台的 Chrome 浏览器 74 及以上版本同时共享屏幕和本地播放的背景音,
-//2. 将 audio 设置为 true 即可
-```
-
-##### **8.4 Electron 屏幕共享**
-
-```
-//1. sdk 内部会判断是否是在 electron 平台内
-//2. electron 平台 会默认选择 第一个屏幕
-//3. 如果需要自定义选择框,请重新定义 emedia.chooseElectronDesktopMedia 方法
-emedia.chooseElectronDesktopMedia = function(sources, accessApproved, accessDenied){
- sources // Array 获取到的屏幕列表
- accessApproved(source)// 选中的 source 对象,进行分享
- accessDenied()// 取消分享,关闭自定义框需要调用此方法
-}
-```
-
-##### **8.5 停止共享桌面**
-
-```
-停止共享桌面,执行 取消流的发布 emedia.mgr.unpublish(screenStream)
-```
-
-**>>SDK 3.2.1 之前版本 文档**
-
-```
-/**
- * let params = {
- * videoConstaints,
- * withAudio,
- * videoTag,
- * ext,
- * confrId,
- * stopSharedCallback
- * }
- */
-
-/**
- * videoConstaints {screenOptions: ['screen', 'window', 'tab']} or true
- * withAudio: true 携带语音,false不携带 如携带语音,需自己调用关闭流,不会执行 stopSharedCallback 回调
- * ext 用户自定义扩展,其他成员可以看到这个字段
- * stopSharedCallback 共享插件 点击【停止共享】的回调函数,做相应的处理(比如删除流...)
- */
-emedia.mgr.shareDesktopWithAudio(params).then(function(pushedStream){
- //stream 对象
-}).catch(function(error){
-
-});
-
-//electron平台 默认选择第一个屏幕,如果需要选择其他,需要重写方法
-emedia.chooseElectronDesktopMedia = function(sources, accessApproved){
- var firstSources = sources[0];
- accessApproved(firstSources);
-}
-```
-
-**注意:** 在chrome浏览器中使用时,需要从[chrome store](https://chrome.google.com/webstore/detail/rtc-share-desktop/ccahbcjalpomijfpjemdgpnbogofnlgl) 或者从[环信服务器](https://download-sdk.oss-cn-beijing.aliyuncs.com/rtc_desktop_share.zip) 中下载插件,解压后在chrome浏览器中输入 chrome://extensions/,选择“Load unpacked” 选择解压后的文件夹中的1.0_0文件夹,加载插件。
-
-### 角色管理
-
-可通过 emedia.mgr.Role 获取会议中的角色类型。
-
-```
-emedia.mgr.Role: {
- ADMIN: 7, // 会议管理员: 能创建会议,销毁会议,移除会议成员,切换其他成员的角色
- TALKER: 3, // 主播: 能上传自己的音视频,能观看收听其他主播的音视频,即能发布流和订阅流)
- AUDIENCE: 1 // 观众: 只能观看收听音视频,即只能订阅流
-};
-// 可在会议中定义更加语义化的判断:
-if(member.role == emedia.mgr.Role.ADMIN){ }
-等同于
-if(member.role == 7){ }
-在以下申请主播和申请管理员的过程,请注意:
-1.从发起申请到管理员回复(同意或拒绝),是一个完整的过程
-2.因此可以认为:当管理员收到请求,会收到两个函数参数(同意和拒绝),用于管理员调用
-3.当管理员处理了请求(同意或拒绝),申请者会收到处理结果(同意或拒绝),未处理则不会收到
-```
-
-**以下方法非回调函数均为异步函数**
-
-```
-try {
- await emedia.mgr.xxx;
- } catch(error) { }
-
-// 以下出现的参数注解
- confrId: 会议id
- memberId: 与会人员的id,member 中的id
- nickName: 昵称
-```
-
-#### **1. 观众申请成为主播**
-
-观众通过调用 **emedia.mgr.requestToTalker** 方法申请主播。
-
-```
-// 观众上麦申请方法
-emedia.mgr.requestToTalker(confrId)
-
-// 管理员收到上麦申请的回调 (主播不会收到这个回调)
-emedia.mgr.onRequestToTalker = function(applicat, agreeCallback, refuseCallback) {
- /*
- * applicat { memberId, nickName } object 申请者信息
- * agreeCallback 管理员同意的回调 示例:agreeCallback(memberId) memberId 申请者 id 必需
- * refuseCallback 管理员拒绝的回调 示例:refuseCallback(memberId) memberId 申请者 id必需
- */
-}
-
-// 观众收到 上麦申请的回复
-emedia.mgr.onRequestToTalkerReply = function(result) {
- // result 0: 同意 1: 拒绝
-}
-```
-
-#### **2. 主播申请成为管理员**
-
-```
-// 主播申请管理员
-emedia.mgr.requestToAdmin(confrId);
-
-//管理员收到申请管理员的回调 (主播不会收到这个回调)
-emedia.mgr.onRequestToAdmin = function(applicat, agreeCallback, refuseCallback) {
- /*
- * applicat { memberId, nickName } object 申请者信息
- * agreeCallback 管理员同意的回调 示例:agreeCallback(memberId) memberId 申请者 id 必需
- * refuseCallback 管理员拒绝的回调 示例:refuseCallback(memberId) memberId 申请者 id必需
- */
-}
-
-// 主播收到 申请管理员的回复
-emedia.mgr.onRequestToAdminReply = function(result) {
- // result 0: 同意 1: 拒绝
-}
-```
-
-#### **3. 授权**
-
-**只有管理员有权限授权**
-调用方法改变与会人员的角色(可升可降)。
-
-```
-var option = {
- confr:, //会议对象 Object 必需
- memberNames: // 被授权人员的memberName集合(可同时给多人授权)Array
- role: // 需要授权成什么角色 Number 必需
-}
-emedia.mgr.grantRole(option.confr, option.memberNames, option.role)
-```
-
-#### **4. 角色降级**
-
-:::tip
-注意:只能角色降级 从管理员到主播、从主播到观众、从管理员到观众,不可逆向操作
-:::
-与会成员调用 **emedia.mgr.degradeRole** 方法就会角色降级。
-
-```
-//[memName] 与会人员的memName、 toRole 想要 达到的角色
-emedia.mgr.degradeRole(confrId, [memName], toRole);
-```
-
-#### **5. 管理员踢人**
-
-:::tip
-只有管理员可踢人
-:::
-```
-// confr: 会议对象,必需 Object
-// memberNames: 被踢掉人员的 memberName, 必需 Array
-emedia.mgr.kickMembersById(confr, memberNames)
-```
-
-#### **6. 管理员执行全体静音/取消全体静音**
-
-:::tip
-只有管理员可操作,其他角色操作不生效,管理员不会被静音
-:::
-
-##### **6.1 管理员静音全体**
-
-```
-await emedia.mgr.muteAll(confrId); // confrId: 会议Id
-
-// 主播收到回调
-emedia.mgr.onMuteAll = () => {
- // 在收到回调后,需要在程序中执行关闭麦克风的逻辑(emedia.mgr.pauseAudio(own_stream))
-}
-```
-
-##### **6.2 取消全体静音**
-
-```
-await emedia.mgr.unmuteAll(confrId); // confrId: 会议Id
-
-//主播收到回调
-emedia.mgr.onUnMuteAll = () => {
- // 在收到回调后,需要在程序中执行关闭麦克风的逻辑(emedia.mgr.resumeAudio(own_stream))
-}
-```
-
-#### **7. 管理员指定成员静音/取消指定成员静音**
-
-:::tip
-只有管理员可操作,其他角色操作不生效
-:::
-
-##### **7.1 管理员指定成员静音**
-
-```
-emedia.mgr.muteBymemberId(confrId, memberId);// memberId 被静音主播的memberId
-
-// 单个主播被管理员静音的回调(只他自己收到回调)
-emedia.mgr.onMuted = () => {
- // 在收到回调后,需要在程序中执行关闭麦克风的逻辑(emedia.mgr.pauseAudio(own_stream))
-}
-```
-
-##### **7.2 管理员取消指定成员静音**
-
-```
-emedia.mgr.unmuteBymemberId(confrId, memberId);// memberId 被取消静音主播的memberId
-
-// 单个主播被管理员取消静音的回调 (只他自己收到回调)
-emedia.mgr.onUnmuted = () => {
- // 在收到回调后,需要在程序中执行关闭麦克风的逻辑(emedia.mgr.resumeAudio(own_stream))
-}
-```
-
-#### **8. 本身角色变更回调**
-
-如果想要变更自己的角色,需要向管理员申请,管理员同意后,角色就会变更
-```
-emedia.mgr.onRoleChanged = function (role) {
- // role: 变更后的角色
-};
-```
-
-#### 9. 管理员变更回调
-
-当会议中的管理员变更时,与会人员都会收到这个回调
-
-```
-emedia.mgr.onAdminChanged = admin => {} //admin 管理员信息
-```
-
-### 其他接口
-
-#### **抓取 video图像,并保存**
-
-```
-emedia.mgr.captureVideo(videoTag, true, filename)
-等价于
-emedia.mgr.triggerCaptureVideo(videoTag, true, filename);
-```
-
-#### **控制远程视频(手机端)定格**
-
-```
-emedia.mgr.freezeFrameRemote(stream);
-等价于
-emedia.mgr.triggerFreezeFrameRemote(videoTag).catch(function(){
- alert("定格失败");
-});
-```
-
-#### **控制手机闪光灯打开/关闭**
-
-```
-/**
- * torch true 打开,否则 关闭; 可缺失
- */
-emedia.mgr.torchRemote(stream, torch);
-等价于
-emedia.mgr.triggerTorchRemote(videoTag, torch).catch(function(){
- alert("Torch失败");
-});
-```
-
-#### **控制手机截屏**
-
-```
-emedia.mgr.capturePictureRemote(stream);
-等价于
-emedia.mgr.triggerCapturePictureRemote(videoTag).catch(function(){
- alert("抓图失败");
-});
-```
-
-#### **控制手机摄像头放大缩小**
-
-```
-emedia.mgr.zoomRemote(stream, multiples);
-等价于
-emedia.mgr.triggerZoomRemote(videoTag, multiples).catch(function(){
- alert("zoom失败");
-});
-```
-
-#### **控制手机摄像头聚焦曝光**
-
-```
-/**
- * clickEvent 为 videoTag的点击事件。通过event计算点击的坐标传给sdk进行控制
- *
- */
-emedia.mgr.focusExpoRemote(stream, videoTag, clickEvent).catch(function(){
- alert("focusExpoRemote失败");
-});
-等价于
-/**
- * event string. 如点击 “click”
- * fail 失败回调;success成功回调
- */
-emedia.mgr.onFocusExpoRemoteWhenClickVideo(videoTag, event, fail, success);
-```
-
-#### **取消在videoTag上的事件**
-
-```
-//用来对onFocusExpoRemoteWhenClickVideo的撤销
-emedia.mgr.offEventAtTag(videoTag);
-//视频收发数据统计
-emedia.mgr.onMediaTransmission(videoTag, function notify(trackId, type, subtype, data) {
- var $iceStatsShow = $div.find("#iceStatsShow");
- var $em = $iceStatsShow.find("#"+subtype);
- if(!$em.length){
- $em = $("").appendTo($iceStatsShow).attr("id", subtype);
- }
-
- $em.text(subtype + ":" + (data*8/1000).toFixed(2));
-});
-//连接状态变化
-emedia.mgr.onIceStateChanged(videoTag, function (state) {
- console.log(state);
-});
-```
-
-#### **支持会议属性**
-
-```
-// 用来自定义一些属性,广播给会议中的成员
- // 有人设置会议属性,所有的成员都能收到
- let options = {
- key:username,
- val:'request_tobe_speaker'
- }
-
- // a. 设置会议属性
- emedia.mgr.setConferenceAttrs(options)
- // b. 删除会议属性
- emedia.mgr.deleteConferenceAttrs(options)
- // c. 会议属性变更回调
- emedia.mgr.onConfrAttrsUpdated = attrs => {} //attrs 会议属性集合 Array
-```
-
-## 客户端API
-
-多人音视频通话的API包括以下接口
-
-- createConference: 创建会议
-- destroyConference:销毁会议
-- getConferenceInfo:获取会议信息
-- publish:发布媒体流
-- unpublish:取消发布媒体流
-- grantRole:改变角色
-- joinConference:通过password 加入会议
-- kickMembersById:通过id踢出成员
-
-**以下方法均为 emedia.mgr 对象的属性方法:**
-
-| 方法 | |
-| :----------------------------------------------------------- | --------------------- |
-| [createConference](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#createConference) | 创建会议 |
-| [destroyConference](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#destroyConference) | 销毁会议 |
-| [getConferenceInfo](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#getConferenceInfo) | 获取会议信息 |
-| [grantRole](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#grantRole) | 改变角色 |
-| [joinConference](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#joinConference) | 通过password 加入会议 |
-| [kickMembersById](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#kickMembersById) | 通过id踢出成员 |
-| [publish](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#publish) | 发布媒体流 |
-| [unpublish](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#unpublish) | 取消发布媒体流 |
\ No newline at end of file
diff --git a/docs/private/media/one2one_android.md b/docs/private/media/one2one_android.md
deleted file mode 100644
index dbfa3035..00000000
--- a/docs/private/media/one2one_android.md
+++ /dev/null
@@ -1,698 +0,0 @@
-# Android集成1对1通话
-
-## 跑通Demo
-
-### 1. 示例代码
-
-- [下载 Android SDK + Demo 代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/easemob-sdk-3.7.6.3.zip)
-- [体验Demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/app-prod-release.apk)
-
-或进入环信[客户端下载](common_clientsdk.html#音视频sdk下载)页面,选择Android SDK + Demo下载
-
-### 2. 前提条件
-
-- Android Studio 3.0 或以上版本
-- Android SDK API 等级 19 或以上
-- Android 4.4 或以上版本的设备
-
-### 3. 运行Demo
-
-#### 3.1 Demo代码目录简介
-
-![img](/images/privitization/android_demo.png)
-源码目录如上所示,主要目录如以下介绍:
-- widget是有关所有Activity的具体实现
-- permission是有关运行是有关动态权限的获取的封装
-- untils是有关工具类的封装
-- DemoHelper和DemoApplication类是全局单例,用来做一些初始化
-
-#### 3.2 工程设置,SDK导入
-
-选择如下任意一种方式将环信语音SDK集成到你的项目中:
-
-**方法一:使用 JCenter 自动集成**
-
-在项目的 /app/build.gradle 文件中,添加如下行
-
-```
-dependencies {
- ...
- // x.x.x 请填写具体版本号,如:3.7.0
- // 可通过 SDK 发版说明取得最新版本号
- api 'com.hyphenate:hyphenate-sdk:x.x.x'
- }
-```
-
-**方法二:手动复制 SDK 文件**
-
-前往SDK载页面,获取最新版的环信音视频SDK,然后解压;
-将SDK包内libs路径下的如下文件,拷贝到你的项目路径下:
-- hyphenatechat_3.7.0.jar 文件 /app/libs/
-- arm-v8a 文件夹 /app/src/main/jniLibs/
-- armeabi-v7a 文件夹 /app/src/main/jniLibs/
-- x86文件夹 /app/src/main/jniLibs/
-- x86_64文件夹 /app/src/main/jniLibs/
-
-#### 3.3 运行项目
-
-用Android Studio 运行examples\ChatDemoUI3.0 或者 连接Android 手机,直接运行即可。
-需要注意的的是项目build.gradle中的,配置成和自己Android Studio相匹配的 gradle 版本,如下所示
-
-```
-dependencies {
- classpath 'com.android.tools.build:gradle:3.2.1'
- }
-```
-
-## 快速集成
-
-### 1. 环信后台注册AppKey
-
-环信为管理者与开发者提供了方便易用的App工作台– **环信管理后台**。
-通过环信管理后台可以完成应用创建、服务配置、企业信息修改基础功能;同时,管理后台也提供了发送消息、用户管理、群组管理、聊天室管理和数据统计等管理监控功能。
-在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。
-
-### 2. 创建项目
-
-- 打开 Android Studio点击Start a new Android Studio project;
-- 在Select a Project Template界面,选择 Phone and Tablet > Empty Activity;
-- 点击 Next;
-- 在 Configure Your Project界面,依次填入以下内容:Name:你的Android项目名称,如 HelloWrold;
-- Package name:你的项目包的名称,如 package.easemob.helloworld;
-- Save location:项目的存储路径;
-- Language:项目的编程语言,如 Java;
-- Minimum API level:项目的最低 API 等级;(**注意本SDK 支持API 19或以上**)
-- 点击 Finish;
-- 根据屏幕提示,安装可能需要的插件;
-上述步骤使用 Android Studio 3.6.2 示例,你也可以直接参考Android Studio 官网文档创建首个应用。
-
-### 3. 导入SDK到工程
-
-新建项目完成以后,可以选择以上任何一种导入SDK的方法,把环信音视频SDK集成到你的项目里面,参考[导入SDK](#_3-2-工程设置-sdk导入)。
-
-### 4. 添加权限
-
-根据场景需要,在 /app/src/main/AndroidManifest.xml 文件中添加如下行,获取相应的设备权限;
-在清单文件 AndroidManifest.xml 里加入以下权限,以及写上你注册的 AppKey;
-权限配置(实际开发中可能需要更多的权限,可参考 Demo);
-
-```
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ...
-
-```
-:::tip
-在创建应用后,获取EASEMOB_APPKEY对应的value
-:::
-
-
-```
- 申请 AppKey并进行相关配置,环信Demo中AppKey为easemob-demo#chatdemoui;
-```
-
-### 5. 打包混淆
-
-在 app/proguard-rules.pro 文件中添加如下行,防止混淆环信SDK的代码。
-
-```
--keep class com.hyphenate.** {*;}
- -dontwarn com.hyphenate.**
- //3.6.8版本之后移除apache,无需再添加
- -keep class internal.org.apache.http.entity.** {*;}
- //如果使用了实时音视频功能
- -keep class com.superrtc.** {*;}
- -dontwarn com.superrtc.**
-```
-
-### 6. 创建UI
-
-根据场景需要,为你的项目创建语音通话的用户界面。若已有界面,可以直接查看导入类;
-可以参考 Demo SDK示例项目的 [em_activity_voice_call.xml](https://github.com/easemob/sdkdemoapp3.0_android/blob/sdk3.0/app/src/main/res/layout/em_activity_voice_call.xml) 文件中的代码。
-
-### 7. 初始化SDK
-
-初始化环信SDK,可以参考使用DemoHelper中的init方法,可设置私有部署地址或者是否允许日志输出,调用如下:
-
-```
-public void init(Context context) {
- EMOptions options = initChatOptions(context);
- appContext = context;
- //可设置私有服务地址
- options.setRestServer("a.b.c");
- options.setIMServer("1.2.3.4");
- options.setImPort(8081);
- EMClient.getInstance().init(context, options);
- //打开日志输出
- EMCallManager manager = EMClient.getInstance().callManager();
- EMClient.getInstance().setDebugMode(true);
-}
-```
-
-### 8. 环信ID注册登录
-
-在进行音视频通话前,需要首先登录IM账户,登录过程参见[账号登录](http://doc.easemob.com/document/android/overview.html#%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95)。
-
-若您还没有IM账户,需要先注册账户,注册过程参见[账号注册](http://doc.easemob.com/document/android/overview.html#%E6%B3%A8%E5%86%8C%E7%94%A8%E6%88%B7)
-
-### 9. 音视频功能初始化
-
-账号登录成功后,需要进行音视频通话功能的初始化,设置监听类;
-主要有监听呼入通话和监听呼入通话状态;
-
-通过注册相应action的BroadcastReceiver来监听呼叫过来的通话,接到广播后开发者可以调起APP里的通话Activity;
-具体调用如下代码所示:
-
-```
-protected void setGlobalListeners(){
- IntentFilter callFilter = new IntentFilter(EMClient.getInstance().
- callManager().getIncomingCallBroadcastAction());
- if(callReceiver == null){
- callReceiver = new CallReceiver();
- }
- appContext.registerReceiver(callReceiver, callFilter);
- }
- private class CallReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- // 拨打方username String from = intent.getStringExtra("from");
- // call type String type = intent.getStringExtra("type"); //跳转到通话页面
- }
-}
-```
-
-
-通过addCallStateChangeListener监听通话状态,在onCreate里面增加这个监听,包括网络连接状态呼入电话状态,听电话状态等都可以在这监听。
-:::tip
-在收到 DISCONNECTED回调时才能finish当前页面保证通话所占用的资源都释放完,然后开始下一个通话;
-:::
-
-调用如下代码所示:
-
-```
-void addCallStateListener() {
- callStateListener = new EMCallStateChangeListener() {
-
- @Override
- public void EMCallStateChangeListener(CallState callState, final CallError error) {
- // Message msg = handler.obtainMessage();
- EMLog.d("EMCallManager", "onCallStateChanged:" + callState);
- switch (callState) {
- case CONNECTING: //正在连接
- break;
- case CONNECTED: //已经连接 等等状态
- break;
- .....
- }
-
- //增加监听
- EMClient.getInstance().callManager().addCallStateChangeListener(callStateListener);
- }
-```
-
-### 10. 发起通话请求
-
-当A方给B方进行视频通话时候,A可以调用下面三个方法中的任意一个来发起通话,后边两个是多参的。
-
-```
-try {//单参数
- EMClient.getInstance().callManager().makeVideoCall(username);
- } catch (EMServiceNotReadyException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- try {//多参数
- EMClient.getInstance().callManager().makeVideoCall(username,"ext 扩展内容");
- } catch (EMServiceNotReadyException e) {
- / / TODO Auto-generated catch block
- e.printStackTrace();
- }
- try {//多参数, recordOnServer:是否在服务器端录制该通话, mergeStream:服务器端录制时是否合并流
- EMClient.getInstance().callManager().makeVideoCall(username,"ext 扩展内容", recordOnServer, mergeStream);
- } catch (EMServiceNotReadyException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
-}
-```
-
-### 11. 接听通话
-
-当A方给B方进行视频通话时候,B可以调用下面的方法,去接通视频,B视频电话以后,A会收到上面已经注册好的EMCallStateChangeListener回调里边的 ACCEPTED 状态,表示B已经接通视频。
-
-```
-try {
-EMClient.getInstance().callManager().answerCall();
-} catch (EMNoActiveCallException e) {
-// TODO Auto-generated catch block
-e.printStackTrace();
-} catch (EMNetworkUnconnectedException e) {
-// TODO Auto-generated catch block
-e.printStackTrace();
-}
-```
-
-### 12. 拒绝通话
-
-当A方给B方进行通话时候,B可以调用下面的方法拒绝通话,B拒绝以后,A会收到上面已经注册好的EMCallStateChangeListener 回调里边的 DISCONNECTED 状态,具体原因为 CallError 中的 REJECTED 表示B拒绝视频。
-
-```
-try {
- EMClient.getInstance().callManager().rejectCall();
-
-} catch (EMNoActiveCallException e) {
-
- // TODO Auto-generated catch block
-
- e.printStackTrace();
-
-}
-```
-
-### 13. 结束通话
-
-A方给B方进行语音通话时候,通话过程中任意一方可以调用下面的方法去挂断电话,另一方会收到已经注册好的EMCallStateChangeListener回调里边的DISCONNECTED状态,
-具体原因为 CallError 中的 ERROR_NONE 表示对方正常挂断电话。
-
-```
-EMClient.getInstance().callManager().endCall();
-```
-
-## 进阶功能
-
-### 取日志
-
-SDK会写入日志文件到本地,日志文件路径如下:sdcard/Android/data/(自己App包名)/(appkey)/core_log/easemob.log。
-以Demo为例,通过adb命令获取本地的log:
-
-```
-adb pull /sdcard/Android/data/com.hyphenate.chatuidemo/easemob-demo#chatdemoui/core_log/easemob.log
-```
-
-### 通话中音视频控制
-
-#### 音频管理
-
-在视频通话过程中可以暂停和恢复语音传输,具体方法如下:
-A和B通话,当A停止或恢复语音传输时候,B会收到已经注册好的EMCallStateChangeListener回调里边的VOICE_PAUSE或者VOICE_RESUME状态,表示A的音频传输暂停或者恢复,
-方法如下所示:
-
-```
-暂停音频数据传输:
-EMClient.getInstance().callManager().pauseVoiceTransfer();
-恢复音频数据传输:
-EMClient.getInstance().callManager().resumeVoiceTransfer();
-```
-
-#### 视频管理
-
-在语音通话过程中可以暂停和恢复视频传输,具体方法如下:
-A和B通话,当A停止或恢复视频传输时候,B会收到已经注册好的 EMCallStateChangeListener回调里边的VIDEO_PAUSE 或者 VIDEO_RESUME 状态,表示A的音频传输暂停或者恢复。
-方法如下所示:
-
-```
-暂停视频数据传输:
-EMClient.getInstance().callManager().pauseVideoTransfer();
-恢复视频数据传输:
-EMClient.getInstance().callManager().resumeVideoTransfer();
-```
-
-#### 切换摄像头
-
-视频通话时如果有前置摄像头,默认使用前置的,提供切换 API 切换到后置或者前置摄像头。
-
-```
-EMClient.getInstance().callManager().switchCamera();
-```
-
-### 设置通话参数
-
-#### 最大音频码率
-
-通话之前,可以设置通话音频的最大音频码率,设置方法如下
-:::tip
-设置最大音频比特率,取值范围 6 ~ 510。
-:::
-
-
-```
-EMClient.getInstance().callManager().getCallOptions().setMaxAudioKbps(50);
-```
-
-#### 设置视频分辨率
-
-可以通过以下方法设置本地视频通话分辨率 默认是(640, 480),例如设置720P分辨率。
-
-```
-EMClient.getInstance().callManager().getCallOptions().setVideoResolution(1280, 720);
-```
-
-#### 设置通话最大帧率
-
-可以通过以下方法设置本地通话最大帧率,SDK 最大支持(30),默认(20),例如以下设置为25。
-
-```
-EMClient.getInstance().callManager().getCallOptions().setMaxVideoFrameRate(25);
-```
-
-#### 设置视频比特率
-
-可以通过以下方法设置视频通话最大和最小比特率(可以不设置,SDK会根据手机分辨率和网络情况自动适配),
-最大值默认800,最小值默认80
-
-```
-EMClient.getInstance().callManager().getCallOptions().setMaxVideoKbps(800);
-EMClient.getInstance().callManager().getCallOptions().setMinVideoKbps(80);
-```
-
-#### 设置流畅度或者清晰度优先
-
-可以通过以下方法设置视频流畅度优先还是清晰度优先(true 为清晰度优先,false为流畅度优先)。
-
-```
-EMClient.getInstance().callManager().getCallOptions().setClarityFirst(true);
-```
-
-### 离线推送
-
-**场景描述**:A,B都开启离线推送后,当A呼叫B,而B离线时,B会收到推送消息,点击推送消息可以打开APP,进入通话页面(true推送,false不推送)。
-目前小米、魅族、OPPO、VIVO推送的主要实现集成在了环信 IM SDK 中,尽量提供给开发者最简单的集成三方推送的形式。
-Google FCM 和华为推送的实现仍在 Demo 层,需要开发者自己集成,详情请参考环信的 Google FCM 和华为的推送集成文档,有个集成, 关于第三方推送集成,大家可以参考:[设置推送](https://docs-im.easemob.com/im/android/push/thirdpartypush)。
-
-```
-//开启离线推送
- EMClient.getInstance().callManager().getCallOptions().setIsSendPushIfOffline(true);
-```
-
-### 云端录制
-
-呼叫方呼叫时可以指定是否开启服务器录制,如要录制,
-使用以下方法呼叫(recordOnServer 是否在服务器端录制该通话 ; mergeStream 服务器端录制时是否合并流)。
-
-```
-EMClient.getInstance().callManager().makeVoiceCall(username, "", recordOnServer , mergeStream);
-```
-
-### 通话统计数据
-
-通话数据的数据统计功能,
-可以从保存的会话callSession中获取到通话的实时码率、帧率、分辨率等数据。
-
-### 弱网监测
-
-语音通话中会实时监测通话网络状态,有变化时通过回调通知应用,
-会收到已经注册好的 EMCallStateChangeListener中有关网络状态的回调,有以下几种状态。
-
-```
-enum CallState{
- NETWORK_UNSTABLE("network_unstable"), //网络不稳定,丢包率较高的场景下提示
- NETWORK_NORMAL("network_normal"), //网络正常
- NETWORK_DISCONNECTED("network_disconnected"); //对方的视频流断开,一般是断网或者app被kill等
-};
-enum CallError{
- ERROR_TRANSPORT("error_transport"),
- ERROR_UNAVAILABLE("error_unavailable"),
- ERROR_NO_DATA("error_no_data"),//传输无数据
-};
-```
-
-### 本地视频镜像显示
-
-设置本地view预览是否开启镜像显示,前置摄像头默认为开启镜像。
-
-```
-EMClient.getInstance().callManager().getCallOptions().setLocalVideoViewMirror(EMMirror.OFF);
-```
-
-### 变声/自定义音频
-
-#### 开启外边音频输入
-
-用户使用自定义音频数据时,需要配置外部输入音频数据的开关,以及音频采样率,通道数(当前通道数只支持1),开启方式如下(true 为开启,false为不开启)。
-
-```
-EMClient.getInstance().callManager().getCallOptions().setExternalAudioParam(true, 44100,1);
-```
-
-#### 输入音频数据
-
-音频数据采集可参考Demo中的ExternalAudioInputRecord.java类实现,音频数据的输入必须在会话接通后开始,否则会导致网络阻塞,影响通话质量。
-建议用户将音频数据采集的开始放在会话接通的回调及callDidAccept回调中。
-
-```
-callStateListener = new EMCallStateChangeListener() {
-
- @Override
- public void onCallStateChanged(CallState callState, final CallError error) {
- case ACCEPTED:
- //启动外部音频输入
- if(PreferenceManager.getInstance().isExternalAudioInputResolution()){
- ExternalAudioInputRecord.getInstance().startRecording();
- }
- ....
- break;
- }
-```
-
-音频采集过程参考Demo中的ExternalAudioInputRecord类实现,音频采集过程开始后,在音频数据采集线程里调用外部输入音频数据接口,具体参考Demo中的实现。
-
-```
-EMClient.getInstance().conferenceManager().inputExternalAudioData(byteBuffer.array(), byteBuffer.capacity());
-```
-
-#### 停止音频输入
-
-会话挂断时,停止音频采集及输入过程
-
-```
-if(PreferenceManager.getInstance().isExternalAudioInputResolution()){
- ExternalAudioInputRecord.getInstance().stopRecording();
- }
-```
-
-### 美颜/自定义视频
-
-如果用户需要自己采集特定的数据或者对于数据需要先进行一些处理,可以使用SDK的外部输入数据的方法进行。
-例如:如果想要使用美颜等功能,需要用户使用系统的摄像头,然后启动监听系统设备,获取到数据后进行处理,处理后再调用我们输入数据的api发布出去。
-使用自定义视频接口如下:开启外边视频输入;
-用户使用自定义视频数据时,需要配置外部输入数据数据的开关(true 为开启,false为不开启)。
-
-```
-EMClient.getInstance().callManager().getCallOptions().setEnableExternalVideoData(true);
-```
-
-输入视频数据
-
-然后就是自己获取视频数据,进行美颜等处理,循环调用以下方法输入数据就行了,
-这个调用频率就相当于你的帧率,调用间隔可以自己进行控制,一般最大30帧/秒)
-输入视频数据的方法如下:
-
-```
-/**
- *
- * 视频数据的格式是摄像头采集的格式即:NV21 420sp 自己手动传入时需要将自己处理的数据转为 yuv 格式输入
- */
- EMClient.getInstance().callManager().inputExternalVideoData(data, width, height, rotate);
-```
-
-### 视频水印
-
-在Android系统可以将图片资源设置为视频流的水印。首先将图片资源转换为Bitmap对象,
-然后设置WaterMarkOption中的属性,比如位置,分辨率及距离边缘的margin等。
-
-```
-try {
- InputStream in = this.getResources().getAssets().open("watermark.png");
- watermarkbitmap = BitmapFactory.decodeStream(in);
-} catch (Exception e) {
- e.printStackTrace();
-}
-watermark = new WaterMarkOption(watermarkbitmap, 75, 25, WaterMarkPosition.TOP_RIGHT, 8, 8);
-//设置水印
-EMClient.getInstance().callManager().setWaterMark(watermark);
-```
-
-
-### 私有部署
-
-私有部署设置方法参见[私有云 Android SDK集成配置](../im/uc_android_private.md)。
-
-## 客户端API
-
-1V1音视频通话的API包括以下接口
-
-- EMCallOptions 视频通话配置类
-- EMACallManager 视频通话的主要管理类,提供了语音通话的拨打、接听、挂断等接口
-- EMCallStateChangeListener 视频通话的监听回调类,实时语音通话相关的回调
-- EMCallSession 视频通话的会话实例接口类
-- EMVideoCallHelper 视频通话获取通话统计信息类
-- EMCallSurfaceView 视频通话UI显示视图类
-- EMWaterMarkOption 视频通话水印对象类
-- EMWaterMarkPosition 视频通话水印位置设置类
-
-### EMCallOptions
-
-| 方法 | 描述 |
-| :----------------------------------------------------------- | :-------------------------------------------- |
-| [pingInterval](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#adcda2ab5ab431592ef906983c8a9df26) | 心跳时间间隔,单位秒,默认30s,最小10s |
-| [setIsSendPushIfOffline](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a8f99a36fbbb6190a2f911d5e9d8ee331) | 被叫方不在线时,是否开启推送 |
-| [setLocalVideoViewMirror](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a4cb1cfe6a11e21a99eb28df1c660c9da) | 是否开启镜像模式 |
-| [setMaxAudioKbps](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a90b11b4c40bbbc4757287efdb8312ec4) | 最大音频码率 |
-| [setIsSendPushIfOffline](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a0acf32a7afc578f477a3dbb6272c93ae) | 是否开启外部音频输入 |
-| [setAudioSampleRate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#ae7725792786081e688e785c910f98e03) | 自定义音频数据的采样率,默认48000 |
-| [setRotation](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a94d9a6abe6925507eac4451b31c460cf) | 设置视频旋转角度,启动前和视频通话中均可设置 |
-| [setEnableExternalVideoData](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#abd8146585edd2f4f38dcfdb8ae50f619) | 是否开启外部输入视频 |
-| [setVideoResolution](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a10ffc50fd622524d2e07def0c9e602f9) | 设置传输视频分辨率 |
-| [setMaxVideoKbps](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a237df350c5e19dbb5f596b6d78e895fb) | 设置最大视频码率 |
-| [setMinVideoKbps](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a7ab32f5b511ee467a727e943a08ff2a9) | 设置最小视频码率 |
-| [setMaxVideoFrameRate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a334a5bfb414903da4b919539eac4dde4) | 设置最大的视频帧率 |
-| [setUse2channelsInput](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a334a5bfb414903da4b919539eac4dde4:~:text=setUse2channelsInput) | 是否开启双声道,当前只支持单通道,必须为false |
-| [setClarityFirst](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a334a5bfb414903da4b919539eac4dde4:~:text=void%20com.hyphenate.chat.EMCallOptions.setClarityFirst) | 设置清晰度还是流畅度优先 |
-
-### EMACallManager
-
-| 方法 | 描述 |
-| :----------------------------------------------------------- | :------------------------------------------- |
-| [addCallStateChangeListener](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a80b224a48a9019501bc724c5ff65a267) | 增加通话监听 |
-| [removeCallStateChangeListener](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#ab2023190fb75c661343e0b0b8443ab29) | 移除通话监听 |
-| [setPushProvider](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#ab186d489c2779e2984498f79b63432fd) | 添加离线推送回调代理,该代理只能设置一个 |
-| [pauseVoiceTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a13470d6e6725c31285f97b4ed0b7217e) | 暂停音频数据传输 |
-| [resumeVoiceTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#ae294c324c0fa3a08e83111c3cb5207b1) | 恢复音频数据传输 |
-| [pauseVideoTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 暂停视频数据传输 |
-| [resumeVideoTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a4c0c6ba346d7432185d49dc594c5fe72) | 恢复视频数据传输 |
-| [muteRemoteAudio](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19d8c3b170bed1359226861f45be39d9) | mute远端音频 |
-| [muteRemoteVideo](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#ac0ec72a6bbd6f19f8c78f28df6b0cb20) | mute远端视频 |
-| [makeVideoCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a3e49344c1ff527960e8978f2ba6858db) | 发起视频通话(有多参数方法,可选择是否录制) |
-| [makeVoiceCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a0dab7508a3592c17c2d3c4023c73c3d3) | 发起语音通话(有多参数方法,可选择是否录制) |
-| [setSurfaceView](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a1d49e876527c6e79e25ffe4ee19516f8) | 设置视频通话本地和对端视频显示视图 |
-| [isDirectCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a866daea70ddec39101b7da293f254eb9) | 当前通话时是否为P2P直连 |
-| [setCameraFacing](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a2982d7b6c6f870568b0fdd2bc6e487c2) | 开启相机拍摄 |
-| switchCamera | 切换前后摄像头 |
-| [inputExternalVideoData](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a75c1911842e876ffe2cff7619072e7e1) | 外部输入视频数据(有多参方法) |
-| [inputExternalAudioData](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a1dd9ce23f11e6e7aff53d1e151396368) | 自定义外部音频数据 |
-| setWaterMark | 通话设置水印 |
-| [answerCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a51fa517af552f757d716c29492a11064) | 接受方同意通话请求 |
-| [endCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a1e48d8764d6ffa3b0fc26ea29dca8689) | 结束通话 |
-| getCallOptions | 获取视频通话配置 |
-| getVideoCallHelper | 获取视频通话统计信息 |
-| getCallState | 获取当前通话状态 |
-| getCurrentCallSession | 获取当前通话Session |
-
-### EMCallStateChangeListener
-
-| CallState 回调状态 | 描述 |
-| :----------------------------------------------------------- | :----------------------------------------------------------- |
-| [CONNECTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallState.html#a4d71b0fb259693e52a4a5edb27971eb7) | 通话通道建立完成,用户A和用户B都会收到这个回调 |
-| [ACCEPTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallState.html#a6904d6921621f2f91cb1ac9fecbe871e) | 用户B同意用户A拨打的通话后,用户A和B会收到这个回调 |
-| [DISCONNECTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallState.html#a9d270eeeddaedf1259c127d0e563f41b) | 用户A或用户B结束通话后 或者 通话出现错误,双方都会收到该回调 |
-| [VOICE_PAUSE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户A和用户B正在通话中,用户A中断音频传输时,用户B会收到该回调 |
-| [VOICE_RESUME](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户A和用户B正在通话中,用户A中恢复音频传输时,用户B会收到该回调 |
-| [VIDEO_PAUSE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户A和用户B正在通话中,用户A中断视频传输时,用户B会收到该回调 |
-| [VIDEO_RESUME](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户A和用户B正在通话中,用户A中恢复视频传输时,用户B会收到该回调 |
-| [NETWORK_UNSTABLE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户网络状态不可用 |
-| [NETWORK_NORMAL](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户网络状态正常 |
-| [NETWORK_DISCONNECTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户网络状态断开 |
-
-| CallError 回调状态 | 描述 |
-| :----------------------------------------------------------- | :----------------------------------------------------- |
-| [ERROR_NONE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#a05e939dde5b09411416d444918cc46df) | 用户正常挂断或者结束通话 |
-| [ERROR_TRANSPORT](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#a9d445232fbf19ab6b97999ecf3432c0b) | P2P连接失败 |
-| [ERROR_UNAVAILABLE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#ad9aa8a289a588b0c4ecea5ceb81bd047) | P2P连接不可用 |
-| [REJECTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#a9b6779b9b6d22aefc61d626b480db2af) | 用户A拨打用户B,用户B拒绝语音通话,用户A会收到这个回调 |
-| [ERROR_BUSY](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#aabd50d9ec74067b4a02aa9421239912f) | 用户A拨打用户B,用户B忙线中 |
-| [ERROR_NO_DATA](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#ac53371aa3c3342b8dab4fea366df51af) | 无音频数据传输状态 |
-
-### EMCallPushProvider
-
-| 回调事件 | 描述 |
-| :----------------------------------------------------------- | :----------------------------------------------------------- |
-| [onRemoteOffline](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1chat_1_1EMCallManager_1_1EMCallPushProvider.html#a2f7eb2e385bb767d19c523e35541b7b0) | 用户A给用户B拨打实时通话,用户B不在线,并且用户A启用了推送功能,则用户A会收到该回调 |
-
-### EMCallSession
-
-| 方法 | 描述 |
-| :---------------- | :--------------------- |
-| getCallId | 获取会话标识符 |
-| getLocalName | 获取通话本地的username |
-| getType | 获取通话的类型 |
-| getIscaller | 是否为主叫方 |
-| getRemoteName | 获取对方的username |
-| getConnectType | 连接类型 |
-| isRecordOnServer | 是否启用服务器录制 |
-| getServerRecordId | 获取录制ID |
-| getExt | 获取消息扩展 |
-
-### EMVideoCallHelper
-
-| 方法 | 描述 |
-| :----------------------------------------------------------- | :--------------------- |
-| [setPreferMovFormatEnable](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#ae195a239bbdae089eaa88bb55982dd55) | 录制的视频文件的路径 |
-| [getVideoLatency](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a433e891df1e8fbb2e8535c744cecba3e) | 视频发送时延 |
-| [getVideoFrameRate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#ac83387d292e78d7d9fca7c5a8820385f) | 视频帧率 |
-| [getVideoLostRate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a0fff93c903d00dcf03d79410cb68a1bb) | 每一百个包中丢包个数 |
-| [getVideoWidth](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a0d5a9060d753f057228b5f1bb17382fd) | 对端视频宽度 |
-| [getVideoHeight](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#ac9987c9e7f672feadc600edcc11312d0) | 对端视频高度 |
-| [getRemoteBitrate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a9f025b264ccc6adfefd66ec7c278de41) | 接收视频比特率(kbps) |
-| [getLocalBitrate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a6c10265ec15af009a0b21017652edc1a) | 发送视频比特率(kbps) |
-| [getLocalAudioBitrate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#af76d7ce55e0121872f2d2b62f071ffaf) | 发送音频比特率(kbps) |
-| [getRemoteAudioBitrate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a490453dbb94cc50750f654c5dde8b170) | 接收音频比特率 (kbps) |
-
-### EMWaterMarkOption
-
-| 方法 | 描述 |
-| :------------- | :-------------------------- |
-| setMarkImg | 水印图片资源 (格式为bitmap) |
-| setOrientation | 水印位置 |
-| setHeight | 水印高度 |
-| setWeight | 水印宽度 |
-| setwMargin | 距离边缘水平距离 |
-| sethMargin | 距离边缘垂直距离 |
-
-### EMWaterMarkPosition
-
-| 方法 | 描述 |
-| :----------- | :----- |
-| TOP_LEFT | 左上角 |
-| TOP_RIGHT | 右上角 |
-| BOTTOM_LEFT | 左下角 |
-| BOTTOM_RIGHT | 右下角 |
\ No newline at end of file
diff --git a/docs/private/media/one2one_introduction.md b/docs/private/media/one2one_introduction.md
deleted file mode 100644
index c5d6a24b..00000000
--- a/docs/private/media/one2one_introduction.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# 1对1通话简介
-
-## 适用场景
-
-1对1通话API用于实现1对1语音通话和1对1视频通话,典型场景包括社交交友,远程心理咨询、远程医疗、一对一在线教育、远程视频辅助等。
-
-其API设计思想类似于传统的电话通话,呼叫过程使用了即时通讯的消息机制,所以和即时通讯功能是紧耦合的。
-
-## 功能列表
-
-| 功能 | android 原生 | iOS 原生 | Web | PC桌面 |
-| :------------- | :----------- | :------- | :----- | :----- |
-| 1对1音频通话 | 支持 | 支持 | 支持 | 支持 |
-| 1对1视频通话 | 支持 | 支持 | 支持 | 支持 |
-| 静音自己 | 支持 | 支持 | 支持 | 支持 |
-| 不听他人 | 支持 | 支持 | 支持 | 支持 |
-| 外部视频源输入 | 支持 | 支持 | 不支持 | 不支持 |
-| 伴音 | 支持 | 支持 | 不支持 | 不支持 |
-| 视频流水印 | 支持 | 支持 | 不支持 | 不支持 |
-| 开启云录制 | 支持 | 支持 | 支持 | 支持 |
-
-:::tip
-1对1通话场景,也可以用多人通话API来实现,开发者使用即时通讯消息机制来实现呼叫应答等。
-:::
-
-## 通话流程
-
-- 发起方调用SDK接口发起呼叫
-- 接收方收到SDK回调通知“收到一个呼叫”,展示振铃页面
-- 接收方用户点击接听按钮,调用SDK接口接听
-- 发起方收到SDK回调通知“对方已接听”,展示通话界面,双方开始通话
-- 一方调用SDK接口挂断通话,另一方收到SDK回调“对方挂断”,结束通话
-
-## 客户端下载
-
-[>>下载音视频SDK及Demo](common_clientsdk.html#音视频sdk下载)
-
-体验Demo:打开Demo,打开联系人,选择视频通话或语音通话,即可体验。
-
-![img](/images/privitization/1v1-demo.png)
-
-## 计费说明
-
-环信私有化音视频服务计费规则及功能详情,请联系商务经理程先生(Tel:17611319060)
\ No newline at end of file
diff --git a/docs/private/media/one2one_ios.md b/docs/private/media/one2one_ios.md
deleted file mode 100644
index ea98d977..00000000
--- a/docs/private/media/one2one_ios.md
+++ /dev/null
@@ -1,694 +0,0 @@
-# iOS集成1对1通话
-
-## 跑通Demo
-
-### 1. 示例代码
-
-- [下载 iOS SDK + Demo 代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/iOS_IM_SDK_V3.7.4.7.zip)
-
-或进入环信[客户端下载](common_clientsdk.html#音视频sdk下载)页面,选择iOS SDK + Demo下载
-
-### 2. 前提条件
-
-运行Demo前你需要具备以下条件
-
-- mac操作系统10.11以上
-- 安装Xcode 11以上
-- iPhone设备iPhone 6以上,安装系统iOS 9.0以上
-
-### 3. 运行Demo
-
-#### 3.1 Demo代码目录简介
-
-目录 EaseIM —>Class 中的 Demo 目录介绍
-
-![img](/images/privitization/ios_demo.png)
-
-- Account:主要是 demo 的注册,登录
-- AppDelegate:主要是 demo 中初始化环信SDK,注册推送等
-- Chat:demo 的聊天功能页面
-- Contact:demo 的好友功能页面
-- Conversation:demo 的会话列表功能页面
-- EMIMHelper:demo 的单例类,包含全局监听接收消息,好友,群组,聊天室等相关事件的回调,从而进行对应的处理
-- Group:demo 的群组功能页面
-- Helper:demo 的功能性文件,全局通用的配置
-- Home:demo 的根控制器页面
-- Settings:demo 的功能设置页面
-
-#### 3.2 工程设置
-
-进入iOS Demo目录,打开EMiOSDemo.xcworkspace ,进入工程设置的Signing & Capaabilities菜单,修改签名Team和bundleId为自己的团队开发。
-
-#### 3.3 运行
-
-连接iPhone手机,选择目标设备,点击运行
-
-## 快速集成
-
-本章节介绍如何使用HyhpenateSDK 快速实现1v1音视频通话
-
-### 1. 环信后台注册appkey
-
-在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。
-
-### 2. 创建项目
-
-参考以下步骤创建一个iOS 应用项目,如果已有项目,可以直接进行下一步集成。创建过程如下:
-
-- 打开 Xcode 并点击 Create a new Xcode project。
-- 选择项目类型为 Single View App,并点击 Next。
-- 输入项目信息,如项目名称、开发团队信息、组织名称和语言,语言为Object-C,并点击 Next。
-- 选择项目存储路径,并点击 Create。
-- 进入工程设置页面的Signing & Capaabilities菜单,选择 Automatically manage signing,并在弹出菜单中点击 Enable Automatic
-
-### 3. 导入SDK到工程
-
-集成SDK有两种方法,分别是使用cocoapods和手动导入SDK
-
-#### 使用cocoapods导入SDK
-
-开始前确保你已安装 Cocoapods。
-
-- 在 Terminal 里进入项目根目录,并运行 pod init 命令。项目文件夹下会生成一个 Podfile 文本文件。
-- 打开 Podfile 文件,修改文件为如下内容。注意将 AppName 替换为你的 Target 名称,并将 version 替换为你需集成的 SDK 版本,如3.7.0。
-
-```
-target 'AppName' do
- pod 'Hyphenate', '~> version'
-end
-```
-
-- 在 Terminal 内运行 pod update 命令更新本地库版本。
-- 运行 pod install 命令安装 Agora SDK。成功安装后,Terminal 中会显示 Pod installation complete!,此时项目文件夹下会生成一个 xcworkspace 文件。
-- 打开新生成的 xcworkspace 文件。
-
-#### 手动导入SDK
-
-- 将在跑通Demo阶段下载的HyphenateFullSDK下的Hyphenate.framework拷贝到项目工程目录下
-- 打开工程设置/Genaral菜单下,将Hyphenate.framework拖拽到Frameworks,libraries,and Embedded Content下,并设置为Embed and Signed
-
-工程中引入SDK,需要引用头文件Hyphenate.h
-
-```
-#import
-```
-
-### 4. 添加权限
-
-应用需要音频设备及摄像头权限,在 info.plist 文件中,点击 + 图标,添加如下信息
-
-| Key | Type | Value |
-| :------------------------------------- | :----- | :----------------------------------- |
-| Privacy - Microphone Usage Description | String | 描述信息,如“环信需要使用您的麦克风” |
-| Privacy - Camera Usage Description | String | 描述信息,如“环信需要使用您的摄像头” |
-
-如果希望在后台运行,还需要添加后台运行音视频权限,在info.plist文件中,点击 + 图标,添加Required background modes,Type为Array,在Array下添加元素App plays audio or streams audio/video using AirPlay
-
-### 5. 创建UI
-
-音视频通话窗口中,一般包括以下几个UI控件
-
-- 暂停/恢复语音按钮
-- 结束通话按钮
-- 扬声器/耳机切换按钮
-- 后置摄像头切换按钮(视频)
-- 打开/关闭摄像头按钮(视频)
-- 本地图像显示与对端图像显示(视频)
-
-通话界面可以参考Demo中Call1v1VideoViewController,效果如下:
-
-![img](/images/privitization/1v1video.png)
-
-### 6. 初始化SDK
-
-初始化HyhpenateSDK使用initializeSDKWithOptions:接口,需要设置自己的appkey,调用如下:
-
-```
-// 这里替换成自己的appkey
-EMOptions *retOpt = [EMOptions optionsWithAppkey:@"easemob-demo#chatdemoui"];
-// 这里打开日志输出
-retOpt.enableConsoleLog = YES;
-[[EMClient sharedClient] initializeSDKWithOptions:retOpt];
-```
-
-### 7. 环信ID注册、登录
-
-在进行音视频通话前,需要首先登录IM账户,登录过程参见[账号登录](http://doc.easemob.com/document/ios/overview.html#%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95)。
-
-若您还没有IM账户,需要先注册账户,注册过程参见[账号注册](http://doc.easemob.com/document/ios/overview.html#%E6%B3%A8%E5%86%8C%E7%94%A8%E6%88%B7)
-
-### 8. 音视频功能初始化
-
-账号登录成功后,需要进行音视频通话功能的初始化,设置监听类
-
-```
-[[EMClient sharedClient].callManager addDelegate:self delegateQueue:nil];
-```
-
-### 9. 发起通话请求
-
-主叫方发起呼叫通话请求的过程如下:
-
-```
-[[EMClient sharedClient].callManager startCall:EMCallTypeVideo
- remoteName:aUsername
- ext:@"123"
- completion:^(EMCallSession *aCallSession, EMError *aError) {
- self.callSession = aCallSession;
-}];
-```
-
-回调的aCallSession为本次会话session,需要在本地保存下来。
-
-在发起视频通话,等待对方接听过程中,已经可以显示本地图像,显示本地图像的过程如下
-
-```
-self.callSession.localVideoView = [[EMCallLocalView alloc] init];
- self.callSession.localVideoView.scaleMode = EMCallViewScaleModeAspectFill;
- [self.minVideoView addSubview:self.callSession.localVideoView];
- [self.view bringSubviewToFront:self.minVideoView];
- [self.callSession.localVideoView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.edges.equalTo(self.minVideoView);
- }];
-```
-
-主叫方发起通话请求后,被叫方若已登录,将会收到如下回调通知
-
-```
-- (void)callDidReceive:(EMCallSession *)aSession
-{
- self.callSession = aSession;
-}
-```
-
-aSession为本次通话的session,被叫方应该在本地保存。
-
-### 10. 接听通话
-
-被叫方在收到通话请求回调后,可以选择接听/拒绝通话,若选择接听通话,调用如下:
-
-```
-[[EMClient sharedClient].callManager answerIncomingCall:self.callSession.callId];
-```
-
-此时被叫方可以显示本地视频图像
-
-```
-self.callSession.localVideoView = [[EMCallLocalView alloc] init];
- self.callSession.localVideoView.scaleMode = EMCallViewScaleModeAspectFill;
- [self.minVideoView addSubview:self.callSession.localVideoView];
- [self.view bringSubviewToFront:self.minVideoView];
- [self.callSession.localVideoView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.edges.equalTo(self.minVideoView);
- }];
-```
-
-当通话接通后,双方会收到callDidAccept回调通知,在这里可以设置远端图像
-
-```
-if (self.callSession.remoteVideoView == nil) {
- self.callSession.remoteVideoView = [[EMCallRemoteView alloc] init];
- self.callSession.remoteVideoView.backgroundColor = [UIColor clearColor];
- self.callSession.remoteVideoView.scaleMode = EMCallViewScaleModeAspectFit;
- self.callSession.remoteVideoView.userInteractionEnabled = YES;
- }
-```
-
-### 11. 拒绝通话
-
-被叫方收到呼叫请求后,可以选择拒绝通话,调用过程如下:
-
-```
-[[EMClient sharedClient].callManager endCall:self.callSession.callId reason:EMCallEndReasonDecline];
-```
-
-拒绝后,主叫方收到如下回调, aReason为EMCallEndReasonDecline
-
-```
-- (void)callDidEnd:(EMCallSession *)aSession
- reason:(EMCallEndReason)aReason
- error:(EMError *)aError
-```
-
-### 12. 结束通话
-
-通话中双方随时都可以结束通话,调用过程如下:
-
-```
-[[EMClient sharedClient].callManager endCall:@"callId" reason:EMCallEndReasonHangup];
-```
-
-结束后双方收到以下回调:
-
-```
-- (void)callDidEnd:(EMCallSession *)aSession
- reason:(EMCallEndReason)aReason
- error:(EMError *)aError
-```
-
-## 进阶功能
-
-在实现基本视频通话的基础上,SDK提供更为丰富的API,可以实现更为复杂的音视频通话场景
-
-### 取日志
-
-SDK会写入日志文件到本地。日志文件路径如下:沙箱Documents/HyphenateSDK/easemoblog,以真机为例,获取过程如下:
-
-- 打开Xcode连接设备,前往Xcode –> Window –> Devices and Simulators
-- 进入Devices选项卡,在左侧选择目标设备,界面如下:
-
-[![img](https://docs-im.easemob.com/_media/rtc/one2one/fetchlogfile.png?w=400&tok=6c005b)](https://docs-im.easemob.com/_detail/rtc/one2one/fetchlogfile.png?id=rtc%3Aone2one%3Aios)
-
-日志文件easemob.log文件在下载包内容的AppData/Library/Application Support/HyphenateSDK/easemobLog目录下
-
-### 音视频控制
-
-使用通话过程中保存的EMCallSession的对象,可以分别进行音频、视频的开关控制,切换前后摄像头等操作,操作过程如下
-
-```
-/*!
- * 暂停语音数据传输
- *
- * @result 错误
- */
-- (EMError *)pauseVoice;
-
-// 调用:
-[aCallSession pauseVoice];
-
-/*!
- * 恢复语音数据传输
- *
- * @result 错误
- */
-- (EMError *)resumeVoice;
-
-// 调用:
-[aCallSession resumeVoice];
-
-/*!
- * 暂停视频图像数据传输
- *
- * @result 错误
- */
-- (EMError *)pauseVideo;
-
-// 调用:
-[aCallSession pauseVideo];
-
-/*!
- * 恢复视频图像数据传输
- *
- * @result 错误
- */
-- (EMError *)resumeVideo;
-
-// 调用:
-[aCallSession resumeVideo];
-```
-
-通话过程中可以切换前后摄像头
-
-```
-#pragma mark - Camera
-
-/*!
- * 设置使用前置摄像头还是后置摄像头,默认使用前置摄像头
- *
- * @param aIsFrontCamera 是否使用前置摄像头, YES使用前置, NO使用后置
- */
-- (void)switchCameraPosition:(BOOL)aIsFrontCamera;
-
-// 调用:
-[aCallSession switchCameraPosition:YES];
-```
-
-当通话一方进行音频、视频的开关控制时,另一方会收到如下回调通知
-
-```
-/*!
- * 用户A和用户B正在通话中,用户A中断或者继续数据流传输时,用户B会收到该回调
- *
- * @param aSession 会话实例
- * @param aType 改变类型
- */
-- (void)callStateDidChange:(EMCallSession *)aSession
- type:(EMCallStreamingStatus)aType;
-```
-
-### 设置通话参数
-
-通话之前,可以设置音频通话的最大音频码率,最小视频码率、最大视频码率、分辨率和是否清晰度优先,设置方法如下
-
-```
-EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
-options.maxAudioKBps = 32;
-options.maxVideoKBps = 3000;
-options.minVideoKBps = 500;
-options.maxVideoFrameRate = 20;
-options.videoResolution = EMCallVideoResolution352_288;
-options.isClarityFirst = YES;//若设为清晰度优先,将在弱网环境下保证视频的分辨率
-```
-
-### 离线推送
-
-iOS离线推送分为pushKit强推送和APNs普通推送,开启离线推送需要上传推送证书,参见[APNs推送证书上传](http://docs-im.easemob.com/im/ios/apns/deploy)和[pushKit推送集成](http://docs-im.easemob.com/knowledge/pushkit)
-
-配置属性(在登录环信服务器成功之后设置)
-
-```
-EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
-//当对方不在线时,是否给对方发送离线消息和推送,并等待对方回应
-options.isSendPushIfOffline = YES;
-[[EMClient sharedClient].callManager setCallOptions:options];
-```
-
-协议
-
-```
-
-```
-
-添加代理
-
-```
-[[EMClient sharedClient].callManager setBuilderDelegate:self];
-```
-
-监听回调
-
-```
-- (void)callRemoteOffline:(NSString *)aRemoteName
-{
- NSString *text = [[EMClient sharedClient].callManager getCallOptions].offlineMessageText;
- EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:text];
- NSString *fromStr = [EMClient sharedClient].currentUsername;
- EMMessage *message = [[EMMessage alloc] initWithConversationID:aRemoteName from:fromStr to:aRemoteName body:body ext:@{@"em_apns_ext":@{@"em_push_title":text}}];
- message.chatType = EMChatTypeChat;
- // 通过消息的ext来自定义提示铃声,其中customSound.caf为自定义铃声名称
- message.ext = @{
- @"em_apns_ext":@{
- @"em_push_sound":@"customSound.caf"
- }
- };
- [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:nil];
-}
-```
-
-因为该消息为提示铃声,所以使用自定义铃声来播放,时长需要控制在30秒以内,此处可以参考文档[自定义铃声](http://docs-im.easemob.com/im/ios/apns/content#自定义推送提示音)
-
-协议,代理,回调方法建议写到工程的根控制器或者appdelegate中监听,起到全局监听的作用。
-
-### 云端录制
-
-主叫方呼叫时可以指定是否开启服务器录制,如要录制,使用以下方法呼叫,isRecord输入YES,isMerge为是否录制合流,根据需要进行设置
-
-```
-- (void)startCall:(EMCallType)aType
- remoteName:(NSString *)aRemoteName
- record:(BOOL)isRecord
- mergeStream:(BOOL)isMerge
- ext:(NSString *)aExt
- completion:(void (^)(EMCallSession *aCallSession, EMError *aError))aCompletionBlock;
-```
-
-### 通话统计数据
-
-通话数据的统计功能需要主动开启,开启方法为在通话前进行如下设置
-
-```
-EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
-options.enableReportQuality = YES;
-```
-
-开启后可以从保存的会话callSession中获取到通话的实时码率、帧率、分辨率等数据
-
-### 弱网检测
-
-SDK提供实时检测通话网络质量的功能,同样需要开启通话数据统计,开启方法同上。开启后,可以通过回调通知应用当前实时通话网络状态。
-
-```
-typedef enum{
- EMCallNetworkStatusNormal = 0, /*! 正常 */
- EMCallNetworkStatusUnstable, /*! 不稳定 */
- EMCallNetworkStatusNoData, /*! 没有数据 */
-}EMCallNetworkStatus;
-
-/*!
- * 用户A和用户B正在通话中,用户A的网络状态出现不稳定,用户A会收到该回调
- *
- * @param aSession 会话实例
- * @param aStatus 当前状态
- */
-- (void)callNetworkDidChange:(EMCallSession *)aSession
- status:(EMCallNetworkStatus)aStatus
-```
-
-### 变声/自定义音频
-
-用户可以通过自己采集音频数据,使用外部输入音频数据的接口进行通话,从而实现变声等音频数据加工功能
-
-##### 配置属性
-
-用户使用自定义音频数据时,需要配置外部输入音频数据的开关,以及音频采样率,通道数(当前通道数只支持1),配置方法如下:
-
-```
-EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
-options.enableCustomAudioData = YES;
-options.audioCustomSamples = 48000;
-options.audioCustomChannels = 1;
-[[EMClient sharedClient].callManager startCall:aType remoteName:aUsername ext:@"123" completion:^(EMCallSession *aCallSession, EMError *aError) {
- completionBlock(aCallSession, aError);
-}];
-```
-
-##### 输入音频数据
-
-音频数据采集可参考Demo中的AudioRecord类实现,音频数据的输入必须在会话接通后开始,否则会导致网络阻塞,影响通话质量。建议用户将音频数据采集的开始放在会话接通的回调里,及callDidAccept回调中
-
-```
-- (void)callDidAccept:(EMCallSession *)aSession
-{
- if ([aSession.callId isEqualToString:self.currentCall.callId]) {
- [self _stopCallTimeoutTimer];
- self.currentController.callStatus = EMCallSessionStatusAccepted;
- }
- EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
- if(options.enableCustomAudioData){
- [self audioRecorder].channels = options.audioCustomChannels;
- [self audioRecorder].samples = options.audioCustomSamples;
- [[self audioRecorder] startAudioDataRecord];
- }
-}
-```
-
-音频采集过程开始后,在音频数据的回调里调用外部输入音频数据接口
-
-```
-[[[EMClient sharedClient] callManager] inputCustomAudioData:data
-```
-
-会话挂断时,停止音频采集及输入过程
-
-```
-EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
-if(options.enableCustomAudioData) {
- [[self audioRecorder] stopAudioDataRecord];
-}
-```
-
-### 美颜/自定义视频
-
-用户可以通过自己采集视频数据,使用外部输入视频数据的接口,实现自定义视频传输功能,可以对视频数据进行添加滤镜、美颜等功能。
-
-##### 配置属性
-
-使用外部输入视频数据接口前,需要先进行配置,配置如下
-
-```
-//进行1v1自定义视频之前,必须设置 EMCallOptions.enableCustomizeVideoData=YES
-EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
-options.enableCustomizeVideoData = YES;
-[[EMClient sharedClient].callManager startCall:aType remoteName:aUsername ext:@"123" completion:^(EMCallSession *aCallSession, EMError *aError) {
- completionBlock(aCallSession, aError);
-}];
-```
-
-##### 自定义摄像头数据
-
-设置 **EMCallOptions.enableCustomizeVideoData=YES** 后,必须自定义摄像头数据。采集视频数据可使用AVCaptureSession实现,呼叫方的视频数据采集可以在呼叫对方时开始,而接听方的数据采集可以在按下接听按钮后开始。 外部输入视频数据的接口如下:
-
-```
-/*!
- * \~chinese
- * 自定义本地视频数据
- *
- * @param aSampleBuffer 视频采样缓冲区
- * @param aRotation 旋转方向
- * @param aCallId 1v1会话实例ID,即[EMCallSession callId]
- * @param aCompletionBlock 完成后的回调
- */
-- (void)inputVideoSampleBuffer:(CMSampleBufferRef)aSampleBuffer
- rotation:(UIDeviceOrientation)aRotation
- callId:(NSString *)aCallId
- completion:(void (^)(EMError *aError))aCompletionBlock;
-
-/*!
- * \~chinese
- * 自定义本地视频数据
- *
- * @param aPixelBuffer 视频像素缓冲区
- * @param aCallId 1v1会话实例ID,即[EMCallSession callId]
- * @param aTime 视频原始数据时间戳,CMTime time = CMSampleBufferGetPresentationTimeStamp((CMSampleBufferRef)sampleBuffer);
- * @param aRotation 旋转方向
- * @param aCompletionBlock 完成后的回调
- */
-- (void)inputVideoPixelBuffer:(CVPixelBufferRef)aPixelBuffer
- sampleBufferTime:(CMTime)aTime
- rotation:(UIDeviceOrientation)aRotation
- callId:(NSString *)aCallId
- completion:(void (^)(EMError *aError))aCompletionBlock;
-```
-
-接口的调用在视频数据的回调中,即captureOutput:didOutputSampleBuffer:fromConnection中调用,调用前需要判断当前会话通话状态,若状态为EMCallSessionStatusAccepted,则可以调用外部输入视频数据接口。
-
-当视频通话挂断时,需要终止视频数据采集过程
-
-### 水印
-
-视频通话时,可以添加图片作为水印,添加时使用[IEMCallManager addVideoWatermark]接口,需要指定水印图片的NSUrl,添加位置.参见[EMWaterMarkOption](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_water_mark_option.html)。
-
-清除水印使用[IEMCallManager clearVideoWatermark]接口。
-
-显示remoteVideo需要使用EMCallViewScaleModeAspectFit模式,否则对方的水印设在边缘位置可能显示不出来。
-
-##### 接口
-
-```
-/*!
-* \~chinese
-* 开启水印功能
-*
-* @param option 水印配置项,包括图片URL,marginX,marginY以及起始点
-*
-* \~english
-* Enable water mark feature
-*
-* @param option the option of watermark picture,include url,margingX,marginY,margin point
- */
-- (void)addVideoWatermark:(EMWaterMarkOption*)option;
-/*!
-* \~chinese
-* 取消水印功能
-*
-* \~english
-* Disable water mark feature
-*
- */
-- (void)clearVideoWatermark;
-```
-
-
-### 私有部署
-
-私有部署设置方法参见[私有云sdk集成配置](../im/uc_iOS_private.md)
-
-## 客户端API
-
-1V1音视频通话的API包括以下接口
-
-- EMCallOption 视频通话配置类
-- EMCallManager 是视频通话的主要管理类,提供了语音通话的拨打、接听、挂断等接口
-- EMCallManagerDelegate 是视频通话的监听回调类,实时语音通话相关的回调
-- EMCallBuilderDelegate 提供了拨打视频通话时对方不在线的回调
-- EMCallSession 语音通话的会话实例接口类
-
-### EMCallOption
-
-| 属性 | 描述 |
-| :----------------------------------------------------------- | :--------------------------------------------------- |
-| [pingInterval](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a3186d2e45fcd6c5697c724679d0affc7) | 心跳时间间隔,单位秒,默认30s,最小10s |
-| [isSendPushIfOffline](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a387a20ee25e1d735b61b0c31bf834556) | 被叫方不在线时,是否推送来电通知 |
-| [offlineMessageText](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a62d88c4b292cdfb13b4ea8d723ba2f65) | 当isSendPushIfOffline=YES时起作用,离线推送显示的内容 |
-| [maxAudioKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#aea45547ce623a0fd5d53a36f00334520) | 最大音频码率 |
-| [maxVideoKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a4130c8f7488d6d6f58c3783dc63be5fd) | 最大视频码率 |
-| [minVideoKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#ae070e260597c913634a21c03aa31826a) | 最小视频码率 |
-| [maxVideoFrameRate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a45f020f84b4513fdc0cb3f8a123fe678) | 最大视频帧率 |
-| [videoResolution](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#af49ac4f01b9bca538fbce40e1de5f866) | 视频分辨率 |
-| [enableReportQuality](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#af2129acdd0d3d73a583e8d37dfc087e2) | 是否监听通话质量 |
-| [enableCustomAudioData](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#ae927cb60d05c59b389517648941e7ec8) | 是否使用自定义音频数据 |
-| [audioCustomSamples](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a76482a8e2702e1905c036142e41c8a6d) | 自定义音频数据的采样率,默认48000 |
-| [enableCustomizeVideoData](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a89f38b15e05ed5d6636af5fde628d114) | 是否使用自定义视频数据 |
-
-### EMCallManager
-
-| 方法 | 功能 |
-| :----------------------------------------------------------- | :--------------------------------------- |
-| [addDelegate:delegateQueue:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a367328bcd0bf83a51dc08ddaec68872f) | 添加回调代理 |
-| [removeDelegate:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#aa9b3da07b69c09e892f828791b1370cb) | 移除回调代理 |
-| [setBuilderDelegate:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#ab186d489c2779e2984498f79b63432fd) | 添加离线推送回调代理,该代理只能设置一个 |
-| [setCallOptions:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a8bdffc278012912e6b647496f950f2d0) | 配置设置项 |
-| [getCallOptions](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#aa57c5e2e99d712a9e228fa4a3456cab4) | 获取设置项 |
-| [startCall:remoteName:ext:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#afb034d6e9e45e8712f6ce152c83cde51) | 发起实时会话 |
-| [startCall:remoteName:record:mergeStream:ext:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a96844b40a066c066bc0e1dd99d98c535) | 发起实时会话,可选择是否录制 |
-| [answerIncomingCall:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#acc32a00500f5ff029035a723fc4234c2) | 接收方同意通话请求 |
-| [endCall:reason:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a3964f06814f26a3f3f9b435f59ee3385) | 结束通话 |
-| [inputCustomAudioData:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a39f332f19d39159b7fdcb5667e38db5d) | 自定义外部音频数据 |
-| [inputVideoSampleBuffer:rotation:callId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a09537a70ba5c40c1de38db2398b9bd95) | 自定义本地视频数据 |
-| [inputVideoPixelBuffer:sampleBufferTime:rotation:callId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a04e9c0e4e1bdbe060552865e39daab73) | 自定义本地视频数据 |
-| [addVideoWatermark:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a5618360f7593b6acc429fd2318962724) | 开启水印 |
-| [clearVideoWatermark](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a16bddaff9383df6da73e08919019d322) | 清除水印 |
-
-### EMCallManagerDelegate
-
-| 回调事件 | 描述 |
-| :----------------------------------------------------------- | :----------------------------------------------------------- |
-| [callDidReceive:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#a3eba09d467fd76b4af04e5bf47154b77) | 用户A拨打用户B,用户B会收到这个回调 |
-| [callDidConnect:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#a5203fbf604e29cacedf483c5f52b9923) | 通话通道建立完成,用户A和用户B都会收到这个回调 |
-| [callDidAccept:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#aa0f4c7b3f5a9c6613f6726420910e76c) | 用户B同意用户A拨打的通话后,用户A和B会收到这个回调 |
-| [callDidEnd:reason:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#a82a5133f2175c94c4b39cf6f42010601) | 1. 用户A或用户B结束通话后,双方会收到该回调. 2. 通话出现错误,双方都会收到该回调 |
-| [callStateDidChange: type:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#a3b78b91a87d76a4ec5f79f60cb213228) | 用户A和用户B正在通话中,用户A中断或者继续数据流传输时,用户B会收到该回调 |
-| [callNetworkDidChange:status:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#aae5150a53d6c69c278b9bdde4cac2022) | 用户A和用户B正在通话中,用户A的网络状态出现不稳定,用户A会收到该回调。若未开启录制,用户B也会收到该回调 |
-
-### EMCallBuilderDelegate
-
-| 回调事件 | 描述 |
-| :----------------------------------------------------------- | :----------------------------------------------------------- |
-| [callRemoteOffline:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_builder_delegate-p.html#a14ac31090d0283a3229cc665aa1b34d2) | 用户A给用户B拨打实时通话,用户B不在线,并且用户A设置了[EMCallOptions.isSendPushIfOffline == YES],则用户A会收到该回调 |
-
-### EMCallSession
-
-属性
-
-| 属性 | 描述 |
-| :----------------------------------------------------------- | :---------------------------------------------------- |
-| [callId](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a66283c44edfc5ae767b382f63176d953) | 会话标识符 |
-| [localName](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a97e3bea964a2228e08cbc77587f5402e) | 通话本地的username |
-| [type](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#aa12fc9a028f5ae16869a302894ffdb4f) | 通话的类型 |
-| [isCaller](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a782bad856c936638349d96e8520cc0ef) | 是否为主叫方 |
-| [remoteName](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a0652ad964df50c2bafe76281026cde69) | 对方的username |
-| [status](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a7ac723de33f96d1f05777c5e53001636) | 通话的状态 |
-| [localVideoView](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ad8ed75a4fedb8ae9573d8c5ce296867a) | 视频通话时本地的图像显示区域 |
-| [remoteVideoView](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a74cf99cc4f08c2694459b878b04f3829) | 视频通话时对方的图像显示区域 |
-| [connectType](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ab31443f1605498f4bb80a4e98925fecb) | 连接类型 |
-| [videoLatency](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a218b700793cbd72fb0bd1a5556bf0e06) | 视频的延迟时间,单位是毫秒 |
-| [localVideoFrameRate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a6d05d54be6d7508b959f2ef020ca0eee) | 本地视频的帧率,实时变化 未获取到返回-1 |
-| [remoteVideoFrameRate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ac1e60bc6f19f4cf2d50c2264702928dd) | 对方视频丢包率,实时变化 未获取到返回-1 |
-| [localVideoBitrate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#aecc7d56536bfedcb924e19e0bc860109) | 本地视频通话对方的比特率kbps,实时变化 未获取到返回-1 |
-| [remoteVideoBitrate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#adf4ac941a4a002e5025b78d01b98b2c0) | 对方视频通话对方的比特率kbps,实时变化 未获取到返回-1 |
-| [localVideoLostRateInPercent](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ab42eb2571e0bb1111ab33f84c80588a0) | 本地视频丢包率,实时变化 未获取到返回-1 |
-| [remoteVideoLostRateInPercent](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#aea427d3dd20376f3a9a5f37fb157358a) | 对方视频丢包率,实时变化 未获取到返回-1 |
-| [remoteVideoResolution](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a3ef044730afda942a2e7955b23bc9d75) | 对方视频分辨率 未获取到返回 (-1,-1) |
-| [serverVideoId](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ac0aa89265a9e30dbb23d3d605cf91172) | 服务端录制文件的id |
-| [willRecord](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a6b76c8b2df03bcf4fab8b459fcc60407) | 是否启用服务器录制 |
-| [ext](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a7c446f7fa3e2d23fd3cb2c8eb448dcd1) | 消息扩展 |
-
-方法
-
-| 方法 | 功能 |
-| :----------------------------------------------------------- | :--------------- |
-| [pauseVoice](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a42467f8c736ca48b7d97d0281e52e0c7) | 暂停语音数据传输 |
-| [resumeVoice](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a52119fa0310787b4041fab33248abf0e) | 恢复语音数据传输 |
-| [pauseVideo](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a36946520d5b65fbe1900c3fc87d7d6c9) | 暂停视频传输 |
-| [resumeVideo](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a5529c28cebfd1959f37934028464b2a6) | 恢复视频传输 |
-| [switchCameraPosition:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a5c3eb19b609b57c4842a4ef8900c984b) | 切换前后摄像头 |
\ No newline at end of file
diff --git a/docs/private/media/one2one_pcdesktop.md b/docs/private/media/one2one_pcdesktop.md
deleted file mode 100644
index 3a5c0fb4..00000000
--- a/docs/private/media/one2one_pcdesktop.md
+++ /dev/null
@@ -1,187 +0,0 @@
-# PC桌面集成1对1通话
-
-------
-
-1v1实时通话允许用户发起、接听、挂断单人的音视频会话,可以在会话过程中进行暂停、恢复,并对会话过程进行监听。
-
-1v1实时通话管理模块为EMCallManager,由EMClient模块加载时主动创建,可以使用EMClient模块的getCallManager方法获取,代码如下
-
-```
-var callManager = emclient.getCallManager();
-```
-
-## 注册消息回调监听
-
-```
-function setCallManagerListener(callManager, listener) {
-// 收到会话请求
-listener.onRecvCallIncoming((callsession) => {
-// 在这里可以选择接通或者拒绝会话
-});
-// 会话连接上
-listener.onRecvCallConnected((callsession) => {
-// 会话连接上之后,如果是应答方,需要Answer信息
-if(!callsession.getIsCaller())
-callManager.sendAnswer(callsession.getCallId());
-});
-// 会话已接通
-listener.onRecvCallAccepted((callsession) => {});
-// 会话挂断,reason为挂断原因,0挂掉,1无响应,2拒绝,3忙碌,4失败,5不支持,6离线
-listener.onRecvCallEnded((callsession,reason,error) => {});
-// 网络状态变化,toStatus状态:0连接,1不稳定,2断开
-listener.onRecvCallNetworkStatusChanged((callsession,toStatus) => {});
-// 对方会话状态变化,type值:0音频暂停,1音频恢复,2视频暂停,3视频恢复
-listener.onRecvCallStateChanged((callsession,type) => {});
-}
-var managerlistener = new easemob.EMCallManagerListener();
-setCallManagerListener(callManager, managerlistener);
-// 添加回调监听
-callManager.addListener(managerlistener);
-//移除回调监听
-callManager.removeListener(managerlistener);
-```
-
-## 发起音视频会话
-
-用户可以主动发起单人会话,方法如下
-
-```
-/**
-* 发起音视频会话asyncMakeCall
-* @param remoteName Srign,对方用户ID,输入参数
-* @param type Number,会话类型,0为音频,1为视频,输入参数
-* @param ext String,会话扩展信息,应答方可见
-* return {code:{Number},description:{String},data:{EMCallSession}}
-*/
-let result = callManager.asyncMakeCall(remoteName,type,ext);
-```
-
-## 接听音视频会话
-
-接听会话方法一般在收到onRecvCallIncoming后调用,方法如下
-
-```
-/**
-* 接听音视频会话asyncAnswerCall
-* @param callId,String,呼叫方ID,输入参数
-*/
-callManager.asyncAnswerCall(callId);
-```
-
-callId可以通过callsession的getCallId()方法获取。
-
-## 发送Answer消息
-
-发送Answer消息由接听方在会话连接上之后调用,即onRecvCallConnected中调用,只有接听方才需要调用此接口,方法如下
-
-```
-/**
-* 发送Answer消息
-* @param callId,String,呼叫方ID,输入参数
-*/
-callManager.sendAnswer(callId);
-```
-
-## 挂断音视频会话
-
-用户可以在收到会话请求时,直接挂断会话,也可以在通话过程中挂断,调用挂断电话API时,需要传入挂断原因
-
-```
-/**
-* 接听音视频会话asyncEndCall
-* @param callId,String,呼叫方ID,输入参数
-* @param reason,Number 结束原因,0挂掉,1无响应,2拒绝,3忙碌,4失败,5不支持,6离线
-*/
-callManager.asyncEndCall(callId,reason);
-```
-
-## 切换语音视频状态
-
-```
-/**
-* 修改会话类型,切换语音视频状态
-* @param {String} callId 呼叫方Id
-* @param {Number} controlType 修改后的类型,0语音暂停,1为语音继续,2视频暂停,3视频继续
-*/
-callManager.updateCal(callId,controlType);
-```
-
-## 音视频配置
-
-获取配置
-
-```
-let emcallconfigs = callManager.getCallConfigs();
-// 呼叫时,若对方不在线,是否发送离线通知
-console.log("IsSendPushIfOffline:" + emcallconfigs.getIsSendPushIfOffline());
-// 视频宽度
-console.log("VideoResolutionWidth:" + emcallconfigs.getVideoResolutionWidth());
-// 视频高度
-console.log("VideoResolutionHeight:" + emcallconfigs.getVideoResolutionHeight());
-// 音视频心跳周期
-console.log("PingInterval:" + emcallconfigs.getPingInterval());
-```
-
-设置配置
-
-```
-// 呼叫时,若对方不在线,是否发送离线通知
-emcallconfigs.setIsSendPushIfOffline(true);
-// 视频宽度,高度
-emcallconfigs.setVideoResolution(640,480);
-// 音视频心跳周期
-emcallconfigs.setPingInterval(60);
-callManager.setCallConfigs(emcallconfigs);
-```
-
-## 注册媒体流回调
-
-会话接通后,需要使用音视频控件展示通话的音视频流,音视频流可通过注册回调得到,注册过程在注册消息回调监听时设置一次即可
-
-```
-// 处理对方的音视频流,回调函数参数:remoteStream为对方音视频流,type为类型,0音频,1视频
-callManager.getRemoteStream((remoteStream,type) => {});
-// 处理本地的音视频流,回调函数参数:remoteStream为本地音视频流,type为类型,0音频,1视频
-callManager.getLocalStream((localStream,type) => {});
-```
-
-## 发送离线通知
-
-设置了若呼叫时,对方处于离线状态,执行的回调。当配置中设置了setIsSendPushIfOffline(true),该API可以应用。应用方法如下:
-
-```
-// 传入回调函数,回调函数的三个参数分别为本地发送方ID,对方ID,呼叫类型(0语音,1视频)
-callManager.setSendPushMessage((from,to,type) => {
-let textMsgBody = new easemob.EMTextMessageBody(type == 0?"语音请求":"视频请求");
-let textMsg = easemob.createSendMessage(from, to, textMsgBody);
-let callback = new easemob.EMCallback();
-
-textMsg.setCallback(callback)
-emclient.getChatManager().sendMessage(textMsg);
-})
-```
-
-## 会话控制接口
-
-音视频会话控制模块为EMCallSesssion,呼叫方通过asyncMakeCall返回,接听方通过监听回调的onRecvCallIncoming获取到。通过会话控制模块可以获取到以下会话信息
-
-```
-// 获取CallId
-console.log(callsession.getCallId());
-// 获取本地名称
-console.log(callsession.getLocalName());
-// 获取会话类型,0音频,1视频
-console.log(callsession.getType());
-// 获取对方名称
-console.log(callsession.getRemoteName());
-// 获取是否呼叫方
-console.log(callsession.getIsCaller());
-// 获取会话状态,0断开,1振铃,2正在连接,3已连接,4已接听
-console.log(callsession.getStatus());
-// 获取会话详情EMCallSessionStatistics
-console.log(callsession.getStatistics());
-// 获取会话扩展信息
-console.log(callsession.getExt());
-// 修改会话状态,0音频暂停,1音频恢复,2视频暂停,3视频恢复
-console.log(callsession.update(controltype));
-```
\ No newline at end of file
diff --git a/docs/private/media/one2one_vxmini.md b/docs/private/media/one2one_vxmini.md
deleted file mode 100644
index 055aa16d..00000000
--- a/docs/private/media/one2one_vxmini.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# 微信小程序集成1对1音视频通话
-
-------
-
-目前,微信小程序尚不支持1对1音视频通话; 如果需要1对1功能,可以通过多人音视频会议的方式来实现。
-
-实现流程:
-
-1. 发起方创建一个会议;
-2. 发起方加入会议;
-3. 发起方发送一条消息给接收方(邀请消息),消息里包含会议Id和会议密码信息;
-4. 接收方收到邀请消息后,也加入会议;
-5. 结束通话时,直接退出会议,另一方收到对方退出会议事件,也退出会议
-
-注意:用多人音视频会议实现1对1通话的方案,和android、iOS端的1对1通话是不能够互通的;如果需要互通,在android和iOS端也需要采用一样的方案。
-
-请参考: [多人音视频会议](conference_vxmini.html)
\ No newline at end of file
diff --git a/docs/private/media/one2one_web.md b/docs/private/media/one2one_web.md
deleted file mode 100644
index f4771f43..00000000
--- a/docs/private/media/one2one_web.md
+++ /dev/null
@@ -1,365 +0,0 @@
-# Web集成1对1通话
-
-## 跑通Demo
-
-### 1. 示例代码
-
-- [下载 Web SDK + Demo 代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webdemo-3.4.2.7.zip)
-- [体验Demo](https://zim-rtc.easemob.com:12005/)
-
-或进入环信[客户端下载](common_clientsdk.html#音视频sdk下载)页面,选择Web SDK + Demo下载
-
-### 2. 前提条件
-
-```
-1.安装一款 Easemob Web SDK 支持的浏览器
-2.本地安装 node 环境 >= 6.3.0
-```
-
-### 3. 运行 Demo
-
-1. demo 目录结构 webim/demo
-2. 进入 webim/demo 文件夹
-3. 安装依赖包
-
-```
-npm install
-```
-
-4. 启动项目
-
-```
-HTTPS=true npm start
-```
-
-## 快速集成
-
-### 1. 环信后台注册 appkey
-
-在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。
-
-### 2. 创建项目
-
-```
-a.可以简单的写一个 html,引入 SDK 测试
-b.或者使用 脚手架搭建一个项目
-```
-
-### 3. 引入 SDK
-
-**1v1 需要依赖 IM SDK 进行通信,所以首先需要引入 IM SDK**
-
-#### 3.1 通过 scrpit 标签的 src 引入
-
-```
- //im SDK
-
-```
-
-#### 3.2 使用 npm 获取 SDK
-
-```
-npm install easemob-websdk --save
-npm install easemob-webrtc --save
-```
-
-### 4. 初始化 SDK
-
-
-#### 4.1 引入 sdk
-
-```
-import webrtc from 'easemob-webrtc'
-```
-
-#### 4.2 初始化 WebRTC Call,用于实现 1v1 音视频通话
-
-```
-var rtcCall = new webrtc.Call({
- connection: conn, // WebIM 的链接信息
- mediaStreamConstaints: {
- audio: true,
- video: true
- /**
- * 修改默认摄像头,可以按照以下设置,不支持视频过程中切换
- * video:{ 'facingMode': "user" } 调用前置摄像头
- * video: { facingMode: { exact: "environment" } } 后置
- */
- },
-
- listener: {
- onAcceptCall: function (from, options) {
- console.log('onAcceptCall::', 'from: ', from, 'options: ', options);
- },
- //通过streamType区分视频流和音频流,streamType: 'VOICE'(音频流),'VIDEO'(视频流)
- onGotRemoteStream: function (stream, streamType) {
- console.log('onGotRemoteStream::', 'stream: ', stream, 'streamType: ', streamType);
- var video = document.getElementById('video');
- video.srcObject = stream;
- },
- onGotLocalStream: function (stream, streamType) {
- console.log('onGotLocalStream::', 'stream:', stream, 'streamType: ', streamType);
- var video = document.getElementById('localVideo');
- video.srcObject = stream;
- },
- onRinging: function (caller, streamType) {
- console.log("onRinging", caller)
- },
- onTermCall: function (reason) {
- console.log('onTermCall::');
- console.log('reason:', reason);
- },
- onIceConnectionStateChange: function (iceState) {
- console.log('onIceConnectionStateChange::', 'iceState:', iceState);
- },
- // 通话断网监听
- onNetWorkDisconnect(endType) { // endType: local || remote, 哪一端断网
- console.log('1v1 onNetWorkDisconnect', endType);
- },
- onError: function (e) {
- console.log(e);
- }
- }
-});
-```
-
-### 5. 视频呼叫
-
-**整个呼叫过程:**
-
-1. 主叫发起呼叫
-2. 被叫收到呼叫(主叫被叫分属于两个页面,通过服务器发送消息)
-3. 被叫接受呼叫或者拒绝呼叫
-4. 主叫收到被叫接受或者拒绝的回调
-5. 通话建立成功
-6. 一方挂断另一方收到挂断的回调
-
-**config 参数为主动呼叫时的配置参数(该功能主要用作web端对APP端呼叫时使用)**
-
-```
-var config = {
- push: true, // 对方(app端)不在线时是否推送
- timeoutTime: 30000, // 超时时间
- txtMsg: 'I gave you a video call.', // 给对方发送的消息
- pushMsg: 'user is calling you' //推送内容
- };
-```
-
-#### 5.1 主叫发起呼叫
-
-```
-callBtn.onclick = function () {
- rtcCall.caller = 'mengyuanyuan'; // 指定呼叫方名字
- rtcCall.makeVideoCall(callee,null,true,true,config);
-};
-```
-
-在 rtcCall.makeVideoCall 方法中 注意以下参数的设置
-
-- 第一个参数callee: 被呼叫人名字 必需 string
-- 第二个参数 指定传 null 必需 null
-- 第三个参数 是否开启录制 非必需 boolean
-- 第四个参数 是否开启录制合并 非必需 boolean
-- 第五个参数 主动呼叫扩展配置 非必需 object
-
-#### 5.2 被叫方收到呼叫回调
-
-```
-// 初始化的函数
-var rtcCall = new webrtc.Call({
- ...
- listener: {
- ...
- onRinging: function (caller, streamType) {
- console.log("onRinging", caller)
- },
- }
-});
-```
-
-#### 5.3 被叫方接受呼叫
-
-```
-rtcCall.acceptCall() // 无参数
-```
-
-#### 5.4 主叫方收到被叫接受呼叫的回调
-
-```
-// 初始化的函数
-var rtcCall = new webrtc.Call({
- ...
- listener: {
- ...
- onGotLocalStream: function (stream, streamType) {
- // stream:媒体流,streamType:流类型 VIDEO 视频流、VOICE 语音流, 可根据不同的流类型做不同的UI展示
- var video = document.getElementById('localVideo');
- video.srcObject = stream; // 将流设置给 video标签 用于显示
- },
- }
-});
-```
-
-### 6. 关掉/拒绝通话
-
-```
-rtcCall.endCall() // 无参数
-```
-
-#### 6.1 收到通话结束的回调
-
-```
-// 初始化的函数
-var rtcCall = new webrtc.Call({
- ...
- listener: {
- ...
- onTermCall: function (reason) {
-
- },
- }
-});
-```
-
-### 7. 音频通话
-
-```
-音频通话步骤与视频通话一致
-回调方法共用
-只是在回调中的 streamType 不同
-结束通话方法相同
-```
-
-#### 7.1 发起音频通话
-
-```
-callBtn.onclick = function () {
- rtcCall.caller = 'mengyuanyuan'; // 指定呼叫方名字
- rtcCall.makeVoiceCall('asdfghj',null,true,true,config);
-};
-```
-
-## 进阶功能
-
-### 取日志
-
-在控制台 调用 WebIM.EMedia.fileReport 方法可下载日志文件
-
-```
-WebIM.EMedia.fileReport() // 无参数
-```
-
-### 通话中音视频控制
-
-调用 rtcCall.controlStream 方法可以控制 音视频的打开/关闭
-
-```
-rtcCall.controlStream(controlType, to)
-```
-
-在 rtcCall.controlStream 方法中 注意以下参数的设置
-
-- controlType: 操作类型 **0:打开麦克风;1:关闭麦克风;2:关闭摄像头;3:打开摄像头** ,必需 number
-- to: 对方 userId,,必需 string
-
-**对方会收到回调函数**
-
-```
-// 对方操作音频的回调 opened: true:打开音频、false:关闭音频
-onOtherUserOpenVoice: function (from, opened) { } ,
-
-// 对方操作视频的回调 opened: true:打开视频、false:关闭视频
-onOtherUserOpenVideo: function (from, opened) { },
-```
-
-### 设置通话参数
-
-可以在初始化 **rtcCall** 的时候,指定 **mediaStreamConstaints** 字段
-自定义分辨率、采样率
-
-```
-var rtcCall = new webrtc.Call({
- ...
- mediaStreamConstaints: {
- audio: { //音频采样率
- sampleRate: 44100,
- sampleSize: 16
- },
- video: { // 视频分辨率 宽度和高度
- width: {
- exact: 1280
- },
- height: {
- exact: 720
- }
- }
- },
-},
-```
-
-### 离线推送
-
-在进行视频或者音频呼叫的时候,可指定是否推送消息
-
-```
-var config = {
- push: true, // 对方(app端)不在线时是否推送
- ...
-};
-callBtn.onclick = function () {
- rtcCall.caller = 'mengyuanyuan'; // 指定呼叫方名字
- rtcCall.makeVideoCall(callee,null,true,true,config);
-};
-```
-
-### 云端录制
-
-在进行视频或者音频呼叫的时候,可指定是否录制和录制合并
-
-```
-var option = {
- callee: //被叫者,
- rec: //是否开启录制,
- recMerge: //是否开启录制合并,
- config: //其他配置参数
-}
-callBtn.onclick = function () {
- rtcCall.caller = 'mengyuanyuan'; // 指定呼叫方名字
- rtcCall.makeVideoCall(option.callee,null,option.rec,option.recMerge,option.config);
-};
-```
-
-### 断网检测
-
-**在通话进行前指定监听函数 onNetWorkDisconnect**
-
-```
-var rtcCall = new webrtc.Call({
- ...
- listener: {
- ...
- onNetWorkDisconnect(endType) { // endType: local || remote, 哪一端断网
- console.log('1v1 onNetWorkDisconnect', endType);
- },
- }
-})
-```
-
-
-### 私有部署
-
-私有部署设置方法参见[私有云sdk集成配置](../im/uc_Web_private.md)。
-
-## 客户端API
-
-1V1音视频通话的API包括以下接口
-
-- option 创建通话类的参数配置
-- makeVideoCall 发起视频呼叫
-- makeVoiceCall 发起音频呼叫
-
-| 方法 | |
-| :----------------------------------------------------------- | -------------- |
-| [option](http://webim-h5.easemob.com/webrtc/jsdoc/out/-_Call.html) | 创建类时的配置 |
-| [makeVideoCall](http://webim-h5.easemob.com/webrtc/jsdoc/out/global.html#makeVideoCall) | 发起视频通话 |
-| [makeVoiceCall](http://webim-h5.easemob.com/webrtc/jsdoc/out/global.html#makeVoiceCall) | 发起音频通话 |
\ No newline at end of file
diff --git a/docs/private/media/overview.md b/docs/private/media/overview.md
deleted file mode 100644
index 2fb8f507..00000000
--- a/docs/private/media/overview.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# 音视频文档
-
-## 1、XXXX
diff --git a/docs/private/media/rest_introduction.md b/docs/private/media/rest_introduction.md
deleted file mode 100644
index 6d980bae..00000000
--- a/docs/private/media/rest_introduction.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# REST接口简介
-
-
-音视频云的REST接口规则与即时通讯的REST规则是一致的,参考[服务端集成](../../document/server-side/overview.md)
-
-在调用音视频云的REST接口前,需获取token,参考 [获取管理员权限](../../document/server-side/easemob_app_token.html#获取管理员权限-token)
\ No newline at end of file
diff --git a/docs/private/media/rest_manage.md b/docs/private/media/rest_manage.md
deleted file mode 100644
index 08795a61..00000000
--- a/docs/private/media/rest_manage.md
+++ /dev/null
@@ -1,247 +0,0 @@
-# 会议管理
-
-
-环信使用 REST 的方式来对音视频会议进行管理操作,包括**创建会议**,**解散会议**,**获取会议**及**从会议中踢人**。
-
-**注:**
-
-- 原会议类型模式目前已经进行优化,用户可以直接使用普通模式, 大会议模式和直播模式将弃用。
-
-- 在[语音连麦聊天室](scenario_tc.html)中,环信仅使用了**创建会议**,**解散会议**两个API,开发者可根据自身需求,选择使用。
-
-# REST API
-
-音视频会议管理在集成过程中,可以使用以下4个接口来对会议进行管理操作。请查看以下 REST API 详细文档说明。
-
-| 名称 | 请求 | Method |
-| :----------------- | :---------------------------------------------------- | :----- |
-| 创建一个会议 | /{orgName}/{appName}/conferences | POST |
-| 解散一个会议 | /{orgName}/{appName}/conferences/{confrId} | DELETE |
-| 获取会议信息 | /{orgName}/{appName}/conferences/{confrId} | GET |
-| 从会议中踢掉一个人 | /{orgName}/{appName}/conferences/{confrId}/{userName} | DELETE |
-
-## 创建会议
-
-#### HTTP Request
-
-| ![img](/images/privitization/post.png) | /{org_name}/{app_name}/conferences |
-| :----------------------------------------------------------- | :--------------------------------- |
-
-#### Request Headers
-
-| 参数 | 说明 |
-| :------------ | :--------------- |
-| Content-Type | application/json |
-| Authorization | Bearer ${token} |
-
-#### Request Body
-
-| 名称 | 类型 | 描述 |
-| :----------------------- | :------ | :----------------------------------------------------------- |
-| confrType | int | 10: 普通模式 ~~11: 大会议模式 12: 直播模式~~ |
-| password | string | 指定密码时,将使用此密码;不指定,将由服务端生成 |
-| confrDelayMillis | long | 会议临时保留时长,指从会议创建成功到第一个用户加入会议之间的时长,单位是毫秒。超过这个保留时间,会议将被解散。第一个人加入会议之后,此保留时间失效,当最后一人离开会议,会议会立即被销毁。此参数默认是120秒,建议不要设置超过60分钟。 |
-| memDefaultRole | int | 会议成员默认角色。用户A通过会议 ID 密码获取加入会议后的角色就是这个 1:观众,3:主播,7:管理员(拥有主播权限)。 缺省时,根据会议类型设置,目前规则如下:普通模式默认主播;~~大会议模式默认主播;直播模式默认观众~~ |
-| allowAudienceTalk | boolean | true 允许观众上麦 |
-| creator | string | 指定创建者,creator 将会成为这个会议的管理员,拥有管理员权限 |
-| rec | boolean | true 此会议将被录制 |
-| recMerge | boolean | true 此会议的所有通话将被合并到一个文件 |
-| supportWechatMiniProgram | boolean | true 这个会议将支持小程序,同时会议编码被强制更新为H264,VP8。注意:默认的会议是不支持小程序的,如果想要支持小程序,请手动指定这个参数为true |
-| useVCodes | 数组 | 指定会议将要采用的编码方式如[“H264”,“VP8”] |
-| maxTalkerCount | int | 会议主播人数 |
-| maxVideoCount | int | 会议最大视频数 |
-| maxAudienceCount | int | 会议中的最大人数 |
-
-#### Response Body
-
-| 名称 | 类型 | 描述 |
-| :---------------- | :------ | :----------------------------------------------------------- |
-| type | int | 10: 普通模式 ~~11: 大会议模式 12: 直播模式~~ |
-| talkerLimit | int | 主播上限数,~~大会议模式全部是是主播~~ |
-| id | string | 会议ID |
-| password | string | 会议密码 |
-| allowAudienceTalk | boolean | 允许观众上麦,~~大会议模式时忽略此项~~ |
-| audienceLimit | int | 观众上限数,~~大会议模式无观众~~ |
-| expireDate | Date | 过期时间,创建会议后,如果在 expireDate 之前没有人加入会议,将会被系统强制解散 |
-
-#### 请求示例
-
-```
-curl -L -X POST 'http://127.0.0.1:9090/easemob-demo/hcl/conferences' \
---header 'Content-Type: application/json' \
---header 'Authorization: Bearer YWMtaJszCI5vEemOhnkmxEo52QAAAAAAAAAAAAAAAAAAAAHmqirKW28R6ZB2cYf5QmSUAQMAAAFrVLgKfgBPGgC863CANqOsZOAF1tnxLeMc0Z-gRFCQwqV-0MB5nVAB5A' \
---header 'Content-Type: application/json' \
---data-raw '{
- "confrType": 10,
- "password": "",
- "confrDelayMillis": 100000,
- "memDefaultRole":3,
- "allowAudienceTalk": false,
- "confrId": "",
- "creator":"122",
- "rec":false,
- "recMerge":false,
- "supportWechatMiniProgram": true,
- "useVCodes": [
- "H264",
- "VP8"
- ],
- "maxTalkerCount":9,
- "maxVideoCount":9,
- "maxAudienceCount":20
-
-
-}'
-```
-
-#### 可能返回的结果示例
-
-- 返回值200,表示会议创建成功
-- 返回值401,未授权[无token、token错误、token过期]
-- 返回值403,没有开通音视频增值服务调用接口失败
-
-```
-{
- "error": 0,
- "id": "IM3SKW51SKH4TB80LV45000C7",
- "type": 10,
- "mixed": false,
- "password": "0.37898245722568236",
- "audienceLimit": 600,
- "talkerLimit": 6,
- "expireDate": "2019-06-14 15:41:58",
- "allowAudienceTalk": true
-}
-```
-
-
-
-------
-
-## 解散会议
-
-#### HTTP Request
-
-| ![img](/images/privitization/delete.png) | /{orgName}/{appName}/conferences/{confrId} |
-| :----------------------------------------------------------- | :----------------------------------------- |
-
-需要在请求时对应填写{confrId},需要删除的会议 ID 。
-
-#### Request Headers
-
-| 参数 | 说明 |
-| :------------ | :--------------- |
-| Content-Type | application/json |
-| Authorization | Bearer ${token} |
-
-#### 请求示例
-
-```
-curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer YWMt7CoyjusbEeixOi3iod4eDAAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnJlhJIwBPGgCqtjiyVnR209iyr8kNbhJhhanNQDdP9CMmpK2G-NIUOQ' 'http://a1.easemob.com/easemob-demo/testapp/conferences/TURN25AIYAVxASW7PL1Q00C51'
-```
-
-#### 可能返回的结果
-
-- 返回值200,表示会议解散成功
-- 返回值404,表示该会议ID不存在
-- 返回值401,未授权[无token、token错误、token过期]
-- 返回值403,没有开通音视频增值服务调用接口失败
-
-------
-
-## 踢掉会议中成员
-
-#### HTTP Request
-
-| ![img](/images/privitization/delete.png) | /{orgName}/{appName}/conferences/{confrId}/{userName} |
-| :----------------------------------------------------------- | :----------------------------------------- |
-
-需要在请求时对应填写{confrId},需要删除的会议 ID 。
-
-userName为成员用户名。
-
-#### Request Headers
-
-| 参数 | 说明 |
-| :------------ | :--------------- |
-| Content-Type | application/json |
-| Authorization | Bearer ${token} |
-
-#### 请求示例
-
-```
-curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer YWMt7CoyjusbEeixOi3iod4eDAAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnJlhJIwBPGgCqtjiyVnR209iyr8kNbhJhhanNQDdP9CMmpK2G-NIUOQ' 'http://a1.easemob.com/easemob-demo/testapp/conferences/TURN25AIYAVxASW7PL1Q00C51/yangss'
-```
-
-#### 可能返回的结果
-
-- 返回值200,表示会议解散成功
-- 返回值404,表示该会议ID不存在
-- 返回值401,未授权[无token、token错误、token过期]
-- 返回值403,没有开通音视频增值服务调用接口失败
-
-------
-
-## 获取会议信息
-
-#### HTTP Request
-
-| ![img](/images/privitization/get.png) | /{orgName}/{appName}/conferences/{confrId} |
-| :----------------------------------------------------------- | :----------------------------------------- |
-
-需要在请求时对应填写{confrId},需要获取的会议 ID 。
-
-#### Request Headers
-
-| 参数 | 说明 |
-| :------------ | :--------------- |
-| Content-Type | application/json |
-| Authorization | Bearer ${token} |
-
-#### Response Body
-
-| 名称 | 类型 | 描述 |
-| :---------------- | :------ | :----------------------------------------------------------- |
-| type | int | 10: 普通模式 ~~11: 大会议模式 12: 直播模式~~ |
-| talkerLimit | int | 主播上限数,~~大会议模式全部是是主播~~ |
-| id | string | 会议ID |
-| password | string | 会议密码 |
-| allowAudienceTalk | boolean | 允许观众上麦,~~大会议模式时忽略此项~~ |
-| audienceLimit | int | 观众上限数,~~大会议模式无观众~~ |
-| expireDate | Date | 过期时间,创建会议后,如果在 expireDate 之前没有人加入会议,将会被系统强制解散 |
-| mems | Array | 现有成员列表 |
-
-#### 请求示例
-
-```
-curl -X GET \
- http://a1.easemob.com/1100181023201864/voicechatroom/conferences/IM3SKW51SKH4TB80LV45000C7 \
- -H 'Accept: */*' \
- -H 'Authorization: Bearer YWMtaJszCI5vEemOhnkmxEo52QAAAAAAAAAAAAAAAAAAAAHmqirKW28R6ZB2cYf5QmSUAQMAAAFrVLgKfgBPGgC863CANqOsZOAF1tnxLeMc0Z-gRFCQwqV-0MB5nVAB5A'
-```
-
-#### 可能返回的结果示例
-
-- 返回值200,表示会议获取成功
-- 返回值404,表示该会议ID不存在
-- 返回值401,未授权[无token、token错误、token过期]
-- 返回值403,没有开通音视频增值服务调用接口失败
-
-```
-{
- "error": 0,
- "id": "13H05522N8TEXW49ESW00C10618",
- "type": 11,
- "mixed": true,
- "password": "",
- "audienceLimit": 0,
- "talkerLimit": 30,
- "allowAudienceTalk": true,
- "mems": [{
- "memberId": "13H05522N8TEXW49ESW00C10618M2",
- "memName": "easemob-demo#chatdemoui_lulu3",
- "role": 7
- }]
-}
-```
-
diff --git a/docs/private/media/rest_record.md b/docs/private/media/rest_record.md
deleted file mode 100644
index 28f480d0..00000000
--- a/docs/private/media/rest_record.md
+++ /dev/null
@@ -1,305 +0,0 @@
-# 录制及提取
-
-
-
-环信使用 REST 的方式来获取实时音视频的录制文件,包括录制的音频文件和视频文件。
-
-- 录制功能可以调用SDK接口控制开启,支持1v1录制和多人录制以及录制合成。
-- 录制文件默认仅在音视频服务器保存30天,到期后会进行删除,如需长期使用,请在部署前确认保存时长。
-- 录制系统会自动根据音视频编码选择文件格式,一般是.webm,.mkv和.mp4三种;合成录制文件固定为.mp4格式。
-- 如果需要其他格式,用户可以自己下载转换,转换工具建议用ffmpeg。
-- 获取录制文件后,如果需要下载,需要通过文件详情中的URL直接下载保存。
-- SDK开启录制
- - [Android 1v1](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_call_manager.html#af7447a6669e37d5d0bbf976b098b435b)
- - [Android 多人](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a6a9bd493a33203869d37780d7f8cdbfe)
- - [iOS 1v1](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a429bded3e8040875d02e84936cd75521)
- - [iOS 多人](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7cd6cdf1b116964fe114d700baf26dc6)
- - [Web 1v1](http://webim-h5.easemob.com/webrtc/jsdoc/out/global.html#makeVideoCall)
- - [Web 多人](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#createConference)
-- 获取录制文件时所需要的confrId,可以从SDK中获取,下面以新版本SDK属性名称为例,老版本以各端SDK头文件内的属性名称为准。
- - 移动端:
- - iOS:
- - 1v1时:在监听通话建立完成的回调中 - (void)callDidConnect:(EMCallSession *)aSession,通过 aSession.serverVideoId 获取(serverVideoId为 EMCallSession 的属性,只有在通话建立完成后通过 EMCallSession 才能拿到 serverVideoId,否则在通话未建立完成时通过 EMCallSession 取到 serverVideoId 的为空);
- - 多人时:在创建并加入会议 createAndJoinConferenceWithType 或者加入会议室 joinConferenceWithConfId 成功后,通过回调中的 EMCallConference 对象 aCall.confId 获取到;
- - Android:
- - 1v1时:在通话状态改变的监听中 void onCallStateChanged (CallState callState, CallError error),通过判断 callState 的状态为 connected 通话建立完成时,通过 EMCallSession 的 getServerRecordId () 获取到录制文件id;
- - 多人时:在创建并加入会议 createAndJoinConference 或者加入会议室 joinConference 成功后,通过 callback 中的 EMConference 对象 调用 getConferenceId () 获取到;
- - web端:1v1时为WebIM.call.getServerRecordId();多人时可以在createConference的回调里拿到;
-
-服务器端存储的是压缩后的视频。录制文件的大小(每分钟)为:
-
-- 240p: 0.75M ~ 3M
-- 480p: 2.2M ~ 7.5M
-- 720p: 6.5M ~ 18.5M
-- 1080p: 15M ~ 37.5M
-
-
-
-:::tip
-1、通话时长<5s可能会出现服务器录制失败的情况。
-2、生成录制文件所花的时间和通话时长有关,通话时间越长,生成录制文件的时间也越长。一般情况下,通话时间1小时以下,在通话结束后2小时可以获取到,为了保证录制文件数据完整建议在24小时后获取。
-:::
-
-------
-
-# REST API
-
-服务器录制文件获取在集成过程中,可以使用以下4个接口获取录制文件。请查看以下 REST API 详细文档说明。
-
-| 名称 | 请求 |
-| :------------------------------- | :----------------------------------------------------------- |
-| 会议ID获取全部录制文件 | {orgName}/{appName}/audio/{confrId} |
-| 开始结束时间获取全部录制文件 | {orgName}/{appName}/audio/{beginTime}/{endTime}/{startId}/{length} |
-| 开始结束时间获取全部合成录制文件 | {orgName}/{appName}/audio/merge/{beginTime}/{endTime}/{startId}/{length} |
-| 获取会议内user全部录制文件 | {orgName}/{appName}/audio/{userName}/{confrId} |
-
-## 会议ID获取全部录制文件
-
-通过指定会议ID获取全部的录制文件。
-
-:::tip
-录制的文件默认保存30天。
-:::
-#### HTTP Request
-
-| ![img](/images/privitization/get.png) | **{orgName}/{appName}/audio/{confrId}** |
-| :----------------------------------------------------------- | :-------------------------------------- |
-
-需要在请求时对应填写{confrId}会议ID,如果当前没有会议ID,请从其他接口获取。
-
-#### Request Headers
-
-| 参数 | 说明 |
-| :------------ | :--------------- |
-| Content-Type | application/json |
-| Authorization | Bearer ${token} |
-
-#### Response Body
-
-返回的文件数据列表是以文件编号id,升序排列。
-
-| 参数 | 说明 |
-| :------------- | :----------------------------------------------------------- |
-| id | 录制文件数字编号 |
-| owner | 录制文件所在的appkey |
-| confrBeginTime | 录制文件所在多人会议的开始时间 |
-| confrEndTime | 录制文件所在多人会议的结束时间 |
-| confrType | 会议类型,“CONFR”、“COMMUNICATION”均是普通会议、~~“COMMUNICATION_MIX”混音会议最多支持30人以下的音频混合、“LIVE”互动会议~~ |
-| confrId | 会议ID,全局唯一 |
-| userName | 参加会议人员,以appkey_username表示(talker,直播模式下的主播) |
-| memberName | 参加会议人员,以appkey_username表示(talker,直播模式下的主播)IM情况下为 JID,系统唯一的ID |
-| accessId | 参加会议时链接的ID |
-| pubStreamId | 推流ID |
-| recordType | 录制文件类型,“ONLY_REC_ONE_AV”是单人音视频,“ONLY_REC_ONE_DESKTOP”是单人共享桌面,“MERGE_ALL”合成视频文件 |
-| recordTime | 录制完成时间 |
-| expireTime | URL过期时间 |
-| url | 录制文件的下载链接 |
-
-#### 请求示例
-
-```
-curl -X GET -i "http://a1.easemob.com/easemob-demo/testapp/audio/IM_X364829524644331520C14" -H 'Authorization: Bearer YWMte3bGuOukEeiTkNP4grL7iwAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnKdc-ZgBPGgBFTrLhhyK8woMEI005emtrLJFJV6aoxsZSioSIZkr5kw' -H 'Content-Type: application/json'
-```
-
-#### 可能返回的结果示例
-
-- 返回值200,表示成功获取录制文件
-- 返回结果是500,可能是服务器故障
-- 返回结果是**429、503**或者其他**5xx**,有可能代表该接口被限流了,请稍微暂停一下并重试。详见[接口限流说明](../../product/limitationapi.html)
-
-```
-{
- "id": 109,
- "owner": "easemob-demo#testapp",
- "confrBeginTime": "2019-02-21 17:56:04",
- "confrEndTime": "2019-02-21 17:56:46",
- "confrType": "LIVE",
- "confrId": "IM_X364829548358926336C16",
- "memberId": "IM_X364829548358926336C16M21",
- "memberName": "easemob-demo#testapp_user1",
- "userName": "easemob-demo#testapp_user1",
- "accessId": "HI365195406759428096",
- "pubStreamId": "rtc-10-xbd__Of_C16M21",
- "recordType": "ONLY_REC_ONE_AV",
- "recordTime": "2019-02-21 17:56:49",
- "expireTime": "2019-03-23 17:56:49",
- "url": "http://kefu-media-files.oss-cn-beijing.aliyuncs.com/1esugl4lgti4qbtle1l450gunvphf9uhi3kmb6b9rdc10cn0jf8g/20190221170556-000000410.webm?Expires=9223372036854775&OSSAccessKeyId=LTAI3pBwoxnmCWUw&Signature=tpQRDw0HS9feBkgnvmYObY2U850%3D"
-}
-```
-
-
-
-------
-
-## 开始结束时间获取全部录制文件
-
-开始到结束时间内,以某个录制文件为起始点,获取之后一定数量的录制文件接口。
-
-:::tip
-录制的文件默认保存30天。
-:::
-
-#### HTTP Request
-
-| ![img](/images/privitization/get.png) | **{orgName}/{appName}/audio/{beginTime}/{endTime}/{startId}/{length}** |
-| :----------------------------------------------------------- | :----------------------------------------------------------- |
-
-
-需要在请求时对应填写{beginTime}/{endTime},起始录制文件id编号{startId},获取的数量{length}。`length限制长度是100,如果请求超过100是会返回错误`。
-
- **如果要取从开始至结束时间的前100个录制文件,起始录制文件id可以为0,获取数量100;如果要继续获取后面的100个录制文件,需要将上次获取的最后一个录制文件id作为下一次请求的起始id继续发起请求。**
-
-#### Request Headers
-
-| 参数 | 说明 |
-| :------------ | :--------------- |
-| Content-Type | application/json |
-| Authorization | Bearer ${token} |
-
-#### 请求示例
-
-```
-curl -X GET -i "http://a1.easemob.com/easemob-demo/testapp/audio/20190101080607/20190304050607/0/2" -H 'Authorization: Bearer YWMte3bGuOukEeiTkNP4grL7iwAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnKdc-ZgBPGgBFTrLhhyK8woMEI005emtrLJFJV6aoxsZSioSIZkr5kw' -H 'Content-Type: application/json'
-```
-
-#### 可能返回的结果示例
-
-- 返回值200,表示成功获取录制文件
-- 返回结果是500,可能是服务器故障
-- 返回结果是**429、503**或者其他**5xx**,有可能代表该接口被限流了,请稍微暂停一下并重试。详见[接口限流说明](../../product/limitationapi.html)
-
-
-```
-{
- "id": 112,
- "owner": "easemob-demo#testapp",
- "confrBeginTime": "2019-02-21 17:56:04",
- "confrEndTime": "2019-02-21 17:56:46",
- "confrType": "LIVE",
- "confrId": "IM_X364829548358926336C16",
- "memberId": "IM_X364829548358926336C16M21",
- "memberName": "easemob-demo#testapp_user1",
- "userName": "easemob-demo#testapp_user1",
- "accessId": "HI365195406759428096",
- "recordType": "ONLY_REC_ONE",
- "recordTime": "2019-02-21 17:56:49",
- "expireTime": "2019-03-23 17:56:49",
- "url": "http://kefu-media-files.oss-cn-beijing.aliyuncs.com/mlgh7n0ltu09sehvst53dh8huurqrj6f5knbhfbnopppgoocr67/20190221170556-000000408.webm?Expires=9223372036854775&OSSAccessKeyId=LTAI3pBwoxnmCWUw&Signature=hZk4jJDcMsuJfioscv%2B4L1zk1aA%3D"
-}
-```
-
-
-------
-
-## 开始结束时间获取全部合成录制文件
-
-开始到结束时间内,以某个录制文件为起始点,获取之后一定数量的合成录制文件接口。
-
-:::tip
-录制的文件默认保存30天。
-:::
-
-#### HTTP Request
-
-| ![img](/images/privitization/get.png) | **{orgName}/{appName}/audio/merge/{beginTime}/{endTime}/{startId}/{length}** |
-| :----------------------------------------------------------- | :----------------------------------------------------------- |
-
-需要在请求时对应填写{beginTime}/{endTime},起始录制文件id编号{startId},获取的数量{length}。`length限制长度是100,如果请求超过100是会返回错误`。
-
-**如果要取从开始至结束时间的前100个合成录制文件,起始录制文件id可以为0,获取数量100;如果要继续获取后面的100个合成录制文件,需要将上次获取的最后一个合成录制文件id作为下一次请求的起始id继续发起请求。**
-
-#### Request Headers
-
-| 参数 | 说明 |
-| :------------ | :--------------- |
-| Content-Type | application/json |
-| Authorization | Bearer ${token} |
-
-#### 请求示例
-
-```
-curl -X GET -i "http://a1.easemob.com/easemob-demo/testapp/audio/merge/20190101080607/20190304050607/0/2" -H 'Authorization: Bearer YWMte3bGuOukEeiTkNP4grL7iwAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnKdc-ZgBPGgBFTrLhhyK8woMEI005emtrLJFJV6aoxsZSioSIZkr5kw' -H 'Content-Type: application/json'
-```
-
-#### 可能返回的结果示例
-
-- 返回值200,表示成功获取录制文件
-- 返回结果是500,可能是服务器故障
-- 返回结果是**429、503**或者其他**5xx**,有可能代表该接口被限流了,请稍微暂停一下并重试。详见[接口限流说明](../../product/limitationapi.html)
-
-
-```
-{
- "id": 112,
- "owner": "easemob-demo#testapp",
- "confrBeginTime": "2019-02-21 17:56:04",
- "confrEndTime": "2019-02-21 17:56:46",
- "confrType": "LIVE",
- "confrId": "IM_X364829548358926336C16",
- "memberId": "IM_X364829548358926336C16M21",
- "memberName": "easemob-demo#testapp_user1",
- "userName": "easemob-demo#testapp_user1",
- "accessId": "HI365195406759428096",
- "recordType": "MERGE_ALL",
- "recordTime": "2019-02-21 17:56:49",
- "expireTime": "2019-03-23 17:56:49",
- "url": "http://kefu-media-files.oss-cn-beijing.aliyuncs.com/mlgh7n0ltu09sehvst53dh8huurqrj6f5knbhfbnopppgoocr67/20190221170556-000000408.webm?Expires=9223372036854775&OSSAccessKeyId=LTAI3pBwoxnmCWUw&Signature=hZk4jJDcMsuJfioscv%2B4L1zk1aA%3D"
-}
-```
-
-
-------
-
-## 获取会议内user全部录制文件
-
-指定会议ID内的用户获取全部录制文件。
-
-:::tip
-录制的文件默认保存30天。
-:::
-
-#### HTTP Request
-
-| ![img](/images/privitization/get.png)| **{orgName}/{appName}/audio/{userName}/{confrId}** |
-| :----------------------------------------------------------- | :------------------------------------------------- |
-
-需要在请求时对应填写{confrId}会议ID,如果当前没有会议ID,请从其他接口获取。以及{userName}用户名。
-
-#### Request Headers
-
-| 参数 | 说明 |
-| :------------ | :--------------- |
-| Content-Type | application/json |
-| Authorization | Bearer ${token} |
-
-#### 请求示例
-
-```
-curl -X GET "http://a1.easemob.com/easemob-demo/testapp/audio/user1/IM_X364829524644331520C14" -H 'Authorization: Bearer YWMte3bGuOukEeiTkNP4grL7iwAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnKdc-ZgBPGgBFTrLhhyK8woMEI005emtrLJFJV6aoxsZSioSIZkr5kw' -H 'Content-Type: application/json'
-```
-
-#### 可能返回的结果示例
-
-- 返回值200,表示成功获取录制文件
-- 返回结果是500,可能是服务器故障
-- 返回结果是**429、503**或者其他**5xx**,有可能代表该接口被限流了,请稍微暂停一下并重试。详见[接口限流说明](../../product/limitationapi.html)
-
-
-```
-{
- "id": 112,
- "owner": "easemob-demo#testapp",
- "confrBeginTime": "2019-02-21 17:56:04",
- "confrEndTime": "2019-02-21 17:56:46",
- "confrType": "LIVE",
- "confrId": "IM_X364829548358926336C16",
- "memberId": "IM_X364829548358926336C16M21",
- "memberName": "easemob-demo#testapp_user1",
- "userName": "easemob-demo#testapp_user1",
- "accessId": "HI365195406759428096",
- "recordType": "ONLY_REC_ONE",
- "recordTime": "2019-02-21 17:56:49",
- "expireTime": "2019-03-23 17:56:49",
- "url": "http://kefu-media-files.oss-cn-beijing.aliyuncs.com/mlgh7n0ltu09sehvst53dh8huurqrj6f5knbhfbnopppgoocr67/20190221170556-000000408.webm?Expires=9223372036854775&OSSAccessKeyId=LTAI3pBwoxnmCWUw&Signature=hZk4jJDcMsuJfioscv%2B4L1zk1aA%3D"
-}
-```
diff --git a/docs/private/media/rest_whiteboard.md b/docs/private/media/rest_whiteboard.md
deleted file mode 100644
index cfbf2903..00000000
--- a/docs/private/media/rest_whiteboard.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# 互动白板REST简介
-
-| 名称 | 请求 | method |
-| ---------------- | ---------------------------------------------------------- | ------ |
-| 创建或者加入白板 | /{orgName}/{appName}/whiteboards/joinorcreate/byname | POST |
-| 上传文件 | /{orgName}/{appName}/whiteboards/upload/{whiteboardUserId} | POST |
-
-## 创建或者加入白板
-
-HTTP Request
-
-| ![img](/images/privitization/post.png) | /{orgName}/{appName}/whiteboards/joinorcreate/byname |
-| ---- | ---------------------------------------------------- |
-
-| 参数 | 说明 |
-| :------------ | :--------------- |
-| Content-Type | application/json |
-| Authorization | Bearer ${token} |
-
-#### Request Body
-
-| 名称 | 类型 | 描述 |
-| :------------- | :----- | :----------------------------------------------------------- |
-| userId | String | im用户的userId |
-| whiteBoardName | String | 将要创建或者加入的白板名称 |
-| password | String | 白板密码 |
-| level | int | 共1-8级,创建白板时可以指定白板成员的默认等级,4级及以上可以操作白板,以下不能操作 |
-| layout | int | 页面布局,共三种分别取0/1/2 |
-| ratio | String | 页面比例比如2:1,比例范围为1:5至5:1 |
-
-#### Response Body
-
-| 名称 | 类型 | 描述 |
-| :------------ | :------ | :------------------------------------ |
-| whiteBoardUrl | string | 将要打开的白板地址 |
-| domainName | String | 白板的域名 |
-| socketIOUrl | String | SocketIO链接地址 |
-| socketIOPath | String | SocketIO链接路径 |
-| roomId | String | 白板系统的userId,注意这不是IM的userId |
-| token | String | 白板的token |
-| status | boolean | 请求状态 |
-
-#### 请求示例
-
-```
-curl -L -X POST 'http://127.0.0.1:8031/easemob-demo/chatdemoui/whiteboards/joinorcreate/byname' \
---header 'Authorization: Bearer YWMtmSQukKrsEeqv9QV7AzcHWwAAAAAAAAAAAAAAAAAAAAFDtjwasNNKD6W3CET2O3RNAQMAAAFynSVq-wBPGgBKfz02AUoGLesKFexM4_1uAAW25lj33z0siltXBgRoWQ' \
---header 'Content-Type: application/json' \
---data-raw '{
- "userId": "zd2",
- "whiteBoardName": "128",
- "password": "1",
- "level":5
-}'
-```
-
-根据请求返回的status字段判断请求是否成功
-
-```
-{
- "whiteBoardUrl": "http://whiteboards-hsb.easemob.com/index.html?roomId=ZBXZH0001TGJ5AAYK400&userId=ZBXZH0001TGJ5AAYK400-0&socketIOUrl=http://127.0.0.1:8900/message&socketIOPath=/socket.io/&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3aGl0ZWJvYXJkIiwiaXNzIjoiZWFzZW1vYiIsInVzZXJOYW1lIjoiemQyIiwiZXhwIjoxNTk3NDg1NTExLCJ1c2VySWQiOiJaQlhaSDAwMDFUR0o1QUFZSzQwMC0wIn0.izUKAFrQBKRnDEg1d_yt-Xe9DGwZobb7Oa9-03yLO0Q&domainName=http://127.0.0.1:8031&appKey=easemob-demo#chatdemoui&isCreater=true",
- "domainName": "http://127.0.0.1:8031",
- "socketIOUrl": "http://127.0.0.1:8900/message",
- "socketIOPath": "/socket.io/",
- "userId": "ZBXZH0001TGJ5AAYK400-0",
- "roomId": "ZBXZH0001TGJ5AAYK400",
- "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3aGl0ZWJvYXJkIiwiaXNzIjoiZWFzZW1vYiIsInVzZXJOYW1lIjoiemQyIiwiZXhwIjoxNTk3NDg1NTExLCJ1c2VySWQiOiJaQlhaSDAwMDFUR0o1QUFZSzQwMC0wIn0.izUKAFrQBKRnDEg1d_yt-Xe9DGwZobb7Oa9-03yLO0Q",
- "status": true
-}
-```
-
-## 白板上传文件
-
-HTTP Request 注意这里的whiteboardUserId不是IM的useId,是上一个创建或者加入白板里返回的userId
-
-| ![img](/images/privitization/post.png) | /{orgName}/{appName}/whiteboards/upload/{whiteboardUserId} |
-| ---- | ---------------------------------------------------------- |
-
-#### 请求示例
-
-```
-curl -L -X POST 'http://127.0.0.1:8031/easemob-demo/chatdemoui/whiteboards/upload/ZBW51UX8XTGFYJX8LL0-0' \
---header 'Content-Type: multipart/form-data' \
---form 'file=@/D:/easemob/文档/中文名字1.jpg'
-```
-
-#### 返回值
-
-- 返回200表示成功
\ No newline at end of file
diff --git a/docs/private/media/scenario_live.md b/docs/private/media/scenario_live.md
deleted file mode 100644
index 454c172e..00000000
--- a/docs/private/media/scenario_live.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# 多人视频互动直播场景介绍
-
-## 概述
-
-环信音视频能力有几种典型的应用模式,包括:一对一音视频、多人音视频会议、多人音视频互动直播。
-
-![img](/images/privitization/em-rtcsdk-scenarios.png)
-
-多人音视频互动直播的典型场景包括多人视频相亲、线上KTV、狼人杀直播、教育小班课、教育双师课等。
-
-## 多人视频互动直播与传统CDN直播的区别
-
-很多开发者和产品经理经常会问,我要做一个直播产品,我应该用传统CDN直播,还是应该用多人视频互动直播呢?
-
--传统CDN直播是主播推流到CDN,观众从CDN拉流观看。主播和观众之间是一对多的单向关系。主播与观众或观众之间的互动主要通过[文字聊天室](../../document/server-side/overview.html#聊天室管理)来实现,比如聊天室消息、弹幕、刷礼物等。传统CDN直播最大的优点是可以支持极高的同时在线人数,数百万数千万都不是问题,但互动性稍弱。
-
--多人视频互动直播则可以有多个主播进行远程的视频连麦互动,观众上麦后,也可以与主播之间进行视频连麦互动。
-
-**多人视频互动极大丰富了直播的可玩度,带来了很多新型应用场景,比如远程培训直播、教育小班课、双师课等。**
-
-## 多人视频互动直播与多人音视频会议的区别
-
-1. 从产品角度看,多人音视频会议和多人音视频互动直播的主要区别是:
-- 多人音视频会议的所有参会者都有相同的权利,都可以随时发布音频和视频,也就是说,每个人都是主播。
-
-- 多人音视频互动直播的参会者除了主播外,还有观众。观众只能观看,如果要发布音频和视频,需要申请上麦,切换到主播角色。
-
-2. 从技术架构角度看,多人音视频会议和多人音视频互动直播使用的是相同的技术架构--**媒体流发布和订阅的技术架构**,主要区别是:
-:::tip
-发布是指参会者发布媒体流(即发言,包括视频流和音频流)到服务器,其他人收到发布事件然后去订阅拉取媒体流。
-:::
-- 多人音视频会议场景中,在创建会议时指定默认角色为主播,即每个参会者加入会议后都可以发言。
-
-- 多人音视频互动直播场景中,在创建会议时指定默认角色为观众,除了管理员(同时也可以是主播)以外,其他人默认是观众。管理员可以设置指定观众成主播实现上麦操作;或设置指定主播为观众,实现下麦操作。
-
-3. 相同点:
-
-**多人音视频里有管理员,主播和观众三种角色**
-
-- 管理员拥有最高权限,可以发布媒体流,订阅媒体流,设定其他人是主播还是观众
-- 主播可以发布媒体流,订阅媒体流
-- 观众只有订阅媒体流权限
-
-**多人音视频会议和多人音视频互动直播模式都支持白板、共享桌面**
-
-## 实现方案
-
-多人视频会议开发的入口文档是:[多人通话简介](conference_introduction)。这个文档包含了以下部分:
-
-- 功能列表:各端功能清单
-- 通话流程:通话流程描述
-- 角色权限:会议室的角色权限说明
-- 客户端SDK及demo源码:开发者可以先下载demo,体验demo中的一对一音视频功能。如有需要,还可以查看demo的源代码。
-- 计费说明
-
-
-多人视频会议如果需要环信即时通讯云的文字聊天室实现IM沟通功能,请详见文档:
-
-服务器端: [聊天室管理](http://doc.easemob.com/document/server-side/chatroom.html)
-
-Android: [聊天室管理](http://doc.easemob.com/document/android/room_overview.html)
-
-iOS: [聊天室管理](http://doc.easemob.com/document/ios/room_overview.html)
-
-web端: [聊天室管理](http://doc.easemob.com/document/web/room_overview.html)
-
-微信小程序: [聊天室管理](http://doc.easemob.com/document/applet/room_overview.html)
-
-PC端: [聊天室管理](https://docs-im.easemob.com/im/pc/basics/chatroom)
-
-
-
\ No newline at end of file
diff --git a/docs/private/media/scenario_meeting.md b/docs/private/media/scenario_meeting.md
deleted file mode 100644
index fb3db517..00000000
--- a/docs/private/media/scenario_meeting.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# 视频会议场景方案介绍
-
-## 概述
-
-环信音视频能力有几种典型的应用模式,包括:一对一音视频、多人音视频会议、多人音视频互动直播。
-
-![img](/images/privitization/em-rtcsdk-scenarios.png)
-
-多人音视频会议的典型场景包括企业多人视频会议、移动协同办公、远程医疗会诊、会诊模式的视频客服等。
-
-## 典型需求
-
-多人视频会议场景的典型功能需求包括:
-
-- 多人音频通话
-- 多人视频通话
-- 共享桌面
-- 外部视频源输入
-- 美颜
-- 服务器端录制及下载
-- 即时沟通:在使用多人会议时,也可以通过集成环信即时通讯实现IM沟通,如发文字、图片、语音片段、各种自定义消息等)
-- 视频流水印
-- 会议室的管理:创建会议、删除会议、获取指定会议室详情、加入会议室、退出会议室
-- 会议室的人员管理:获取会议室参会人名列表、踢人,设置观众为主播,设置主播为观众等
-- 多端支持:Android、iOS、Web、PC、小程序
-
-:::tip
-在多人视频会议场景下用到的某些功能需要在特定的浏览器、版本或插件下才能使用。
所以为了简化用户体验,不推荐直接使用浏览器,**建议引导用户使用本地应用(如PC端应用)**。
-
-:::
-## 实现方案
-
-1. 多人视频会议开发的入口文档是:[多人通话简介](conference_introduction),这个文档包含了以下部分:
-
-- 功能列表:各端功能清单
-- 通话流程:通话流程描述
-- 角色权限:会议室的角色权限说明
-- 客户端SDK及demo源码:开发者可以先下载demo,体验demo中的一对一音视频功能。如有需要,还可以查看demo的源代码。
-- 计费说明
-
-
-2. 多人视频会议如果需要环信即时通讯云的文字聊天室实现IM沟通功能,请详见文档:
-
-服务器端: [聊天室管理](http://doc.easemob.com/document/server-side/chatroom.html)
-
-Android: [聊天室管理](http://doc.easemob.com/document/android/room_overview.html)
-
-iOS: [聊天室管理](http://doc.easemob.com/document/ios/room_overview.html)
-
-web端: [聊天室管理](http://doc.easemob.com/document/web/room_overview.html)
-
-微信小程序: [聊天室管理](http://doc.easemob.com/document/applet/room_overview.html)
-
-PC端: [聊天室管理](https://docs-im.easemob.com/im/pc/basics/chatroom)
-
-
-
-
-## 客户端应用源码
-
-“环信视频会议”Demo主要面向开发者,用于演示如何通过调用音视频API实现视频会议基础功能,如需打造产品级别应用,要按自身项目需求完成UI/UE设计。
-
-### Demo 下载
-
-Demo下载地址请见: [demo下载](common_clientsdk#场景demo及源码下载)
-
-### Demo 源码
-
-我们在 Github 提供了完整的 Demo源代码,大家可以在 Github 上获取。
-
-- [Android](https://github.com/easemob/videocall-android)
-
-- [iOS](https://github.com/easemob/videocall-ios)
-
-- [Web](https://github.com/easemob/videocall-web)
-
-- [桌面](https://github.com/easemob/videocall-web) (桌面端使用electron打包了web端的代码,跟web端是同一套代码)
-
-
-### Demo 功能介绍
-
-#### **创建或加入房间**
-
-1. 创建房间:在本页面,输入一个不存在的房间号和密码,可以创建新房间
-2. 加入房间:如果输入当前存在的房间号,则加入现有房间
-
-:::tip
-请选择“以主播身份进入房间”。
-“以观众身份进入房间”属于环信多人音视频互动直播API的一部分,使用说明请见 [互动直播介绍](scenario_live)
-:::
-![img](/images/privitization/meeting-demo4.png?w=300)
-#### **音视频会议主界面**
-
-在音视频会议的主界面,演示了以下功能:
-
-- 打开或关闭麦克风。
-- 打开或关闭摄像头。切换前后摄像头。
-- 查看当前会议室参会人员名单
-- 踢人
-- 上麦、下麦
-- 退出会议室
-
-:::tip
-“上麦/下麦”属于环信多人音视频互动直播API的一部分,使用说明请见 [互动直播介绍](scenario_live)
-:::
-
-![img](/images/privitization/meeting-demo5.png?w=300)
\ No newline at end of file
diff --git a/docs/private/media/scenario_one2one.md b/docs/private/media/scenario_one2one.md
deleted file mode 100644
index 06437dd4..00000000
--- a/docs/private/media/scenario_one2one.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# 1对1音视频场景介绍
-
-## 概述
-
-环信音视频能力有几种典型的应用模式,包括:一对一音视频、多人音视频会议、多人音视频互动直播。
-
-![img](/images/privitization/em-rtcsdk-scenarios.png)
-
-一对一音视频用于实现1对1语音通话和1对1视频通话,典型场景包括社交交友,远程心理咨询、远程医疗、视频面试、一对一在线教育、远程视频辅助等。
-
-## 需求
-
-1对1音视频场景的主要功能需求包括:
-
-- 1对1音频通话
-- 1对1视频通话
-- 外部视频源输入:用户可自行采集视频数据,比如接入外部摄像头;这个功能也可以用于对接第三方美颜,变声等。以Android为例,请参考[用户自定义数据采集及数据处理](one2one_android.html#变声-自定义音频)接口文档
-- 美颜
-- AI鉴黄
-- 服务器端录制及下载
-- 即时沟通:在使用音视频服务时,也可以通过集成环信即时通讯实现IM沟通,如发文字、图片、语音片段、各种自定义消息等
-
-## 实现方案
-
-1. 一对一音视频开发的入口文档是:[1对1通话简介](one2one_introduction.html),这个文档包含了以下部分:
-
-- 功能列表:各端功能清单
-- 通话流程:通话流程描述
-- 客户端SDK及demo源码:开发者可以先下载demo,体验demo中的一对一音视频功能。如有需要,还可以查看demo的源代码。
-- 计费说明
-
-2. 一对一音视频还需要用到环信即时通讯云的基础IM功能,请详见文档:
-
-服务器端:[服务端集成](http://doc.easemob.com/document/server-side/overview.html)
-
-Android:[Android SDK 介绍及导入](http://doc.easemob.com/document/android/quickstart.html)
-
-iOS:[iOS SDK 快速集成](http://doc.easemob.com/document/ios/quickstart.html)
-
-web端: [Web IM 介绍](http://doc.easemob.com/document/web/quickstart.html)
-
-微信小程序: [微信小程序SDK简介](http://doc.easemob.com/document/applet/wechat.html)
-
-PC端: [桌面端集成说明](https://docs-im.easemob.com/im/pc/intro/integration)
\ No newline at end of file
diff --git a/docs/private/media/scenario_tc-host.md b/docs/private/media/scenario_tc-host.md
deleted file mode 100644
index 1f3434f9..00000000
--- a/docs/private/media/scenario_tc-host.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# 主持模式
-
-## 前言
-本文将简要分享语音聊天室中主持玩法的的应用场景,并讲述基于环信语聊解决方案,主持玩法的实现步骤。
-
-:::tip
-`仅特定的私有化版本SDK支持语聊解决方案.` 开发者如有需求,请联系商务咨询。
-:::
-
-主持玩法是目前语音连麦聊天室中必备的玩法之一,通过房主的主持,大家可以有序的进行发言,更好的组织聊天室的互动场景。
-
-在主持模式,由房主指定谁可以发言,被指定的主播可以发言,其他人不能发言。这个功能是通过会议属性来实现的,当房主指定发言人后,房主修改会议属性,所有人收到会议属性变更通知,如果发现会议属性中是指定的自己发言,自己打开麦克风。其他人关闭。当房主指定另外一个主播发言时,房主修改会议属性,所有人收到会议属性变更通知,当前主播自动下麦。
-
-## 实现方案
-我们可以通过一张图,来了解主持模式中接口的调用逻辑:
-
-![img](/images/privitization/tc_logic_host.png)
-
-上图中每步涉及到的iOS/Android接口如下:
-
-| 步骤 | iOS API | Android API |
-| :--------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
-| 1.设置主持会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) |
-| 2.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) |
-| 3.指定某个主播发言,并修改会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) |
-| 4.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) |
-| 5.指定者说话,其他人闭麦 | [EMClient.sharedClient.conferenceManager updateConference: isMute:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#abc3d1658875a99bdd1f5f1158a74e789) | [EMClient.getInstance().conferenceManager().openVoiceTransfer();EMClient.getInstance().conferenceManager().closeVoiceTransfer();](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a7b4bd022d9daf8fe127d89494897bf99) |
-| 6.指定某个主播发言,并修改会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) |
-| 7.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) |
-| 8.指定者说话,其他人闭麦 | [EMClient.sharedClient.conferenceManager updateConference: isMute:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#abc3d1658875a99bdd1f5f1158a74e789) | [EMClient.getInstance().conferenceManager().openVoiceTransfer();EMClient.getInstance().conferenceManager().closeVoiceTransfer();](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a7b4bd022d9daf8fe127d89494897bf99) |
-
-语音聊天室可根据业务模型提供多种模式与玩法。目前环信提供的语聊集成方案对准备开发和正在集成聊天室的开发者来说,不仅可以更好的理解环信 IM 即时通讯、音视频所提供的丰富功能,还能通过产品层面的操作,帮助开发者构思出更多的互动玩法,扩展更多有意思的场景。
-
diff --git a/docs/private/media/scenario_tc-robmic.md b/docs/private/media/scenario_tc-robmic.md
deleted file mode 100644
index 05773243..00000000
--- a/docs/private/media/scenario_tc-robmic.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# 抢麦模式
-
-## 前言
-本文将简要分享语音聊天室中抢麦玩法的的应用场景,并讲述基于环信语聊解决方案,实现抢麦玩法的步骤。
-
-:::tip
-`仅特定的私有化版本SDK支持语聊解决方案.` 开发者如有需求,请联系商务咨询。
-:::
-
-在抢麦模式下,只有抢到麦的主播可以发言,由 AppServer 来决定是否抢到麦当房主发起抢麦时;
-
-首先请求 AppServer , AppServer 确定主播可以抢麦,返回成功的同时,AppServer 开始计时,在计时结束前或者抢到麦的主播主动释放麦之前,其他主播请求 AppServer 抢麦返回失败。主播抢到麦后,修改会议属性,告知所有人自己抢到了,同时开始倒计时,倒计时结束后,主动重新设置会议属性,告诉所有人自己释放麦。其他人收到抢麦的会议属性变化回调后更新 UI,并开始倒计时,在倒计时结束或者收到释放麦的会议属性变化前,所有人不可以发起抢麦操作。
-
-## 实现方案
-
-我们可以通过一张图,来了解抢麦模式中接口的调用逻辑:
-
-![img](/images/privitization/tc_logic_robmic.png)
-
-上图中每步涉及到的 iOS/Android 接口如下,其中部分调用到了 AppServer 的接口,开发者需要自己实现 AppServer 功能
-
-| 步骤 | iOS API | Android API |
-| :---------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
-| 1.设置抢麦会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) |
-| 2.广播抢麦会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) |
-| 3.主播向AppServer发起抢麦请求 | AppServer API | Android与iOS调用接口相同 |
-| 4.返回抢麦成功结果 | AppServer API | Android与iOS调用接口相同 |
-| 5.主播改变会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) |
-| 6.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) |
-| 7.抢麦者说话,其他人闭麦 | [EMClient.sharedClient.conferenceManager updateConference: isMute:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#abc3d1658875a99bdd1f5f1158a74e789) | [EMClient.getInstance().conferenceManager().openVoiceTransfer();EMClient.getInstance().conferenceManager().closeVoiceTransfer();](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a7b4bd022d9daf8fe127d89494897bf99) |
-| 8.释放麦,改变会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) |
-| 9.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) |
-
-语音聊天室可根据业务模型提供多种模式与玩法。目前环信提供的语聊集成方案对准备开发和正在集成聊天室的开发者来说,不仅可以更好的理解环信 IM 即时通讯、音视频所提供的丰富功能,还能通过产品层面的操作,帮助开发者构思出更多的互动玩法,扩展更多有意思的场景。
\ No newline at end of file
diff --git a/docs/private/media/scenario_tc-scene.md b/docs/private/media/scenario_tc-scene.md
deleted file mode 100644
index 0cfb1186..00000000
--- a/docs/private/media/scenario_tc-scene.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# 临场模式
-
-## 前言
-
-本文简要分享语音聊天室中临场模式的使用场景,并概述基于环信音视频会议实现临场模式切换的主要步骤。
-:::tip
-`仅特定的私有化版本SDK支持语聊解决方案.` 开发者如有需求,请联系商务咨询。
-:::
-
-临场模式环信以常见的杀人游戏白天、黑夜示例两种临时模式的切换,示例并非完整展示游戏的过程。仅提供切换方法和思路,以便开发者学习使用。
-
-2018年后,由于实时音视频在社交应用中的广泛使用,影响了了大量私密社交和娱乐化社交的场景升级,娱乐社交方式不在停留在即时通讯的领域而更加激进的走向实时通讯领域。无论是连麦、直播或者场景化的聊天室。互动过程中更丰富发玩法自由切换,场景自由穿插组合成成为大部分社交应用的基础功能。业务模型的逐渐升级也推进环信语音连麦场景需要更迅速的提供通用的解决方案和集成支持。
-
-环信将音视频会议内的临时场景切换归纳形成临场模式集成方案,主要解决:
-
-- 用户通过业务场景的定义实现发言逻辑变更,用户使用行为变更等常用功能;
-- 通过此模式的集成实现,可以更快速的切换业务;
-- 保持音视频会议通讯的稳定;
-- 以及最大化的录制保存用户沟通的全部信息。
-
-下面将详细介绍语音聊天室临场模式的集成方法:
-
-临场模式中的场景切换核心是通过修改和广播会议属性,由客户端预先约定好会议属性内的参数对应业务进行对订阅流音频、视频设置实现,这个`至关重要!!!` 同时还增加了服务端 的修改接口,可以通过 REST API 对会议属性进行控制。下图详细介绍临时场景实现过程。
-
-## 临场变更
-
-![img](/images/privitization/tc_logic_scene.png)
-
-| 步骤 | iOS API | Android API | REST API |
-| :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :------- |
-| 1. 修改会议属性 | [EMConferenceManagerDelegate](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMConferenceManager.setConferenceAttribute](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | 近期上线 |
-| 2. 广播同步会议属性 | [EMConferenceManagerDelegate.h](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | - |
-| 3. 客户端按照约定参数进行muteRemote指定的特殊用户并mute自身,并且配合UI进行场景分别定制 | [muteRemoteAudio:mute](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28f9297ad2411c6aa9bdbb291bb8df26) | [muteRemoteAudio](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#aa55d14555c59930263659b1f608e8f18) | - |
-
-4. 当前语聊demo中的特殊主播用户(狼人)在夜晚场景可以自由发言,其他主播夜晚将无法发言;
-
-5. 所有订阅未改变,按照会议默认的方式继续同步;
-
-6. 但是由于其他主播用户设置muteRemote的特殊用户,将不进行特殊用户发言发本地播放行为。从而实现了临时场景屏蔽;
-
-
-## 临场变更恢复
-
-![img](/images/privitization/tc_logic_scene_reset.png)
-
-| 步骤 | iOS API | Android API | REST API |
-| :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :------- |
-| 1. 修改会议属性 | [EMConferenceManagerDelegate](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMConferenceManager.setConferenceAttribute](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | 近期上线 |
-| 2. 广播同步会议属性 | [EMConferenceManagerDelegate.h](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | - |
-| 3. 客户端按照约定参数取消之前muteRemote指定的特殊用户并mute自身,并且配合UI进行场景恢复 | [muteRemoteAudio:mute](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28f9297ad2411c6aa9bdbb291bb8df26) | [muteRemoteAudio](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#aa55d14555c59930263659b1f608e8f18) | - |
-
-临场模式的优势在于:
-
-1. 通过会议属性的切换同步,可以快速通知到各客户端场景切换,并且可以使新用户接入时继承最新的会议状态衔接场景功能。
-2. 过程中没有改变会议订阅的情况,与服务器之间交互行为减少,减少其他非必要的网络延迟,符合多次、小范围、临时的场景切换的要求。
-3. 保持全员通话畅通的基础上可以最大限度的保留原始素材的服务端录制,对后续的回溯播放提供完整的信息。
-
-以上是临场模式的集成介绍,临场模式配合各种玩法,希望结合实际业务完成更多的聊天室互动场景。如有相关集成问题可以联系环信支持与产品咨询。另有更多的玩法集成请考到其他常见集成文档。
\ No newline at end of file
diff --git a/docs/private/media/scenario_tc.md b/docs/private/media/scenario_tc.md
deleted file mode 100644
index f4604c31..00000000
--- a/docs/private/media/scenario_tc.md
+++ /dev/null
@@ -1,176 +0,0 @@
-# 语音连麦聊天室集成介绍
-
-
-## 前言
-本文将简要分享几个语音聊天室的应用场景,并讲述基于环信 SDK ,实现语音连麦聊天室的步骤。
-:::tip
-`仅特定的私有化版本SDK支持语聊解决方案.` 开发者如有需求,请联系商务咨询。
-:::
-
-语音聊天是社交软件必备的功能,语音相比文字图片更丰富,比视频又更简便,是天然的社交工具。除了单纯的1对1语音或视频聊天,在实时音视频技术支持下,很多 APP 已经延伸出多人语聊房、语音电台、语音游戏、私人聊天房、KTV 语聊房等非常丰富的场景。
-
-比如:
-1. 语音电台:是目前很多社交APP的玩法。主播可以在直播间中给听众讲故事、脱口秀、唱歌,多种形式不胜枚举,观众也可以申请上麦与主播聊天互动,在聊天的基础上,加上了背景伴奏音以及通过消息系统来实现的文字消息功能,在这种模式下,可以提高用户的活跃度。
-
-2. 语音游戏:也是语音聊天室的常见应用场景。支持在狼人杀、剧本杀,王者荣耀及吃鸡等游戏中实现语音开黑,为玩家创建音视频对话实时互动的场景,功能上与语音直播相似,只是在这个频道中,上麦下麦的玩法逻辑有所不同。
-
-------
-
-## Demo
-
-
-### Demo 源码
-
-我们在 Github 已经提供了一套完整的 Demo,在 Demo 的基础上,开发者只需要不到1周的时间,对 UI 和功能做简单修改即可准备测试上线。
-
-- [Android](https://github.com/easemob/liveroom-android)
-
-- [iOS](https://github.com/easemob/liveroom-ios)
-
-
-
-------
-
-## 实现方案
-
-语音聊天室需要满足的主要功能包括:
-- 支持多人参与语音聊天
-- 支持本地混音
-- 多种连麦模式
-
-要实现一个具备以上功能的语音聊天室,大致可以分为三步:**实现语音连麦、支持本地混音,多种连麦模式**的设计,基于设计需求,语音聊天室场景化方案的架构图与实现思路如下:
-![img](/images/privitization/tc_architecture.png)
-
-
-------
-
-### 实现语音连麦
-
-基于开发者反馈,如果要通过自研的方法实现语音连麦,会存在如下问题:
-- 需要自己部署服务器做好高并发处理;
-- 需要对编解码器优化来解决回声、噪声问题;
-- 需要有成熟的技术方案降低延迟、提高音质;
-- 需要兼容各种网络环境下的用户体验等;
-
-总体来讲,就是需要解决设备端网络中的语音连麦**稳定低延时问题与可用性问题**。而以上这些问题,环信已为开发者提供成熟的解决方案,并将相关接口封装于SDK 中,让开发者可以简单快速调用集成。
-
-**场景需求:观众上麦请求和主播通过上麦申请**
-在任意模式下,听众进入房间后可以允许发出上麦申请,房主同意后,听众可上麦,用户角色由听众变为了主播,主播要遵循房间模式来实现自己的功能。
-
-**实现方案:通过会议属性实现**
-在语音聊天室 Demo 中,抢麦、主持、自由麦等模式,及包括各个模式中的上麦者均可通过会议属性实现,当会议属性发生更改时,会广播给房间内所有人。
-
-------
-
-#### 创建语聊房间
-
-首先创建者通过 AppServer 创建并加入语聊房间,IM 聊天室。在房主通过 AppServer 创建并进入房间后,通过音视频提供的会议属性接口修改房间的会议属性,从而自定义一些房间的属性。
-
-我们可以通过一张图,来了解创建语聊房间接口的调用逻辑:
-
-![img](/images/privitization/tc_logic_create.png)
-
-上图中每步涉及到的 iOS/Android 接口如下,其中部分调用到了 AppServer 的接口,开发者需要自己实现 AppServer 功能。
-
-| 步骤 | iOS API | Android API |
-| :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
-| 1. 创建语聊房间 | AppServer API | Android与iOS调用接口相同 |
-| 2. [ 创建conference](rest_manage.html#创建会议) | AppServer API http://a1.easemob.com/{orgname}/{appname}/conferences POST | Android与iOS调用接口相同 |
-| 3. 创建 chatroom | AppServer API http://a1.easemob.com/{orgname}/{appname}/chatrooms POST | Android与iOS调用接口相同 |
-| 4. 创建成功返回conference ID,chatroom ID | AppServer API | Android与iOS调用接口相同 |
-| 5. 加入 conference | [EMClient.sharedClient.conferenceManager joinConferenceWithConfId: password: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a465bd08db130e2d10d9bf0d418871bac) | [EMClient.getInstance().conferenceManager().joinConference(conferenceId, password, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#aa04a85ab5f36f3f4ac14dc23ac18afb8) |
-| 6. 加入 chatroom | [EMClient.sharedClient.roomManager joinChatroom: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chatroom_manager-p.html#a4091826df825b9f1825f2ea97c4fb3e2) | [EMClient.getInstance().chatroomManager().joinChatRoom(chatRoomId, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMChatRoomManager.html#af2d592b0801dbc333c0c60bd551e150d) |
-| 7. 设置会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) |
-
-------
-
-#### 加入语聊房间
-
-当房主创建语聊房间后,其他人通过 AppServer 看到有房间被创建,可以输入房间密码加入到房间中。当加入房间后,就会收到会议属性变更的通知,从而得到会议属性。
-
-我们可以通过一张图,来了解观众进入语聊房间接口的调用逻辑:
-
-![img](/images/privitization/tc_logic_join.png)
-
-上图中每步涉及到的 iOS/Android 接口如下,其中部分调用到了 AppServer 的接口,开发者需要自己实现 AppServer 功能。
-
-| 步骤 | iOS API | Android API |
-| :----------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
-| 1.获取语聊房间列表 | AppServer API | Android与iOS调用接口相同 |
-| 2.加入 conference | [EMClient.sharedClient.conferenceManager joinConferenceWithConfId: password: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a465bd08db130e2d10d9bf0d418871bac) | [EMClient.getInstance().conferenceManager().joinConference(conferenceId, password, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#aa04a85ab5f36f3f4ac14dc23ac18afb8) |
-| 3.加入 chatroom | [EMClient.sharedClient.roomManager joinChatroom: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chatroom_manager-p.html#a4091826df825b9f1825f2ea97c4fb3e2) | [EMClient.getInstance().chatroomManager().joinChatRoom(chatRoomId, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMChatRoomManager.html#af2d592b0801dbc333c0c60bd551e150d) |
-| 4.同步会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) |
-
-------
-
-#### 上麦
-
-已在语聊房间的观众通过 IMServer 发送 message 向房主发起上麦请求,房主同意后,通过 MediaServer 改变会议属性,将观众上麦成为主播,成为主播后就能说话进行推流。房间内其他的人都能收到推流通知并进行订阅。
-
-我们可以通过一张图,来了解观众上麦接口的调用逻辑:
-
-![img](/images/privitization/tc_logic_mic.png)
-
-上图中每步涉及到的 iOS/Android 接口如下:
-
-| 步骤 | iOS API | Android API |
-| :------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
-| 1.请求上麦 | [EMClient.sharedClient.chatManager sendMessage: progress: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chat_manager-p.html#ad139d7ad31d934a721a979955baf1868) | [EMClient.getInstance().chatManager().sendMessage(msg);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMChatManager.html#ad50be7183f088c415b9507bc7ce792e6) |
-| 2.改变角色属性 | [EMClient.sharedClient.conferenceManager changeMemberRoleWithConfId: memberNames: role: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ac613f23e6f13a14f8c40f12f5c1b45f9) | [EMClient.getInstance().conferenceManager().grantRole(targetRole);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a52a1e73bc4b588bc57227c7a57512409) |
-| 3.上麦成为主播 | [EMConferenceManagerDelegate#-roleDidChanged:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ada8c07dac796d492a5165b28b50fb02c) | [EMConferenceListener#onRoleChanged(role);](http://www.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1EMConferenceListener.html#a6df0e567fc534314cee3008c310dfe72) |
-| 4.推流 | [EMClient.sharedClient.conferenceManager publishConference: streamParam: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a4a621606d73a0ea1fab14aa336446a6b) | [EMClient.getInstance().conferenceManager().publish(param,callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#aa087a548e2d8f79ce06f50927decc137) |
-| 5.收到推流通知 | [EMConferenceManagerDelegate#-streamDidUpdate: addStream:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#aaec86cf13eaa8930fa5261c1f3848785) | [EMConferenceListener#onStreamAdded(stream);](http://www.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1EMConferenceListener.html#ad06a034d00575fbf41798b98bebe6089) |
-| 6.订阅 | [EMClient.sharedClient.conferenceManager subscribeConference: streamId: remoteVideoView: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a97e899177d4a7abcc49d8d7ea5152039) | [EMClient.getInstance().conferenceManager().subscribe(stream,surface,callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a405c38df38cbb0e6bf11420ff80540e0) |
-
-------
-
-#### 下麦、销毁房间
-
-当主播在麦上时,如果想要下麦,同样通过 IMServer 向房主发送 message 发起下麦请求,这里无需房主同意,默认直接下麦。若房主主动将主播下麦,则没有之前这步,房主直接通过 MediaServer 改变会议属性,将主播下麦成为观众,主播成为观众后就停止推流。房主调用 AppServer 销毁房间,进而销毁conference、chatroom。
-
-我们可以通过一张图,来了解主播下麦、房主销毁语聊房间接口的调用逻辑:
-
-![img](/images/privitization/tc_logic_down.png)
-
-上图中每步涉及到的 iOS/Android 接口如下,其中部分调用到了 AppServer 的接口,开发者需要自己实现 AppServer 功能
-
-| 步骤 | iOS API | Android API |
-| :--------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
-| 1.请求下麦 | [EMClient.sharedClient.chatManager sendMessage: progress: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chat_manager-p.html#ad139d7ad31d934a721a979955baf1868) | [EMClient.getInstance().chatManager().sendMessage(msg);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMChatManager.html#ad50be7183f088c415b9507bc7ce792e6) |
-| 2.改变角色属性 | [EMClient.sharedClient.conferenceManager changeMemberRoleWithConfId: memberNames: role: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ac613f23e6f13a14f8c40f12f5c1b45f9) | [EMClient.getInstance().conferenceManager().grantRole(targetRole);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a52a1e73bc4b588bc57227c7a57512409) |
-| 3.下麦成为观众 | [EMConferenceManagerDelegate#-roleDidChanged:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ada8c07dac796d492a5165b28b50fb02c) | [EMConferenceListener#onRoleChanged(role);](http://www.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1EMConferenceListener.html#a6df0e567fc534314cee3008c310dfe72) |
-| 4.停止推流 | [EMClient.sharedClient.conferenceManager unpublishConference: streamId: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a679bced8da6fa7b293626c0c3243cfe8) | [EMClient.getInstance().conferenceManager().unpublish(publishId,callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a926c631717ce04a6c2a31401c8e095f7) |
-| 5.销毁语聊房间 | AppServer API | Android与iOS调用接口相同 |
-| 6.销毁conference | AppServer API http://a1-hsb.easemob.com/{orgname}/{appname}/conferences/{confrId} DELETE | Android与iOS调用接口相同 |
-| 7.销毁chatroom | AppServer API http://a1.easemob.com/{orgname}/{appname}/chatrooms/{groupid} DELETE | Android与iOS调用接口相同 |
-
-------
-
-### 本地混音
-
-本地混音是指将几种不同的声音在发送端混在一起。例如常见的K歌场景,就需要将人唱歌的声音和歌曲的背景音乐进行混音处理。所以,在实现了基本的连麦功能后,我们还需要增加背景音乐的混音、播放控制。
-
-在这里,主播可以在自己的客户端上选择要播放的音乐,然后通过 SDK 的 **startAudioMixing** 接口在本地与主播语音混音后播放给连麦听众和普通听众。并且连麦语音与背景音乐播放互不干扰,帮助用户活跃房间内的气氛。在默认情况下,背景音乐是循环播放的。
-
-------
-
-### 多种连麦模式
-
-在语音聊天室 Demo 中,提供了三种模式,自由麦模式、主持模式、抢麦模式(开发者还可以基于此扩展更多模式玩法)。这三种模式就是通过会议属性区分的,当用户进入房间后,就可以知道当前的房间属于哪种模式。
-
-自由麦模式:主播用户可以自由打开和关闭发言,实现起来较为简单就不过多赘述。
-
-这里主要介绍一下,主持模式和抢麦模式的实现逻辑:
-
-- [主持模式](scenario_tc-host)
-
-- [抢麦模式](scenario_tc-robmic)
\ No newline at end of file
diff --git a/docs/private/media/whiteboard_android.md b/docs/private/media/whiteboard_android.md
deleted file mode 100644
index 4ccb4a6e..00000000
--- a/docs/private/media/whiteboard_android.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Android集成互动白板
-
-**注意:**`仅特定的私有化版本SDK支持白板功能.`
-
-使用白板功能首先需要登录环信,登录成功之后才可以去调用api创建白板房间,创建成功之后会直接加入房间,不需要再去调用加入的api。
-
-其他人可以通过房间名称或者通过创建成功之后返回的房间ID去加入白板房间。创建或者加入成功之后会返回对应白板房间的URL,在webview中去加载显示
-
-## 创建白板房间
-
-```
-/**
- * \~chinese
- * 创建白板房间
- * @param user 用户名
- * @param token 用户的token
- * @param roomName 房间名
- * @param password 房间的密码
- * @param isInteractive 是否允许互动
- * @param callBack 请求完成的回调
- */
-public void createWhiteboardRoom(final String user, final String token, final String roomName,
- final String password, final boolean isInteractive,
- final EMValueCallBack callBack) {}
-```
-
-## 通过房间名称加入白板房间
-
-```
-/**
- * \~chinese
- * 通过白板名称加入房间
- * @param user 用户名
- * @param token 用户的token
- * @param roomName 房间名
- * @param password 房间的密码
- * @param callBack 请求完成的回调
- */
- public void joinWhiteboardRoomWithName(final String user, final String token, final String roomName, final String password, final EMValueCallBack callBack)
-```
-
-## 通过房间ID加入白板房间
-
-```
-/**
- * \~chinese
- * 通过白板id加入房间
- * @param user 用户名
- * @param token 用户的token
- * @param roomId 房间名
- * @param password 房间的密码
- * @param callBack 请求完成的回调
- */
- public void joinWhiteboardRoomWithId(final String user, final String token, final String roomId, final String password, final EMValueCallBack callBack)
-```
-
-## 通过房间ID修改白板互动权限
-
-```
-* \~chinese
- * 通过白板Id 修改白板操作权限
- * @param user 创建者的userId
- * @param roomId 房间Id
- * @param token 用户的token
- * @param isInteractive 是否开启交互权限
- * @param aServentIds 需要互动控制的成员
- * @param isAllInTeract 是否允许所有人交互
- * @param callBack 请求完成的回调
- *
- */
- public void updateWhiteboardRoomWithRoomId(final String user,final String roomId, final String token, final boolean isInteractive,final List aServentIds,final boolean isAllInTeract, EMCallBack callBack){}
-```
-
-## 销毁白板房间
-
-```
-/**
- * \~chinese
- * 销毁白板房间
- * @param user 用户名
- * @param token 用户的token
- * @param roomId 房间id
- * @param callBack 请求完成的回调
- */
- public void destroyWhiteboardRoom(final String user, final String token, final String roomId, EMCallBack callBack)
-```
\ No newline at end of file
diff --git a/docs/private/media/whiteboard_introduction.md b/docs/private/media/whiteboard_introduction.md
deleted file mode 100644
index adbe6bb7..00000000
--- a/docs/private/media/whiteboard_introduction.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# 互动白板简介
-
-### 产品介绍
-
-白板(Easemob-WhiteBoard)服务端基于socket.io,页面基于svg.js开发,所以兼容性参考上述两项即可。
-
-SDK提供了创建白板、加入白板、销毁白板三个API。白板角色默认分为创建者/成员,都可以在实时共享的画布上运用提供工具进行元素的绘制、拖动等操作。创建者会增加白板页面的相关操作如:增加/删除白板页面、查看页面缩略图、上传文档(上传文档会根据文档页数在当前页面后面作为白板页插入);同时创建者有撤销/恢复、清空当前画布并更改房间成员的互动权限的操作。一个白板中支持多个白板页面,支持通过上传文档增加白板页面并作为白板页的背景。文档类型包括:PDF文档、Word、PPT文档进行实时展示和讲解。
-
-创建白板后会返回一个白板地址链接,用户通过直接使用页面、ifram 或者 webview等方式集成。白板功能是实时音视频通话场景的互动补充,可以满足广泛的业务场景,例如:教育板书、会议内容展示、笔记记录。
-
-白板功能特性:
-
-- 多客户端支持: 桌面端(基于electron)、Web端;
-- 多人实时互动:可支持多人同时在线互动;
-- 超低时延同步:白板操作低时延同步展示;
-- 上传文件支持类型:图片、PDF文档、Word、PPT;
-
-### SDK API
-
-#### 1.创建白板房间
-
-```
-a. whiteBoard.create()
-b.whiteBoard.join()
-```
-
-注:.create()只是单独的创建并加入房间; .join()存在当前的房间名称就加入房间,不存在当前房间名就创建房间并加入;
-
-#### 2.加入白板房间
-
-```
-a.whiteBoard.join()
-当前房间名已存在,则加入该房间
-b.whiteBoard.joinByRoomName()
-通过房间名加入
-c.whiteBoard.joinByRoomId()
-通过房间id加入
-```
-
-#### 3.房间权限更改
-
-```
-whiteBoard.oprateAuthority()
-控制房间内成员是否可以进行白板操作
-```
-
-#### 4.删除白板
-
-```
-whiteBoard.destroy()
-```
-
-## Demo
-
-### Demo源码
-
-我们在 Github 已经提供了一套完整的 Demo,大家可以在 Github 地上获取。
-
-- [Android](https://github.com/easemob/whiteboard_demo_android)
-
-- [iOS](https://github.com/easemob/whiteboard_demo_ios)
-
-- [web](https://github.com/easemob/whiteboard_demo_web)
-
-在 Demo 的基础上,开发者只需要不到1周的时间,对 UI 和功能做简单修改即可准备测试上线。
-
-### 产品功能
-
-白板操作有3类,分别为:页面类操作、元素类操作、文档类操作;
-表1.白板支持功能
-
-![img](/images/privitization/whiteboard_function.png)
-
-图2.白板操作界面
-
-![img](/images/privitization/whiteboard_view.png)
-
diff --git a/docs/private/media/whiteboard_ios.md b/docs/private/media/whiteboard_ios.md
deleted file mode 100644
index 4e6c2743..00000000
--- a/docs/private/media/whiteboard_ios.md
+++ /dev/null
@@ -1,127 +0,0 @@
-# iOS集成互动白板
-
-**注意:**`仅特定的私有化版本SDK支持白板功能.`
-
-使用白板功能首先需要登录环信,登录成功之后才可以去调用api创建白板房间,创建成功之后会直接加入房间,不需要再去调用加入的api。
-
-其他人可以通过房间名称或者通过创建成功之后返回的房间ID去加入白板房间。创建或者加入成功之后会返回对应白板房间的URL,在webview中去加载显示
-
-## 创建白板房间
-
-```
-/**
- * \~chinese
- * 创建白板房间
- * @param aUsername 用户名
- * @param aToken 用户的token
- * @param aRoomName 房间名
- * @param aPassword 房间的密码
- * @param bInteract 是否允许互动
- * @param aCompletionBlock 请求完成的回调
- *
- * \~english
- * create room for whiteboard
- * @param aUsername username
- * @param aToken user's token
- * @param aRoomName room name for whiteboard
- * @param aPassword password for room
- * @param bInteract weather allow members interact
- * @param aCompletionBlock callback
- */
-- (void)createWhiteboardRoomWithUsername:(NSString *)aUsername
- userToken:(NSString *)aToken
- roomName:(NSString *)aRoomName
- roomPassword:(NSString *)aPassword
- interact:(BOOL)aInteract
- completion:(void(^)(EMWhiteboard *aWhiteboard, EMError *aError))aCompletionBlock;
-```
-
-## 通过房间名称加入白板房间
-
-```
-/**
- * \~chinese
- * 通过白板名称加入房间
- * @param aRoomName 房间名
- * @param aUsername 用户名
- * @param aToken 用户的token
- * @param aPassword 房间的密码
- * @param aCompletionBlock 请求完成的回调
- */
-- (void)joinWhiteboardRoomWithName:(NSString *)aRoomName
- username:(NSString *)aUsername
- userToken:(NSString *)aToken
- roomPassword:(NSString *)aPassword
- completion:(void(^)(EMWhiteboard *aWhiteboard, EMError *aError))aCompletionBlock;
-```
-
-## 通过房间ID加入白板房间
-
-```
-/**
- * \~chinese
- * 通过白板id加入房间
- * @param aRoomId 房间id
- * @param aUsername 用户名
- * @param aToken 用户的token
- * @param aPassword 房间的密码
- * @param aCompletionBlock 请求完成的回调
- */
-- (void)joinWhiteboardRoomWithId:(NSString *)aRoomId
- username:(NSString *)aUsername
- userToken:(NSString *)aToken
- roomPassword:(NSString *)aPassword
- completion:(void(^)(EMWhiteboard *aWhiteboard, EMError *aError))aCompletionBlock;
-```
-
-## 修改成员互动权限
-
-白板创建者可以修改其他成员的互动权限,禁止互动的成员将无法操作白板。修改互动权限的api如下
-
-```
-/**
- * \~chinese
- * 修改白板的用户互动权限
- * @param aRoomId 房间Id
- * @param aToken 用户的token
- * @param aPassword 房间的密码
- * @param aInteract 是否允许互动,YES为允许互动,NO为不允许互动
- * @param aAll 是否操作所有成员,YES时操作所有人,aServentIds不起作用
- * @param aServentIds 操作的成员数组,aAll为NO时有效
- * @param aCompletionBlock 请求完成的回调
- *
- * \~english
- * update whiteboard room interact
- * @param aRoomId room Id
- * @param aUsername username
- * @param aToken user's token
- * @param aInteract weather allow members interact
- * @param aAll weather update all members`s interact right.if YES,aServentIds is invalid.
- * @param aServentIds array of members`s id.invalid when aAll is NO
- * @param aCompletionBlock callback
- */
-- (void)updateWhiteboardRoomWithRoomId:(NSString *)aRoomId
- username:(NSString *)aUsername
- userToken:(NSString *)aToken
- intract:(BOOL)aInteract
- allUsers:(BOOL)aAll
- serventIds:(NSArray*)aServentIds
- completion:(void(^)(EMError *aError))aCompletionBlock;
-```
-
-## 销毁白板房间
-
-```
-/**
- * \~chinese
- * 销毁白板房间
- * @param aUsername 用户名
- * @param aToken 用户的token
- * @param aRoomId 房间id
- * @param aCompletionBlock 请求完成的回调
- */
-- (void)destroyWhiteboardRoomWithUsername:(NSString *)aUsername
- userToken:(NSString *)aToken
- roomId:(NSString *)aRoomId
- completion:(void(^)(EMError *aError))aCompletionBlock;
-```
\ No newline at end of file
diff --git a/docs/private/media/whiteboard_pcdesktop.md b/docs/private/media/whiteboard_pcdesktop.md
deleted file mode 100644
index cf82da55..00000000
--- a/docs/private/media/whiteboard_pcdesktop.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# PC桌面集成互动白板
-
-------
-
-参考 [Web集成互动白板](whiteboard_web.html)
\ No newline at end of file
diff --git a/docs/private/media/whiteboard_vxmini.md b/docs/private/media/whiteboard_vxmini.md
deleted file mode 100644
index c94a4c17..00000000
--- a/docs/private/media/whiteboard_vxmini.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# 微信小程序集成互动白板
-
-------
-
-参考 [Web集成互动白板](whiteboard_web.html)
\ No newline at end of file
diff --git a/docs/private/media/whiteboard_web.md b/docs/private/media/whiteboard_web.md
deleted file mode 100644
index 78becca2..00000000
--- a/docs/private/media/whiteboard_web.md
+++ /dev/null
@@ -1,179 +0,0 @@
-# Web集成互动白板
-
-## 下载
-
-```
-npm install easemob-whiteboards
-```
-
-## 引入sdk
-
-```
-import whiteboards from 'easemob-whiteboards'
-```
-
-## 初始化
-
-```
-var WDSdk = new whiteboards({
- appKey: "yourAppKey"
-});
-```
-
-## APIs
-
-有两种方式创建白板:
-
-### 1. 通过房间名加入,没有房间创建房间,有房间加入房间
-
-```
-/**
- * @param {string} roomName 房间名
- * @param {string} password 房间密码
- * @param {string} userName im用户名
- * @param {number} level 权限等级 ,1-3禁止互动,4-8允许互动。默认允许互动
- * @param {number} layout 工具栏位置 ,默认0;0-底部,1-右侧,2-顶部
- * @param {string} ratio 白板画布宽高比。建议"4:3"、"2:1"
- * @param {string} token im登录token
- * @param {function} suc 成功的回调
- * @param {function} error 失败的回调
- */
-WDSdk.join({
- roomName: 'roomName',
- password: 'password',
- userName: 'userName',
- level: 4,
- layout:0,
- ratio:"2:1",
- token: 'token',
- suc: (res) => {
- res.whiteBoardUrl; 为白板房间地址
- },
- error: () => {},
-})
-```
-
-### 2. 通过单独api去创建、加入
-
-a. 创建白板 (WDSdk.create)
-
-```
-/**
- * @param {string} roomName 房间名
- * @param {string} password 房间密码
- * @param {string} userName im用户名
- * @param {number} level 权限等级 ,1-3禁止互动,4-8允许互动。默认允许互动
- * @param {number} layout 工具栏位置 ,默认0;0-底部,1-右侧,2-顶部
- * @param {string} ratio 白板画布宽高比。建议"4:3"、"2:1"
- * @param {string} token im登录token
- * @param {function} suc 成功的回调
- * @param {function} error 失败的回调
- */
-WDSdk.create({
- userName: 'userName',
- roomName: 'roomName',
- level: 4,
- layout:0,
- ratio:"2:1",
- password: 'password',
- token: 'token',
- suc: (res) => {
- window.location = res.whiteBoardUrl;
- },
- error: () => {}
-});
-```
-
-b. 加入白板,可支持两种方式加入白板:
-- joinByRoomId :通过已经创建的房间ID加入;
-- joinByRoomName :通过已经创建的房间名称加入;
-
-```
-/**
- * 1 通过房间ID加入
- * @param {string} roomId 房间Id
- * @param {string} password 房间密码
- * @param {string} userName im用户名
- * @param {string} token im登录token
- * @param {function} suc 成功的回调
- * @param {function} error 失败的回调
- */
-WDSdk.joinByRoomId({
- userName: userName,
- roomId: roomId,
- token: "token",
- suc: function(res){
- window.location = res.whiteBoardUrl;
- },
- error: function(err){
- console.log("err", err);
- }
-});
-
-/**
- * 2 通过房间名加入
- * @param {string} roomName 房间名
- * @param {string} password 房间密码
- * @param {string} userName im用户名
- * @param {string} token im登录token
- * @param {function} suc 成功的回调
- * @param {function} error 失败的回调
- */
-WDSdk.joinByRoomName({
- userName: userName,
- roomName: roomName,
- token: "token",
- suc: function(res){
- window.location = res.whiteBoardUrl; //同joinByRoomId返回
- },
- error: function(err){
- console.log("err", err);
- }
-});
-```
-
-### 3. 白板互动权限
-
-```
-/**
- * @param {string} userName im用户名
- * @param {string} roomId 房间id
- * @param {number} leval 4-8允许互动/1-3禁止互动
- * @param {arr} members 操作的权限用户名数组,当isAll为true,此参数不生效,所以设置此参数时需设置isAll=false
- * @param {bloon} isAll ture时操作对象为房间所有成员,默认为true
- * @param {string} token im登录token
- * @param {function} suc 成功的回调
- * @param {function} error 失败的回调
- */
-WDSdk.oprateAuthority({
- userName: "username",
- roomId: "roomId",
- leval: 4,
- members:[],
- isAll: true,
- token: "token",
- suc: function(res){},
- err: function(err){}
-})
-```
-
-### 4. 销毁白板
-
-```
-/**
- * @param {string} roomId 房间id
- * @param {string} token im登录token
- * @param {function} suc 成功的回调
- * @param {function} error 失败的回调
- */
-WDSdk.destroy({
- roomId: roomId,
- token: "token",
- suc: function(res){
- console.log(res);
- },
- error: function(err){
- console.log("err", err);
- }
-});
-```
\ No newline at end of file
diff --git a/docs/product/GDPR.md b/docs/product/GDPR.md
deleted file mode 100644
index 73143d7f..00000000
--- a/docs/product/GDPR.md
+++ /dev/null
@@ -1,93 +0,0 @@
-# GDPR 安全合规
-
-
-
-环信 IM 提供一系列数据删除和导出 API,保护数据安全和用户隐私 ,确保符合 GDPR(通用数据保护条例)的安全合规要求。
-
-## 数据删除
-
-
-为保护用户隐私,环信提供数据删除 REST API 供开发者对环信即时通讯服务器存储的用户相关数据进行删除,例如:删除用户账号、删除用户属性、解散群组和聊天室。
-
-### 认证方式
-
-环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 `Authorization` 字段:
-
-`Authorization:Bearer YourAppToken`
-
-为提高项目的安全性,环信使用 Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 仅支持使用 app token 的鉴权方式,详见[使用 App Token 鉴权](easemob_app_token.html)。
-
-### REST API 介绍
-
-#### 删除用户账号
-
-[删除 App 下指定的用户](/document/server-side/account_system.html#删除单个用户),删除的用户数据主要包括用户的会话列表、用户属性和好友关系。
-
-#### 删除用户属性
-
-[删除 App 下指定用户的用户属性](/document/server-side/userprofile.html#删除用户属性)。
-
-#### 解散群组
-
-[删除 App 下指定群 ID 的群组](/document/server-side/group_member.html#解散群组)。
-
-#### 解散聊天室
-
-[删除 App 下指定 ID 的聊天室](/document/server-side/chatroom_manage.html#解散聊天室)。
-
-## 数据导出
-
-### 功能描述
-
-为了保证用户管理其隐私数据的权利,环信提供了数据导出 REST API,可供开发者导出环信即时通讯服务器存储的相关数据,包括用户数据、群组数据、聊天室数据、历史消息和附件。
-
-### REST API 概览
-
-本文介绍数据导出 API 的列表。
-
-#### 导出用户数据
-
-| REST API | 描述 |
-| :----------------------------------------------------------- | :---------------------------------- |
-| [获取单个用户信息](/document/server-side/account_system.html#获取单个用户的详情)
[批量获取用户信息](/document/server-side/account_system.html#批量获取用户详情) | 获取 App 下指定用户 ID 的用户信息。 |
-| [获取用户属性](/document/server-side/userprofile.html#获取用户属性) | 获取 App 下指定用户 ID 的用户属性。 |
-
-#### 导出群组数据
-
-| REST API | 描述 |
-| :----------------------------------------------------------- | :---------------------------------------- |
-| [群组详情](/document/server-side/group_manage.html#获取群组详情) | 获取 App 下指定群组 ID 的群组详情。 |
-| [App 下所有的群组](/document/server-side/group_manage.html#获取-app-中所有的群组-可分页) | 获取 App 下包含所有群组的列表。 |
-| [群组管理员列表](/document/server-side/group_member.html#获取群管理员列表) | 获取 App 下指定群组 ID 的群组管理员列表。 |
-| [群组成员列表](/document/server-side/group_member.html#分页获取群组成员) | 获取 App下指定群组 ID 的群组成员列表。 |
-| [群组公告](/document/server-side/group_file.html#获取群组公告) | 获取 App 下指定群组 ID 的群组公告。 |
-| [群组共享文件](/document/server-side/group_file.html#获取群组共享文件) | 获取 App 下指定群组 ID 的群组共享文件。 |
-| [群组黑名单列表](/document/server-side/group_member.html#查询群组黑名单) | 获取 App 下指定群组 ID 的群组黑名单列表。 |
-| [群组禁言列表](/document/server-side/group_member.html#获取禁言列表) | 获取 App 下指定群组 ID 的群组禁言列表。 |
-
-#### 导出聊天室数据
-
-| REST API | 描述 |
-| :----------------------------------------------------------- | :-------------------------------------------- |
-| [获取聊天室详情](/document/server-side/chatroom.html#查询聊天室详情) | 获取 App 下指定聊天室 ID 的聊天室详情。 |
-| [App 下所有的聊天室](/document/server-side/chatroom.html#获取-app-中所有的聊天室) | 获取 App 下所有的聊天室列表。 |
-| [用户加入的聊天室](/document/server-side/chatroom.html#获取用户加入的聊天室) | 获取 App 下指定用户 ID 加入的聊天室列表。 |
-| [聊天室管理员列表](/document/server-side/chatroom.html#获取聊天室管理员列表) | 获取 App 下指定聊天室 ID 的聊天室管理员列表。 |
-| [聊天室成员列表](/document/server-side/chatroom.html#分页获取聊天室成员) | 获取 App 下指定聊天室 ID 的聊天室禁言列表。 |
-| [聊天室禁言列表](/document/server-side/chatroom.html#获取禁言列表) | 获取 App 下指定聊天室 ID 的聊天室禁言列表。 |
-
-#### 获取历史消息记录
-
-此接口一次只能获取一个小时的历史消息记录。
-
-| REST API | 描述 |
-| :----------------------------------------------------------- | :------------------------------------ |
-| [获取历史消息记录](/document/server-side/message_historical.html) | 获取 App 下指定时间段的历史消息文件。 |
-
-#### 导出附件
-
-附件包含图片、语音、视频、文件。
-
-| REST API | 描述 |
-| :----------------------------------------------------------- | :---------------------------- |
-| [下载附件](/document/server-side/message_download.html#下载文件) | 下载 App 下指定 UUID 的附件。 |
\ No newline at end of file
diff --git a/docs/product/README.md b/docs/product/README.md
deleted file mode 100644
index e13416f9..00000000
--- a/docs/product/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
----
-title: 产品简介
----
diff --git a/docs/product/aigc/aigc_rest_api.md b/docs/product/aigc/aigc_rest_api.md
deleted file mode 100644
index f78c9851..00000000
--- a/docs/product/aigc/aigc_rest_api.md
+++ /dev/null
@@ -1,199 +0,0 @@
-# AI 智能
-
-环信即时通讯云提供 REST API 获取 app 下的机器人列表。**如果需要该功能相关的其他 REST API,请联系环信商务。**
-
-## 前提条件
-
-要调用环信即时通讯 RESTful API,请确保满足以下要求:
-
-- 已在环信即时通讯云控制台 [开通配置环信即时通讯 IM 服务](/product/enable_and_configure_IM.html)。
-- 已从服务端获取 app token,详见 [使用 App Token 鉴权](/product/easemob_app_token.html)。
-- 了解环信 IM API 的调用频率限制,详见 [接口频率限制](/product/limitationapi.html)。
-
-## 认证方式
-
-环信即时通讯 REST API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 `Authorization` 字段:
-
-`Authorization: Bearer YourAppToken`
-
-为提高项目的安全性,环信使用 Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。本文介绍的即时通讯所有 REST API 均需使用 App Token 的鉴权方式,详见 [使用 App Token 鉴权](/product/easemob_app_token.html)。
-
-## 获取 app 下的机器人列表
-
-你可以调用该 API 获取你的 app 下的机器人列表。
-
-**调用频率上限**:100 次/秒/App Key
-
-### HTTP 请求
-
-```http
-GET https://{host}/{org_name}/{app_name}/robot/rule?&page={page}&size={size}
-```
-
-#### 路径参数
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :--------- | :----- | :------- | :------------------------- |
-| `host` | String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。详见 [获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 |
-| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。详见 [获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 |
-| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。详见 [获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 |
-
-#### 查询参数
-
-| 字段 | 类型 | 是否必选 | 备注 |
-| :-------------- | :----- | :------- | :--------------------------------------- |
-| `page` | Int | 是 | 当前页码,默认值为 `0`。|
-| `size` | Int | 是 | 每页返回的机器人数量,取值范围为 [1,20],默认值为 `10`。|
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :-------------- | :----- | :------- | :--------------------------------------- |
-| `Authorization` | String | 是 | App 管理员的鉴权 token,格式为 `Bearer YourAppToken`,其中 `Bearer` 为固定字符,后面为英文空格和获取到的 app token。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中的字段描述如下:
-
-| 字段 | 类型 | 描述 |
-| :------------------ | :----- | :-------------------------------------- |
-| `status` | String | 是否成功获取 app 下的机器人列表。`OK` 表示成功获取。 |
-| `entities` | JSONArray | app 下的机器人详情。 |
-| - `id` | String | 机器人 ID。 |
-| - `name` | String | 机器人名称。 |
-| - `appkey` | String | 应用的唯一标识,由 `Orgname` 和 `Appname` 组成,生成后不允许修改。在[环信即时通讯云控制台](https://console.easemob.com/user/login)的 **应用详情** 页面查看。 |
-| - `robotId` | String | robot ID。 |
-| - `robotAppId` | String | robot ID 对应的 robot app ID。 |
-| - `msgType` | String | 消息类型,目前固定值为 `txt`,即文本消息。 |
-| - `targetType` | String | 会话类型,目前固定值为 `chat`,即单聊。 |
-| - `targetId` | List | 机器人对应的 IM 的用户 ID。目前只有一个用户 ID。 |
-| - `providerType` | String | AI 大模型厂商,目前固定值为 `MINIMAX`。 |
-| - `providerId` | String | 机器人对应的厂商 ID。 |
-| - `timeout` | Int | 超时时间,目前未启用。 |
-| - `status` | String | 机器人的状态,`ACTIVE` 为启用状态,默认是启用。 |
-| - `createDateTime` | DATETIME | 开通使用 MiniMax AI 聊天服务的时间。 |
-| - `updateDateTime` | DATETIME | 更新 MiniMax AI 聊天服务开通状态的时间。 |
-| - `providerTextApi` | String | 厂商支持的 AI 接口,默认使用 `chatcompletion_pro`,当前不支持可选。 |
-| - `providerModel` | String | 厂商支持的 AI 模型类别。|
-| - `providerAttribute` | JSONObject | 机器人的一些属性。 |
-| - `historyNum` | Int | 传递给机器人的历史消息数,固定为 `10`。开发者忽略该字段。 |
-| - `avatar` | String | 机器人头像图片链接。 |
-| - `restMsgLimit` | Int | 发送的 REST 消息大小值。该字段为内部使用,开发者可忽略。 |
-| - `providerPayload` | JSONObject | 调用厂商接口时的一些参数。 |
-| - `top_p` | Int | 控制生成环节采样范围,参数值越小,生成结果越稳定。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 |
-| - `tokens_to_generate` | Int | 机器人回复的最大生成 token 数。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 |
-| - `temperature` | Int | 控制生成环境采样随机性,参数值越小,生成结果越稳定。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 |
-| - `providerContent` | String | 具体机器人的设定,长度影响接口性能。 |
-| - `textType` | String | 固定值,该字段为内部使用,开发者可忽略。 |
-| `size` | Int | 当前页面返回的机器人数量。 |
-| `page` | Int | 当前页码。 |
-| `elements` | Int | 当前页面返回的机器人数量。 |
-| `totalPages` | Int | 总页数。 |
-| `totalElements` | Int | App 下的机器人总数。 |
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#错误码) 了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-# 将 替换为你在服务端生成的 App Token
-curl --location 'http://XXXX/XXXX/XXXX/robot/rule?page=0&size=10'
--H 'Authorization: Bearer '
-```
-
-#### 响应示例
-
-```json
-{
- "status": "OK",
- "entities": [
- {
- "id": "1eUOZ3RFpJA2BFSsaB8n5EFrETh",
- "name": "Kyler_Robel",
- "appkey": "easemob-demo#test",
- "robotId": "f5f07c60ce95ca4f496870665d0e868d",
- "robotAppId": "1eRg1UCOhrvkMw1q47G7tToUduJ",
- "msgType": "TEXT",
- "targetType": "CHAT",
- "targetId": [
- "some_user_id371-916-6147"
- ],
- "providerType": "MINIMAX",
- "providerId": "1eUOZ28DChC1LUc5a5YSvSoPPnq",
- "timeout": 3000,
- "status": "ACTIVE",
- "createDateTime": "2024-05-29T09:30:56.427220Z",
- "updateDateTime": "2024-05-29T09:37:40.969794Z",
- "providerTextApi": "chatcompletion_pro",
- "providerModel": "abab6.5-chat",
- "providerAttribute": {
- "historyNum": 10,
- "avatar": "http://placeimg.com/640/480",
- "restMsgLimit": 1024
- },
- "providerPayload": {
- "top_p": 0.9,
- "tokens_to_generate": 2048,
- "temperature": 0.1
- },
- "providerContent": "putMessage我是助理222",
- "textType": "DEFAULT"
- },
- {
- "id": "1eUbgljnq7yhHqgQ7cjKw5mOUxC",
- "name": "Dessie81",
- "appkey": "easemob-demo#test",
- "robotId": "f5f07c60ce95ca4f496870665d0e868d",
- "robotAppId": "1eRg1UCOhrvkMw1q47G7tToUduJ",
- "msgType": "TEXT",
- "targetType": "CHAT",
- "targetId": [
- "some_user_id379-312-1146"
- ],
- "providerType": "MINIMAX",
- "providerId": "1eUbgjWOKkzbaRCysbLozPy4E4h",
- "timeout": 3000,
- "status": "ACTIVE",
- "createDateTime": "2024-05-29T11:18:51.454156Z",
- "updateDateTime": "2024-05-29T11:46:19.333387Z",
- "providerTextApi": "chatcompletion_pro",
- "providerModel": "abab6.5-chat",
- "providerAttribute": {
- "historyNum": 10,
- "avatar": "http://placeimg.com/640/480",
- "restMsgLimit": 1024
- },
- "providerPayload": {
- "top_p": 0.9,
- "tokens_to_generate": 2048,
- "temperature": 0.1
- },
- "providerContent": "putMessage我是助理222",
- "textType": "DEFAULT"
- }
- ],
- "size": 10,
- "page": 0,
- "elements": 2,
- "totalPages": 1,
- "totalElements": 2
-}
-```
-
-### 错误码
-
-| HTTP 状态码 | 错误类型 | 错误提示 | 可能原因 | 处理建议 |
-| :----------- | :--- | :------------- | :----------- | :----------- |
-| 401 | unauthorized | Unable to authenticate (OAuth) | token 不合法,可能过期或 token 错误。 | 使用新的 token 访问。 |
-| 500 | Internal Server Error | Internal Server Error | 服务内部错误。 | 检查请求参数是否合理。|
-| 400 | Bad Request | Request param error | 请求参数错误。 | 检查请求参数是否合理。|
-
-关于其他错误,你可以参考 [响应状态码](/document/server-side/overview.html) 了解可能的原因。
-
-
-
-
diff --git a/docs/product/aigc/aigc_run_through_demo_client.md b/docs/product/aigc/aigc_run_through_demo_client.md
deleted file mode 100644
index 6aaed24e..00000000
--- a/docs/product/aigc/aigc_run_through_demo_client.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# 客户端跑通示例项目
-
-通过配置服务端和客户端,利用环信即时通信 IM 服务器回调功能,在 IM 中引入 AI 服务(以 MiniMax 中文大语言模型为例),创建机器人账号,从而跑通示例项目。
-
-本文介绍通过跑通示例项目如何配置客户端,跑通示例项目。
-
-## 环境准备
-
-1. 开发环境
-
-- 工具:Android Studio
-- 系统:MacOS
-- 代码:Java
-
-2. 运行环境
-
-系统: Android 6.0 +
-
-## 下载代码
-
-通过 [GitHub 链接下载客户端代码](https://github.com/easemob/Easemob-AIGCService-Example/tree/dev/AIGCService-AndroidClient)。
-
-## 参数配置
-
-使用 `AndroidStudio` 运行项目,打开 `com.imchat.chanttyai/base/Constants.java` 文件,只需将 `APP_KEY` 及 `HTTP_HOST` 参数分别修改为环信 App Key 和服务端部署域名或 IP 地址。
-
-![img](/images/aigc/parameter_configure.png)
-
-## 运行示例项目
-
-跑通示例项目,跑通后的界面以及聊天界面如下图所示:
-
-- 启动页面和机器人列表用户界面如下图所示:
-
-
-
-
-- 聊天页面如下图所示:
-
-
-
\ No newline at end of file
diff --git a/docs/product/aigc/aigc_run_through_demo_server.md b/docs/product/aigc/aigc_run_through_demo_server.md
deleted file mode 100644
index f664065b..00000000
--- a/docs/product/aigc/aigc_run_through_demo_server.md
+++ /dev/null
@@ -1,290 +0,0 @@
-# 服务端配置
-
-通过配置服务端和客户端,利用环信即时通信 IM 服务器回调功能,在 IM 中引入 AI 服务(以 MiniMax 中文大语言模型为例),创建机器人账号,从而跑通示例项目。本文介绍通过跑通示例项目如何配置服务端。
-
-此外,利用 AI 聊天功能,你可以设置问候语,让机器人用户每天定时主动向聊天用户发送问候语,实现详情请参见 [FAQ](#faq)。
-
-若要体验 Demo,你可以扫描以下二维码:
-
-![img](/images/aigc/ai_solution1_demo.png)
-
-## 环境准备
-
-1. 部署要求:Windows 或者 Linux 服务器
-
-2. 环境要求
-
-- JDK 1.8+
-- Redis 3.0.504
-- Redis 绑定地址更改为 127.0.0.1
-- MySQL 8.0.30
-
-## 代码下载
-
-当部署环境准备好后,通过 [GitHub 链接下载服务端代码](https://github.com/easemob/Demo-ChattyAI/tree/dev/chattyai_server)。
-
-## 信息配置
-
-服务端配置信息全部集中在以下文件中,主要配置包含三个部分:环信即时通讯 IM、miniMax 和 redis,配置内容如下:
-
-```
-src/main/resources/application.yml
-```
-
-### 环信即时通讯 IM 相关配置
-
-#### 1. 创建应用
-
-登录[环信即时通讯云控制台](https://console.easemob.com/user/login),点击**添加应用**,填写应用相关信息。
-
-![img](/images/aigc/app_create.png)
-
-#### 2. 获取 app 信息
-
-选中创建的应用,点击**管理**,进入**应用详情**页面,获取 **App Key**、**ClientID** 及**ClientSecret**。
-
-```yaml
-logging:
- level:
- com.easemob.im.http: debug #启动之后可打印的日志级别
-server:
- port: 80 #修改启动端口,只能为数字(请确保该端口没有被占用)
-easemob:
- appkey: {appkey} # 创建应用获取到的 App Key,可通过环信即时通讯云控制台的 “应用详情” 页面上的 “APPKEY” 字段获取。
- clientId:{clientId} # App 的 client_id,可通过环信即时通讯云控制台的 “应用详情” 页面上的 “Client ID” 字段获取。
- clientSecret:{clientSecret} # App 的 client_secret,可通过环信即时通讯云控制台的 “应用详情” 页面上的 “ClientSecret” 字段获取。
-```
-
-![img](/images/aigc/app_detail.png)
-
-#### 3. 关闭好友关系检查
-
-设置**用户注册模式**为**开放注册**,关闭好友关系检查。
-
-![img](/images/aigc/user_register_contact.png)
-
-#### 4. 创建机器人账号
-
-选择**应用概览** > **用户认证** 创建机器人账号,进行单聊或群组聊天。
-
-示例项目中创建了 3 个智能体,因此建议设置 3 个机器人账号与智能体一 一绑定,即 `com.easemob.chattyai.chat.util.BotSettingUtil` 中的 `botBean0.setAccount`(机器人用户 ID)与 `botBean0.setName`(智能体名称)为一 一对应关系,见下方代码。
-
-下图红框中的用户 ID(`bot1222700215765565440`、`bot1223027765968633856` 和 `bot1223027786982096896`)为示例项目中的与智能体绑定的机器人账号,若使用其他用户 ID,则需同步修改 `BotSettingUtil` 的 `botBean0.setAccount` 中的值,否则无法跑通示例项目。
-
-![img](/images/aigc/robot_account_create.png)
-
-```java
-static{
-
-BotBean botBean0 = new BotBean();
-botBean0.setAccount("boy0");
-botBean0.setName("智能体名称");
-botBean0.setGender(0);
-botBean0.setContent("智能体介绍" +
-");
-botBean0.setDesc("智能体相关信息,例如特征等。");
-bots.put("boy0",botBean0);
-
-}
-```
-
-#### 5. 配置发送前回调规则
-
-若使用消息发送前回调功能,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通该功能,详见[回调配置相关文档](/product/enable_and_configure_IM.html#配置消息回调)。该功能为增值服务,费用详见[功能费用文档](/product/pricing.html#增值服务费用)。
-
-回调功能开通后,选择**即时通讯** > **功能配置** > **消息回调**,点击**添加回调地址**,配置发送前回调规则。其中,**会话类型**选择**单聊**和**群聊**,**消息类型**选择**文本**,**启用状态**选择**启用**,**回调地址**需确保设置为环信即时通讯 IM 可以通过外网访问到回调地址,格式为 `http(s)://ip:端口/chatty/callback.json`。其他参数的含义详见[配置回调规则相关文档](/product/enable_and_configure_IM.html#配置回调规则)。
-
-![img](/images/aigc/callback_address.png)
-
-### 大语言模型(LLM)信息配置
-
-本代码示例以 MiniMax 为例 [MiniMax 开放平台快速开始](https://platform.minimaxi.com/document/Fast%20access?key=66701cf51d57f38758d581b2),若使用其他大语言模型,可按其他语言模型配置要求进行调整。
-
-```yaml
-miniMax:
- groupId:{groupId} # MiniMax 基础信息的 groupID。选择 “MiniMax账号管理” > “账户信息”页面,获取 “groupID” 字段。
- appkey: {appkey} # MiniMax 的接口密钥。当需要复制 API 密钥时,可以重新创建一个以完成复制操作。
- url: https://api.minimax.chat/v1/text/chatcompletion_pro?GroupId=
-```
-
-### MySQL 配置
-
-```yaml
-spring:
- datasource:
- type: com.alibaba.druid.pool.DruidDataSource
- driverClassName: com.mysql.cj.jdbc.Driver
- druid:
- url: xxxx
- username: xxxx
- password: xxxx
- initial-size: 10
- max-active: 100
- min-idle: 10
- max-wait: 60000
- pool-prepared-statements: true
-```
-
-### redis 配置
-
-redis 安装完成以后,设置上 redis 的密码(也可以设置为空),确保 "host:port" 链接可以访问 redis 即可。
-
-```yaml
- redis:
- host: {host} #redis 地址
- port: {port} #redis 端口
- password: {password} #redis 密码
- # 连接超时时间(毫秒)
- timeout: 30000
- # 连接池中的最大空闲连接
- max-idle: 8
- # 连接池中的最小空闲连接
- min-idle: 10
- # 连接池最大连接数(使用负值表示没有限制)
- max-active: 100
- # 连接池最大阻塞等待时间(使用负值表示没有限制)
- max-wait: -1
-```
-
-### 数据库初始化
-
-导入下方脚本:
-
-```yaml
-/*
-SQLyog 企业版 - MySQL GUI v8.14
-MySQL - 8.3.0 : Database - chattyai
-*********************************************************************
-*/
-
-
-/*!40101 SET NAMES utf8 */;
-
-/*!40101 SET SQL_MODE=''*/;
-
-/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
-/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-CREATE DATABASE /*!32312 IF NOT EXISTS*/`chattyai` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
-
-USE `chattyai`;
-
-/*Table structure for table `chat_bot` */
-
-DROP TABLE IF EXISTS `chat_bot`;
-
-CREATE TABLE `chat_bot` (
- `id` bigint NOT NULL AUTO_INCREMENT,
- `bot_name` varchar(50) DEFAULT NULL COMMENT '名称',
- `describe` varchar(2000) DEFAULT NULL COMMENT '描述',
- `pic` varchar(50) DEFAULT NULL COMMENT '头像地址',
- `open` tinyint NOT NULL DEFAULT '1' COMMENT '是否公开',
- `ea_account` varchar(50) DEFAULT NULL COMMENT '环信账号',
- `create_account` varchar(50) DEFAULT NULL COMMENT '创建人',
- `create_time` datetime DEFAULT NULL COMMENT '创建时间',
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB COMMENT='聊天机器人';
-
-/*Data for the table `chat_bot` */
-
-insert into `chat_bot` (`id`, `bot_name`, `describe`, `pic`, `open`, `ea_account`, `create_account`, `create_time`) values('1','智能助手','理解人类语言、生成内容,是生活和工作的智能助手。','1','1','bot1222700215765565440','default','2024-03-28 00:14:08');
-insert into `chat_bot` (`id`, `bot_name`, `describe`, `pic`, `open`, `ea_account`, `create_account`, `create_time`) values('2','编程助手','一个经验丰富的程序员开发助手,擅长 web 前端、springboot 后端和 Android 开发','2','1','bot1223027765968633856','default','2024-03-28 00:14:07');
-insert into `chat_bot` (`id`, `bot_name`, `describe`, `pic`, `open`, `ea_account`, `create_account`, `create_time`) values('3','法律顾问','你精通各个领域的法律知识,能够提供专业且贴心的法律咨询服务','3','1','bot1223027786982096896','default','2024-03-28 00:14:06');
-
-
-/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
-/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
-/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-
-```
-
-### 启动说明
-
-1. `host` 填写为 `127.0.0.1`。
-2. `port` 填写为 redis 所占用的端口。
-3. `password` 填写 redis 的密码(如果没有密码,使用 `#` 注释该配置)。
-
-![img](/images/aigc/redis_password.png)
-
-4. 使用 `mvn install` 将项目打包为 `jar`。
-
-![img](/images/aigc/jar.png)
-
-5. 找到对应位置的 `jar` 包,上传到服务器。
-
-使用命令启动即可:
-
-```shell
-nohup java -jar $APP_DIR/chattyai-0.0.1-SNAPSHOT.jar --server.port=$PORT >> ./chattyai.log 2>&1 &
-```
-
-- `$APP_DIR` 替换为上传 jar 包存在的根路径。
-- `$PORT` 替换为需要占用的端口。
-
-6. 查看启动日志。
-
-```shell
-tail -f $APP_DIR/chattyai.log
-```
-
-## FAQ
-
-1. Q: 项目为何启动失败?
-
-A: 确保 JDK 配置正确,端口没有被占用,redis 能被访问到。
-
-1. Q: 项目启动后为何无法访问?
-
-A: 检查以下两方面:
- - 配置 nginx 的情况下,请确保 nginx 配置正确。
- - 未配置 nginx 的情况下,请确保端口对外开放。
-
-3. Q: MiniMax 的调用失败,无返回结果,是什么原因?
-
-A: 请确保 MiniMax 有余额,否则可能导致调用 MiniMax 的调用失败。
-
-4. Q: 如何实现问候语?
-
-A: 你可以设置问候语,让机器人用户每天定时主动向聊天用户发送问候语。
-
-`com.easemob.chattyai.chat.util.GreetUtil` 类中存在一个静态代码块和以下三个镜头属性。
-
-静态代码用于加载该类时,分别向这三个 List 中添加对应的问候语。
-
-```java
- /**
- * 早上问候语 list
- */
- public static List moringGreetList = new ArrayList<>();
-
- /**
- * 中午问候语 list
- */
- public static List noonGreetList = new ArrayList<>();
-
- /**
- * 晚上问候语 list
- */
- public static List eveningGreetList = new ArrayList<>();
-```
-
-设置问候语后,可在 `com.easemob.chattyai.task.GreetTask` 类中设置定时任务。定时任务触发的 Cron 如下所示。例如,若用户 A 与机器人用户 B 聊过天,机器人用户 B 会在每天早上 9 点、中午 12 点和晚上 21 点给用户发送消息。
-
-```java
-0 0 9,12,21 * * ?
-```
-
-5. Q: 如何获取历史消息?
-
-A: 下图中的 `MiniMaxAiSingleHandler` 为单聊的 MinMax 处理类,`MiniMaxAiGroupHandler` 为群聊的 MinMax 的处理类。
-
-![img](/images/aigc/historical_message.png)
-
-在本示例项目中,与智能体交互后,聊天记录会同步处理到 从 redis 获取的 key (`Constant.CHAT_GROUP_HISTORY_REDIS_KEY_PREFIX+发送人的环信用户ID+:+机器人的环信 ID`)的对应的 value 中,方便下一次聊天时作为历史消息传递给 AI。示例项目中只取最近 10 条消息作为历史数据,对应的代码如下所示:
-
-```java
-long l = redisUtil.lGetListSize(key);
-if (l > 10) {
- redisUtil.leftpop(key, 2L);
-}
-```
diff --git a/docs/product/aigc/aigc_scenario_introduction.md b/docs/product/aigc/aigc_scenario_introduction.md
deleted file mode 100644
index 8d1615be..00000000
--- a/docs/product/aigc/aigc_scenario_introduction.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# 方案介绍
-
-环信 AIGC X IM(Artificial Intelligence Generated Content,生成式人工智能)一站式解决方案,充分发挥即时通讯的实时性和便利性,同时叠加AI的智能化能力,实现了更便捷的开发、更具沉浸感和个性化的用户体验。通过环信 AIGC 解决方案,可以快速搭建多类低延迟的 AI 实时互动场景,包括:
-
-- **虚拟角色互动**:AIGC 结合 IM 能力可定制特定人物性格的 AI 陪伴者,提供即时的情感支持与个性化体验,创造更加新颖的社交体验。
-- **营销内容推送**:AIGC 基于用户属性、历史记录等数据训练,可定制化生成营销摘要,基于 IM 消息通道,实现信息的精准推送。
-- **社群活跃度提升**:通过 AIGC 在 IM 社群场景中实时创建互动式故事线/谜题等娱乐内容,增强群组活跃度,促进用户间深度互动。
-- **社交辅助工具**:AIGC 技术在聊天过程中生成表情包、GIF 动图、多语言翻译等个性化内容,满足用户表达需求,提升沟通乐趣。
-
-## 亮点功能
-
-**模型能力**
-
-- 集成了国内外多语言大模型,可以根据用户输入实时生成高质量的内容回复。
-- 支持跨语言沟通,并可针对不同领域提供定制化的智能对话服务。
-
-**多模态交互与融合**
-
-- AI 模型能够基于文本、语音、图像等多元信息进行理解并产出相应的内容。
-- AI+IM 可以自动生成图文混排、动态表情、互动卡片等内容,丰富聊天体验。
-
-**消息触达能力**
-
-- 结合 AIGC 技术,可实现智能化消息推荐,例如,根据上下文情境自动发送相关信息或提示。
-- 实时高效离线唤醒推送机制,根据用户行为和偏好进行定制化推送,提高推送效果和转化率。
-
-**群组模型与协同创作**
-
-- 在群聊环境中,AI 可以辅助管理群组讨论,如提炼关键信息、总结讨论要点。
-- 支持多个 AI 机器人同时参与群聊讨论,多角色分工,从不同角度对用户提问进行协作回答。
-
-## 方案优势
-
-环信 AIGC 解决方案具有如下优势:
-
-**1. 海量并发,稳定可靠的平台能力**
-
-支持多重备份、灾备恢复、回调容灾等技术手段,单日数十亿级别的消息传输和处理,SLA 达 99.99%,持续保障系统高可用性和可靠性。
-
-**2. 国际化加速,提升出海使用体验**
-
-提供快速、准确的消息传递和响应,全球平均时延小于 100 ms,使得用户交互过程流畅自然,提升应用的竞争力和用户满意度。
-
-**3. 易开发,方案快速上线**
-
-开发者可以通过调用 API 等方式快速构建智能交互功能,提供开箱即用的场景化 Demo,最快 1 天实现方案快速验证。
-
-**4. 内容审核,为应用安全保驾护航**
-
-基于先进的算法和 AI 技术,在保证高效性和准确性的同时,自动检测和屏蔽不合规信息,确保聊天环境的健康和安全。
-
-**5. 安全合规,保障用户隐私安全**
-
-支持国内外不同区域合规要求,根据最小化和公开透明处理原则,保护不同区域的网络安全、数据安全及用户隐私安全。
-
-**6. 卓越服务,助力战略愿景落地**
-
-支持全球范围内的企业级客户服务,具备丰富的行业标杆客户案例,提供专属方案咨询、集成顾问、营销推广及客户成功保障服务。
-
-
-
-
diff --git a/docs/product/aigc/aigc_selection.md b/docs/product/aigc/aigc_selection.md
deleted file mode 100644
index 925df9ec..00000000
--- a/docs/product/aigc/aigc_selection.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# 环信 AIGC 方案选择
-
-本文提供两种方案供你接入环信 AI 聊天服务,实现与机器人的聊天功能:
-
-- **方案一**:利用服务器回调服务,在 IM 中引入 AI 服务。
-- **方案二**:使用环信即时通讯云提供的 AI 智能功能。
-
-## 方案一
-
-通过配置服务端和客户端,利用环信即时通信 IM 服务器回调功能,在 IM 中引入 AI 服务(以 MiniMax 中文大语言模型为例),创建机器人账号,从而跑通示例项目。
-
-### 技术架构
-
-目前,环信 AIGC 方案可通过服务器回调服务实现与机器人聊天,以单聊为例,工作流程如下:
-
-1. 用户发消息给机器人。
-2. 环信服务器收到消息后,通过服务端回调将事件通知第三方大模型厂商。
-3. 第三方大模型厂商收到事件通知,将消息回复内容发送给 app server。
-4. app server 调用 Restful API 将回复内容发送给环信服务器。
-5. 环信服务器将回复内容发送给用户。
-
-![img](/images/aigc/technical_architecture1.png)
-
-### 跑通示例项目
-
-完成客户端和服务端配置,跑通 [GitHub 示例项目](https://github.com/easemob/Easemob-AIGCService-Example),体验与 AIGC 数字人沟通方案。
-
-有关更多信息,请参见[跑通示例项目文档说明](aigc_run_through_demo_server.html)。
-
-## 方案二
-
-使用环信即时通讯 IM 提供的 AI 机器人聊天。你需要在[环信即时通讯控制台](https://console.easemob.com/user/login)开通 AI 智能功能,创建机器人,即实现与机器人的**单聊**功能。
-
-此外,你可以在[环信即时通讯控制台](https://console.easemob.com/user/login)查看机器人账号消耗的 token 数和消耗趋势。
-
-有关更多信息,请参见[使用 AI 机器人聊天](aigc_use.html)和[调用 REST API 获取 app 下的机器人列表](aigc_rest_api.html)相关文档。
-
-### 技术架构
-
-目前,环信 AI 智能功能**仅支持单聊**,工作流程如下:
-
-1. 用户发消息给机器人。
-2. 环信服务器收到消息后,通过环信机器人服务将用户消息传递给第三方大模型厂商。
-3. 第三方大模型厂商对用户消息进行回复,将消息回复内容发送给环信机器人服务。
-4. 环信机器人服务收到消息后,通过环信服务器将回复内容发送给用户。
-
-![img](/images/aigc/technical_architecture2.png)
-
-
diff --git a/docs/product/aigc/aigc_use.md b/docs/product/aigc/aigc_use.md
deleted file mode 100644
index 39ac1fd9..00000000
--- a/docs/product/aigc/aigc_use.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# 使用 AI 智能功能
-
-使用 AI 机器人聊天,你需要首先开通 AI 智能功能,然后创建机器人,与机器人进行**一对一聊天**。
-
-## 1. 开通 AI 智能功能
-
-你可以在[环信即时通讯控制台](https://console.easemob.com/user/login)开通 AI 智能功能。
-
-1. 登录[环信即时通讯云控制台](https://console.easemob.com/user/login),在首页的**应用列表**区域点击目标应用的**操作**一栏中的**管理**。
-
-![img](/images/aigc/app_select.png)
-
-2. 选择**即时通讯** > **功能配置** > **功能配置总览**。选择**试用功能**页签,点击**智能机器人 Chatbot** 对应的**操作**一栏中的**申请试用**。
-
-![img](/images/aigc/ai_open.png)
-
-## 2. 创建机器人
-
-1. 选择**即时通讯** > **AI 智能** > **AI机器人**,进入 **AI 机器人**页面。点击**创建机器人**。
-
-:::tip
-每个 app 默认支持 200 个机器人,可联系环信商务提升该上限。
-:::
-
-![img](/images/aigc/aichatbot_create.png)
-
-2. 配置机器人相关信息。
-
-![img](/images/aigc/aichatbot_configure.png)
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :--------- | :----- | :----------- | :--------- |
-| 机器人名称 | String | 是 | 机器人的名称,长度在 64 个字符内。 |
-| 用户 ID | String | 是 | 机器人对应的 IM 的用户 ID。目前一个机器人只能绑定一个用户 ID。
**若输入了不存在的用户 ID,配置机器人信息后,会自动创建用户。**
用户 ID 长度不可超过 64 个字节。不可设置为空。支持以下字符集:
- 26 个小写英文字母 a-z;
- 26 个大写英文字母 A-Z;
- 10 个数字 0-9;
- “\_”, “-”, “.”。
- 该参数不区分大小写,因此 `Aa` 和 `aa` 为相同的用户 ID;
- 请确保同一个 app 下,用户 ID 唯一;
- 用户 ID 为公开信息,请勿使用 UUID、邮箱地址、手机号等敏感信息。 |
-| 头像 | String | 是 | 机器人的头像图片链接。 |
-| AI引擎 | | 是 | 目前只能选择 **MINIMAX**。 |
-| Model | | 是 | 厂商支持的 AI 模型类别,当前可支持选择。关于 API 模型类别的详细介绍,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/Models?key=66701cb01d57f38758d581a4)。 |
-| System prompt | String | 是 | 具体机器人的设定,长度影响接口性能。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 |
-| Top-p | Int | 是 | 控制生成环节采样范围,参数值越小,生成结果越稳定。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。|
-| Temperature | Int | 是 | 控制生成环境采样随机性,参数值越小,生成结果越稳定。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 |
-
-3. 查看新创建的机器人。
-
-![img](/images/aigc/aichatbot_view.png)
-
-## 3. 使用机器人聊天
-
-创建机器人账户后,你可以体验和它进行**一对一聊天**。
-
-1. 若你开启了好友关系检查功能(**即时通讯** > **服务概览** > **设置**),可以在**即时通讯 > 运营服务 > 用户管理** 页面,添加机器人绑定的即时通讯 IM 用户为好友。例如,图中的 **aitest** 用户添加新创建的 **bbb** 用户为好友,与机器人 **aaa** 进行聊天。在 **aitest1** 用户的**操作**一栏中选择**查看IM用户好友**,在文本框中输入 **bbb**,点击**添加好友**。
-
-:::tip
-若关闭了好友检查功能,则无需添加好友即可聊天。
-:::
-
-![img](/images/aigc/ai_add_contact.png)
-
-2. 用户 **aitest** 与机器人 **aaa** 进行聊天,以下截图以 Android 设备为例。
-
-
-
-## 4. 查看数据统计
-
-你可以在[环信即时通讯控制台](https://console.easemob.com/user/login)的左侧导航栏选择 **即时通讯** > **AI 智能** > **数据统计**,查看机器人账号消耗的 token 数和消耗趋势。
-
-目前,大模型平台只能选择 **MINIMAX**。
-
-![img](/images/aigc/ai_token_statistic.png)
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/product/circle/api_reference_android.md b/docs/product/circle/api_reference_android.md
deleted file mode 100644
index 6e434f9c..00000000
--- a/docs/product/circle/api_reference_android.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# 环信超级社区 Android SDK API 参考
-
-
-
-若要访问环信超级社区 Android SDK API 参考,请点击[这里](https://www.easemob.com/apidoc/Android/hyphenate-api-doc/html/annotated.html)。
-
-
diff --git a/docs/product/circle/api_reference_ios.md b/docs/product/circle/api_reference_ios.md
deleted file mode 100644
index 3ab48bd8..00000000
--- a/docs/product/circle/api_reference_ios.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# 环信超级社区 iOS SDK API 参考
-
-
-
-若要访问环信超级社区 iOS SDK API 参考,请点击[这里](https://www.easemob.com/apidoc/iOS/html_ch/annotated.html)。
\ No newline at end of file
diff --git a/docs/product/circle/api_reference_web.md b/docs/product/circle/api_reference_web.md
deleted file mode 100644
index 1dbe6926..00000000
--- a/docs/product/circle/api_reference_web.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# 环信超级社区 Web SDK API 参考
-
-
-
-若要访问环信超级社区 Web SDK API 参考,请点击[这里](https://www.easemob.com/apidoc/Web/)。
\ No newline at end of file
diff --git a/docs/product/circle/category_mgmt_android.md b/docs/product/circle/category_mgmt_android.md
deleted file mode 100644
index 91b3ebdf..00000000
--- a/docs/product/circle/category_mgmt_android.md
+++ /dev/null
@@ -1,173 +0,0 @@
-# 管理频道分组
-
-
-
-环信超级社区(Circle)支持将多个频道归入一个频道分组,方便频道管理。例如,可将歌剧频道、民歌频道和流行歌曲频道划分为声乐频道分组。
-
-社区创建时会创建默认的频道分组,包含默认频道。
-
-**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:**
-
-**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。**
-**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。**
-**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_android.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。**
-**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_android.html#解散社区)和[删除频道](channel_mgmt_android.html#解散频道)等 API。**
-
-## 技术原理
-
-环信 Circle Android SDK 提供 `EMCircleManager` 类和 `EMCircleCategory` 类用于频道分组管理,支持你通过调用 API 实现如下功能:
-
-- 创建和管理频道分组;
-- 监听频道分组事件。
-
-## 前提条件
-
-开始前,请确保满足以下条件:
-
-- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/initialization.html)
-- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
-- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
-
-## 实现方法
-
-### 创建频道分组
-
-仅社区所有者可以调用 `createCategory` 方法创建频道分组。创建频道分组时需设置频道分组所属的社区 ID 和频道分组名称。频道分组创建后,社区所有成员(除创建者外)会收到 `EMCircleCategoryListener#onCategoryCreated` 事件。
-
-每个社区下最多可创建 50 个频道分组,超过需要联系商务。
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().createCategory(serverId, categoryName, new EMValueCallBack() {
- @Override
- public void onSuccess(EMCircleCategory value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
-});
-```
-
-### 修改频道分组名称
-
-仅社区所有者和管理员可调用 `updateCategory` 方法修改频道分组名称。频道分组名称修改后,社区所有成员(除操作者外)会收到 `EMCircleCategoryListener#onCategoryUpdated` 事件。
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().updateCategory(serverId, categoryId, categoryName, new EMValueCallBack() {
- @Override
- public void onSuccess(EMCircleCategory value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
-});
-```
-
-### 删除频道分组
-
-仅社区所有者可调用 `destroyCategory` 方法删除频道分组。社区所有成员(除操作者外)会收到 `EMCircleCategoryListener#onCategoryDestroyed` 事件。频道分组删除后,该频道分组下的所有频道会移至当前社区的默认频道分组下。
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().destroyCategory(serverId, categoryId, new EMCallBack() {
- @Override
- public void onSuccess() {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
- });
-```
-
-### 分页获取社区下的频道分组列表
-
-社区中的所有成员可以调用 `fetchCategoriesInServer` 方法获取社区下的频道分组列表。
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().fetchCategoriesInServer(serverID, 20, null, new EMValueCallBack>() {
- @Override
- public void onSuccess(EMCursorResult value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
- });
-```
-
-### 更换指定频道的频道分组
-
-仅社区所有者和管理员可以调用 `transferChannel` 方法将指定频道从一个频道分组转移至另一个频道分组。频道分组更换后,社区所有成员(除操作者外)会收到 `EMCircleCategoryListener#onChannelTransfered` 事件。
-
-:::tip
-调用该方法时,若 `newCategoryId` 参数传入 `null` 或空字符串 `""`,表示将频道归入社区默认的频道分组。
-:::
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().transferChannel(serverId,channelId, newCategoryId, new EMCallBack() {
- @Override
- public void onSuccess() {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
- });
-```
-
-### 监听频道分组事件
-
-`EMCircleManager` 中提供频道分组事件的监听接口。开发者可以通过设置此监听,获取频道分组中的事件,并做出相应处理。如果不再使用该监听,需要移除,防止出现内存泄漏。
-
-```java
-EMCircleCategoryListener chatCategoryListener = new EMCircleCategoryListener() {
- //创建了频道分组。社区所有成员(除创建者外)会收到该事件。
- @Override
- public void onCategoryCreated(EMCircleCategory category, String creator) {
-
- }
- //删除了频道分组。社区所有成员(除操作者外)会收到该事件。
- @Override
- public void onCategoryDestroyed(String serverId, String categoryId, String initiator) {
-
- }
- //修改了频道分组名称。社区所有成员(除操作者外)会收到该事件。
- @Override
- public void onCategoryUpdated(EMCircleCategory category, String initiator) {
-
- }
- //频道更换了分组。社区所有成员(除操作者外)会收到该事件。
- @Override
- public void onChannelTransfered(String serverId, String fromCategoryId, String toCategoryId, String channelId, String initiator) {
-
- }
-};
-
-//添加频道分组监听。
-EMClient.getInstance().chatCircleManager().addCategoryListener(chatCategoryListener);
-//移除频道分组监听。
-EMClient.getInstance().chatCircleManager().removeCategoryListener(chatCategoryListener);
-//清除所有频道分组监听。
-EMClient.getInstance().chatCircleManager().clearCategoryListeners();
-```
\ No newline at end of file
diff --git a/docs/product/circle/category_mgmt_ios.md b/docs/product/circle/category_mgmt_ios.md
deleted file mode 100644
index c1e83166..00000000
--- a/docs/product/circle/category_mgmt_ios.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# 管理频道分组
-
-
-
-环信超级社区(Circle)支持将多个频道归入一个频道分组,方便频道管理。例如,可将歌剧频道、民歌频道和流行歌曲频道划分为声乐频道分组。
-
-社区创建时会创建默认的频道分组,包含默认频道。
-
-**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:**
-
-**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。**
-**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。**
-**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_ios.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。**
-**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_ios.html#解散社区)和[删除频道](channel_mgmt_ios.html#解散频道)等 API。**
-
-## 技术原理
-
-环信 Circle Android SDK 提供 `IEMCircleManager` 类和 `EMCircleManagerCategoryDelegate` 类用于频道分组管理,支持你通过调用 API 实现如下功能:
-
-- 创建和管理频道分组;
-- 监听频道分组事件。
-
-## 前提条件
-
-开始前,请确保满足以下条件:
-
-- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/initialization.html)。
-- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
-- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
-
-## 实现方法
-
-### 创建频道分组
-
-仅社区所有者可以调用 `createCategory` 方法创建频道分组。创建频道分组时需设置频道分组所属的社区 ID 和频道分组名称。频道分组创建后,社区所有成员(除创建者外)会收到 `EMCircleManagerCategoryDelegate#onCategoryCreated` 事件。
-
-每个社区下最多可创建 50 个频道分组,超过需要联系商务。
-
-示例代码如下:
-
-```swift
-EMClient.shared().circleManager?.createCategory(serverId, name: name, completion: { category, error in
-})
-```
-
-### 修改频道分组名称
-
-仅社区所有者和管理员可调用 `updateCategory` 方法修改频道分组名称。频道分组名称修改后,社区所有成员(除操作者外)会收到 `onCategoryUpdated` 事件。
-
-示例代码如下:
-
-```swift
-EMClient.shared().circleManager?.updateCategory(serverId, categoryId: categoryId, name: name, completion: { category, error in
-})
-```
-
-### 删除频道分组
-
-仅社区所有者可调用 `destroyCategory` 方法删除频道分组。社区所有成员(除操作者外)会收到 `EMCircleManagerCategoryDelegate#onCategoryDestroyed` 事件。频道分组删除后,该频道分组下的所有频道会移至当前社区的默认频道分组下。
-
-示例代码如下:
-
-```swift
-EMClient.shared().circleManager?.destroyCategory(self.serverId, categoryId: self.groupId, completion: { error in
-})
-```
-
-### 分页获取社区下的频道分组列表
-
-社区中的所有成员可以调用 `fetchCategories` 方法获取社区下的频道分组列表。
-
-示例代码如下:
-
-```swift
-EMClient.shared().circleManager?.fetchCategories(inServer: self.serverId, limit: 20, cursor: refresh ? nil : self.result?.cursor, completion: { result, error in
-})
-```
-
-### 更换指定频道的频道分组
-
-仅社区所有者和管理员可以调用 `transferChannel` 方法将指定频道从一个频道分组转移至另一个频道分组。频道分组更换后,社区所有成员(除操作者外)会收到 `EMCircleManagerCategoryDelegate#onChannelTransferred` 事件。
-
-:::tip
-调用该方法时,若 `newCategoryId` 参数传入 `nil` 或空字符串 `""`,表示将频道归入社区默认的频道分组。
-:::
-
-示例代码如下:
-
-```swift
-EMClient.shared().circleManager?.transferChannel(self.serverId, channelId: self.channelId, newCategoryId: category.categoryId, completion: { error in
-})
-```
-
-### 监听频道分组事件
-
-`IEMCircleManager` 中提供频道分组事件的监听接口。开发者可以通过设置此监听,获取频道分组中的事件,并做出相应处理。如果不再使用该监听,需要移除,防止出现内存泄漏。
-
-```swift
-//添加频道分组回调代理。
-EMClient.shared().circleManager?.add(categoryDelegate: self, queue: nil)
-//移除频道分组回调代理。
-EMClient.shared().circleManager?.remove(categoryDelegate: self)
-```
-
-```swift
-//创建了频道分组。社区所有成员(除创建者外)会收到该事件。
-func onCategoryCreated(_ category: EMCircleCategory, creator: String) {
-}
-
-//删除了频道分组。社区所有成员(除操作者外)会收到该事件。
-func onCategoryDestroyed(_ serverId: String, categoryId: String, initiator: String) {
-}
-
-//修改了频道分组名称。社区所有成员(除操作者外)会收到该事件。
-func onCategoryUpdated(_ category: EMCircleCategory, initiator: String) {
-}
-
-//频道更换了分组。社区所有成员(除操作者外)会收到该事件。
-func onChannelTransferred(_ serverId: String, from fromCategoryId: String, to toCategoryId: String, channelId: String, initiator: String) {
-}
-```
diff --git a/docs/product/circle/category_mgmt_rest.md b/docs/product/circle/category_mgmt_rest.md
deleted file mode 100644
index 3ef05588..00000000
--- a/docs/product/circle/category_mgmt_rest.md
+++ /dev/null
@@ -1,699 +0,0 @@
-# 管理社区频道分组
-
-
-
-环信超级社区(Circle)支持频道分组方便频道管理。例如,可将歌剧频道、民歌频道和流行歌曲频道划分为声乐频道分组。
-
-社区创建时会创建默认的频道分组,包含默认频道。
-
-**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:**
-
-**1. 在环信控制台或者调用 RESTful API 解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。**
-**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。**
-**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_rest.html#查询指定频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。**
-**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_rest.html#删除社区)和[删除频道](channel_mgmt_rest.html#删除频道)等 API。**
-
-## 前提条件
-
-要调用环信即时通讯 RESTful API,请确保满足以下要求:
-
-- 已在环信即时通讯控制台 [开通配置环信即时通讯 IM 服务](/document/server-side/enable_and_configure_IM.html)。
-- 了解环信 IM RESTful API 的调用频率限制,详见 [接口频率限制](/product/limitationapi.html)。
-
-## 公共参数
-
-### 请求参数
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :--------- | :----- | :------- | :----------------------------------------------------------- |
-| `host` | String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。详见[获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 |
-| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。详见[获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 |
-| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。详见[获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 |
-| `server_id` | String | 是 | 社区 ID。 |
-| `channel_id` | String | 是 | 频道 ID。 |
-| `channel_category_id` | String | 是 | 频道分组 ID。 |
-| `user_id` | String | 是 | 用户 ID。 |
-
-:::tip
-对于分页获取数据列表,若查询参数中的 `limit` 和 `cursor` 均未设置,则服务器返回首页的数据列表。
-:::
-
-### 响应参数
-
-| 参数 | 类型 | 描述 |
-| :-----------------| :----- | :----------------------------------------------------------- |
-| `channels.owner` | String | 频道创建者。 |
-| `channels.name` | String | 频道名称。 |
-| `channels.type` | Int | 频道类型:
- `0`:公开频道;
- `1`:私密频道。 |
-| `channels.mode` | Int | 频道模式:
- `0`:文字频道;
- `1`:语聊频道。 |
-| `channels.description` | String | 频道描述。|
-| `channels.custom` | String | 频道的扩展信息。 |
-| `channels.created` | Long | 频道的创建时间,Unix 时间戳,单位为毫秒。 |
-| `channels.server_id` | String | 社区 ID。 |
-| `channels.channel_category_id` | String | 频道分组 ID。 |
-| `channels.channel_id` | String | 频道 ID。 |
-| `channels.max_users` | Long | 频道最大成员数量。 |
-| `channels.default_channel` | Int | 是否为社区的默认频道:
- `0`:否;
- `1`:是。 |
-| `rtc_name` | String | RTC 频道名称。该名称在加入 RTC 频道时使用。若使用声网 RTC,该名称还用于[生成 RTC Token](https://docportal.shengwang.cn/cn/voice-call-4.x/token_server_android_ng?platform=Android)。
该参数仅在创建语聊频道时返回,若创建语聊房频道时未指定 `rtc_name`,服务器将使用频道 ID 作为该参数的值返回。 |
-
-## 认证方式
-
-环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 `Authorization` 字段:
-
-Authorization:`Bearer ${YourToken}`
-
-为提高项目的安全性,环信使用 App Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 需使用 App Token 的鉴权方式,详见 [使用环信 App Token 鉴权](/product/easemob_app_token.html)。
-
-## 创建频道分组
-
-在社区下创建一个频道分组,将多个频道归入一个频道分组方便管理。
-
-每个社区下最多可以创建 50 个频道分组。每个频道只能加入一个频道分组。
-
-### HTTP 请求
-
-```http
-POST https://{host}/{org_name}/{app_name}/circle/channel/category
-```
-
-#### 路径参数
-
-参数及描述详见[公共参数](#公共参数)。
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :------------ | :----- | :------- | :----------------------------------------------------------- |
-| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Accept` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 |
-
-#### 请求 body
-
-| 参数 | 类型 | 是否必需 | 备注 |
-| :---------- | :----- | :------- | :----------------------------------------------------------- |
-| `server_id` | String | 是 | 社区 ID,即频道分组所属的社区。 |
-| `name` | String | 是 | 频道分组名称,长度不能超过 50 个字符。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段:
-
-| 字段 | 类型 | 描述 |
-| :-------- | :----- | :------------------ |
-| `code` | Int | 环信超级社区的服务状态码。 |
-| `channel_category_id` | String | 频道分组 ID。 |
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-将 替换为你在服务端生成的 App Token
-curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category' -d '{
- "server_id" : "19SW5Q85jHxxxxx6T5kexvn",
- "name" : "channel category name"
-}'
-```
-
-#### 响应示例
-
-```json
-{
- "code": 200,
- "channel_category_id": "77a9860xxxxxx2b54881025861c",
-}
-```
-
-## 修改频道分组的名称
-
-修改指定社区下的特定频道分组的名称。
-
-### HTTP 请求
-
-```http
-PUT https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}
-```
-
-#### 路径参数
-
-参数及描述详见[公共参数](#公共参数)。
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :------------ | :----- | :------- | :----------------------------------------------------------- |
-| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Accept` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 |
-
-#### 请求 body
-
-| 参数 | 类型 | 是否必需 | 备注 |
-| :---------- | :----- | :------- | :----------------------------------------------------------- |
-| `server_id` | String | 是 | 社区 ID,即要修改的频道分组所属社区的 ID。 |
-| `name` | String | 是 | 修改后的频道分组名称,长度不能超过 50 个字符。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段:
-
-| 字段 | 类型 | 描述 |
-| :----- | :--- | :------------------ |
-| `code` | Int | 环信超级社区的服务状态码。 |
-| `channelCategory` | JSON | 频道分组的数据。 |
-| `channelCategory.name` | String | 修改后的频道分组名称。 |
-| `channelCategory.created` | Long | 频道分组的创建时间,Unix 时间戳,单位为毫秒。 |
-| `channelCategory.channel_category_id` | String | 频道分组 ID。 |
-
-其他字段及描述详见 [公共参数](#公共参数)。
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [响应状态码](/document/server-side/error.html)了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-将 替换为你在服务端生成的 App Token
-curl -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX' -d '{
- "server_id" : "19SW5Q85jHxxxxx6T5kexvn",
- "name" : "update channel category name"
-}'
-```
-
-#### 响应示例
-
-```json
-{
- "code": 200,
- "channelCategory": {
- "name": "update channel category name",
- "created": 1667471759201,
- "server_id": "19SW5Q85jHxxxxx6T5kexvn",
- "channel_category_id": "77a9860xxxxxx2b54881025861c"
- }
-}
-```
-
-## 删除社区下的频道分组
-
-删除指定社区下的特定频道分组。删除频道分组后,该频道分组下的所有频道会添加到社区的默认频道分组中。
-
-### HTTP 请求
-
-```http
-DELETE https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}?serverId={server_id}
-```
-
-#### 路径参数
-
-参数及描述详见[公共参数](#公共参数)。
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :------------ | :----- | :------- | :----------------------------------------------------------- |
-| `Accept` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段:
-
-| 字段 | 类型 | 描述 |
-| :--- | :--- | :------------------ |
-| `code` | Int | 环信超级社区的服务状态码。 |
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-将 替换为你在服务端生成的 App Token
-curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX?serverId=XXX'
-```
-
-#### 响应示例
-
-```json
-{
- "code": 200
-}
-```
-
-## 更换频道的频道分组
-
-将指定频道从当前频道分组转移至其他频道分组。
-
-### HTTP 请求
-
-```http
-POST
-http://{host}/{org_name}/{app_name}/circle/channel/category/member/transfer?serverId={server_id}&channelCategoryId={channel_category_id}&channelId={channel_id}
-```
-
-#### 路径参数
-
-参数及描述详见[公共参数](#公共参数)。
-
-#### 查询参数
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :-------------------- | :----- | :------- | :----------------------------------------------------------- |
-| `server_id` | String | 是 | 社区 ID。 |
-| `channel_category_id` | String | 否 | 频道分组 ID。请求时若设置了该参数,会将频道转移至指定的频道分组中;若不设置该参数,则将频道转移至社区的默认频道分组中。 |
-| `channel_id` | String | 是 | 要转移频道分组的频道 ID。 |
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :-------------- | :----- | :------- | :----------------------------------------------------------- |
-| `Accept` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段:
-
-| 字段 | 类型 | 描述 |
-| :----------- | :----- | :--------------------------------------------------- |
-| `code` | Int | 环信超级社区的服务状态码。 |
-
-其他字段及描述详见[公共参数](#公共参数)。
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-将 替换为你在服务端生成的 App Token
-curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/member/transfer?serverId=XXX&channelCategoryId=XXX&channelId=XXX'
-```
-
-#### 响应示例
-
-```json
-{
- "code": 200
-}
-```
-
-## 获取社区下的频道分组列表
-
-分页获取指定社区下的频道分组列表。
-
-### HTTP 请求
-
-```http
-GET https://{host}/{org_name}/{app_name}/circle/channel/category/list?serverId={server_id}&limit={limit}&cursor={cursor}
-```
-
-#### 路径参数
-
-参数及描述详见[公共参数](#公共参数)。
-
-#### 查询参数
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :--- | :----- | :------- | :----------------------------------------------------------- |
-| `server_id` | String | 是 | 社区 ID。|
-| `limit` | Int | 否 | 每页获取的社区下的频道分组数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。 |
-| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 |
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :------------ | :----- | :------- | :----------------------------------------------------------- |
-| `Accept` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段:
-
-| 字段 | 类型 | 描述 |
-| :------ | :--- | :--------------------- |
-| `code` | Int | 环信超级社区的服务状态码。 |
-| `count` | Int | 获取的频道分组数量。 |
-| `channelCategoryList` | List | 获取的频道分组列表。 |
-| `channelCategoryList.name` | String| 频道分组名称。 |
-| `channelCategoryList.created` | Long | 频道分组的创建时间。 |
-| `channelCategoryList.channel_category_id` | String | 频道分组 ID。 |
-| `cursor` | String | 查询游标,指定下次数据查询的起始位置。 |
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-将 替换为你在服务端生成的 App Token
-curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/list?serverId=XXX'
-```
-#### 响应示例
-
-```json
-{
- "code": 200,
- "count": 1,
- "channelCategoryList": [
- {
- "name": "channel category name",
- "created": 1667471759201,
- "server_id": "19SW5Q85jHxxxxx6T5kexvn",
- "channel_category_id": "77a9860xxxxxx2b54881025861c"
- }
- ],
- "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX"
-}
-```
-
-## 获取指定频道分组下的频道列表
-
-分页获取指定频道分组下的所有频道的列表(包括公开和私密频道)。
-
-### HTTP 请求
-
-```http
-GET https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}/member/list?serverId={server_id}&limit={limit}&cursor={cursor}
-```
-
-#### 路径参数
-
-参数及描述详见[公共参数](#公共参数)。
-
-#### 查询参数
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :--- | :----- | :------- | :----------------------------------------------------------- |
-| `server_id` | String | 是 | 社区 ID。|
-| `limit` | Int | 否 | 每页获取的频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。|
-| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 |
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :------------ | :----- | :------- | :----------------------------------------------------------- |
-| `Accept` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段:
-
-| 字段 | 类型 | 描述 |
-| :---- | :--- | :------------------- |
-| `code` | Int | 环信超级社区的服务状态码。 |
-| `count` | Int | 获取的指定频道分组下的频道数量。 |
-| `channels` | List | 获取的频道列表。 |
-| `cursor` | String | 游标,指定下次数据查询的起始位置。 |
-
-其他字段及描述详见[公共参数](#公共参数)。
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-将 替换为你在服务端生成的 App Token
-curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX/member/list?serverId=xxx?limit={limit}&cursor={cursor}'
-```
-
-#### 响应示例
-
-```json
-{
- "code": 200,
- "count": 1,
- "channels": [
- {
- "owner": "user1",
- "name": "chat channel",
- "type": 0,
- "mode": 0,
- "description": "chat channel",
- "custom": "custom",
- "created": 1675845650856,
- "server_id": "19VM9oPBasxxxxxx0tvWViEsdM",
- "channel_category_id": "77a9860xxxxxx2b54881025861c",
- "channel_id": "2059xxxxxx1542",
- "max_users": 200,
- "default_channel": 0
- }
- ],
- "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX"
-}
-```
-
-## 获取指定频道分组下的公开频道列表
-
-分页获取指定频道分组下的公开频道列表。
-
-### HTTP 请求
-
-```http
-GET https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}/public/member/list?serverId={server_id}&limit={limit}&cursor={cursor}
-```
-
-#### 路径参数
-
-参数及描述详见[公共参数](#公共参数)。
-
-#### 查询参数
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :--- | :----- | :------- | :----------------------------------------------------------- |
-| `server_id` | String | 是 | 社区 ID。|
-| `channel_category_id` | String | 是 | 频道分组 ID。|
-| `limit` | Int | 否 | 每页获取的公开频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。|
-| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 |
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :------------ | :----- | :------- | :----------------------------------------------------------- |
-| `Accept` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段:
-
-| 字段 | 类型 | 描述 |
-| :---- | :--- | :------------------- |
-| `code` | Int | 环信超级社区的服务状态码。 |
-| `count` | Int | 获取的公开频道数量。 |
-| `channels` | List | 获取的指定频道分组下的公开频道列表。 |
-| `cursor` | String | 游标,指定下次数据查询的起始位置。 |
-
-其他字段及描述详见[公共参数](#公共参数)。
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-将 替换为你在服务端生成的 App Token
-curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX/public/member/list?serverId=XXX'
-```
-
-#### 响应示例
-
-```json
-{
- "code": 200,
- "count": 1,
- "channels": [
- {
- "owner": "user1",
- "name": "chat channel",
- "type": 0,
- "mode": 0,
- "description": "chat channel",
- "custom": "custom",
- "created": 1675845650856,
- "server_id": "19VM9oPBasxxxxxx0tvWViEsdM",
- "channel_category_id": "77a9860xxxxxx2b54881025861c",
- "channel_id": "2059xxxxxx1542",
- "max_users": 200,
- "default_channel": 0
- }
- ],
- "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX"
-}
-```
-## 获取指定频道分组下的私密频道列表
-
-分页获取频道分组下的私密频道列表。
-
-### HTTP 请求
-
-```http
-GET https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}/private/member/list?serverId={server_id}&limit={limit}&cursor={cursor}
-```
-
-#### 路径参数
-
-参数及描述详见[公共参数](#公共参数)。
-
-#### 查询参数
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :--- | :----- | :------- | :----------------------------------------------------------- |
-| `server_id` | String | 是 | 社区 ID。|
-| `limit` | Int | 否 | 每页获取的社区频道分组下私密频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。 |
-| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 |
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :------------ | :----- | :------- | :----------------------------------------------------------- |
-| `Accept` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段:
-
-| 字段 | 类型 | 描述 |
-| :---- | :--- | :------------------- |
-| `code` | Int | 环信超级社区的服务状态码。 |
-| `count` | Int | 获取的私密频道数量。 |
-| `channels` | List | 获取的指定频道分组下的私密频道列表。 |
-| `cursor` | String | 游标,指定下次数据查询的起始位置。 |
-
-其他字段及描述详见[公共参数](#公共参数)。
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-将 替换为你在服务端生成的 App Token
-curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX/private/member/list?serverId=XXX'
-```
-
-#### 响应示例
-
-```json
-{
- "code": 200,
- "count": 1,
- "channels": [
- {
- "owner": "user1",
- "name": "chat channel",
- "type": 1,
- "mode": 0,
- "description": "chat channel",
- "custom": "custom",
- "created": 1675845650856,
- "server_id": "19VM9oPBasxxxxxx0tvWViEsdM",
- "channel_category_id": "77a9860xxxxxx2b54881025861c",
- "channel_id": "2090xxxxxx2369",
- "max_users": 200,
- "default_channel": 0
- }
- ],
- "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX"
-}
-```
-
-## 获取指定频道分组下用户加入的频道列表
-
-分页获取指定频道分组下用户加入的频道 ID 列表。
-
-### HTTP 请求
-
-```http
-GET https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}/user/joined/member/list?serverId={server_id}&userId={user_id}&limit={limit}&cursor={cursor}
-```
-
-#### 路径参数
-
-参数及描述详见[公共参数](#公共参数)。
-
-#### 查询参数
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :--- | :----- | :------- | :----------------------------------------------------------- |
-| `server_id` | String | 是 | 社区 ID。|
-| `user_id` | String | 是 | 用户 ID。|
-| `limit` | Int | 否 | 每页获取的用户在指定频道分组下加入的频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。|
-| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 |
-
-#### 请求 header
-
-| 参数 | 类型 | 是否必需 | 描述 |
-| :------------ | :----- | :------- | :----------------------------------------------------------- |
-| `Accept` | String | 是 | 内容类型。请填 `application/json`。 |
-| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 |
-
-### HTTP 响应
-
-#### 响应 body
-
-如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段:
-
-| 字段 | 类型 | 描述 |
-| :---- | :--- | :------------------- |
-| `code` | Int | 环信超级社区的服务状态码。 |
-| `count` | Int | 获取的用户在指定的频道分组下加入的频道数量。 |
-| `channelIds` | List | 获取的用户在指定的频道分组下加入的频道 ID 列表。 |
-| `cursor` | String | 游标,指定下次数据查询的起始位置。 |
-
-如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。
-
-### 示例
-
-#### 请求示例
-
-```shell
-将 替换为你在服务端生成的 App Token
-curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX/user/joined/member/list?serverId=XXX&userId=XXX'
-```
-
-#### 响应示例
-
-```json
-{
- "code": 200,
- "count": 1,
- "channelIds": [
- "2090xxxxxx2369"
- ],
- "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX"
-}
-```
-
-
diff --git a/docs/product/circle/category_mgmt_web.md b/docs/product/circle/category_mgmt_web.md
deleted file mode 100644
index 30d36297..00000000
--- a/docs/product/circle/category_mgmt_web.md
+++ /dev/null
@@ -1,133 +0,0 @@
-# 管理频道分组
-
-
-
-环信超级社区(Circle)支持将多个频道归入一个频道分组,方便频道管理。例如,可将歌剧频道、民歌频道和流行歌曲频道划分为声乐频道分组。
-
-社区创建时会创建默认的频道分组,包含默认频道。
-
-**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:**
-
-**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。**
-**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。**
-**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_web.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。**
-**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_web.html#解散社区)和[删除频道](channel_mgmt_web.html#解散频道)等 API。**
-
-## 技术原理
-
-环信 Circle Android SDK 支持你通过调用 API 实现如下功能:
-
-- 创建和管理频道分组;
-- 监听频道分组事件。
-
-## 前提条件
-
-开始前,请确保满足以下条件:
-
-- 完成环信即时通讯 IM Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/initialization.html)。
-- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
-- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
-
-## 实现方法
-
-### 创建频道分组
-
-仅社区所有者可以调用 `createCategory` 方法创建频道分组。创建频道分组时需设置频道分组所属的社区 ID 和频道分组名称。频道分组创建后,社区所有成员(除创建者外)会收到 `onCategoryEvent` 回调,事件为 `create`。
-
-每个社区下最多可创建 50 个频道分组,超过需要联系商务。
-
-示例代码如下:
-
-```javascript
-let options = {
- serverId: 'serverId',
- name: 'categoryName',
-}
-WebIM.conn.createCategory(options).then(res => {
- console.log(res)
-})
-```
-
-### 修改频道分组名称
-
-仅社区所有者和管理员可调用 `updateCategory` 方法修改频道分组名称。频道分组名称修改后,社区所有成员(除操作者外)会收到 `onCategoryEvent` 回调,事件为 `update`。
-
-示例代码如下:
-
-```javascript
-let options = {
- serverId: 'serverId',
- categoryId: 'categoryId',
- name: 'categoryName',
-}
-WebIM.conn.updateCategory(options).then(res => {
- console.log(res)
-})
-```
-
-### 删除频道分组
-
-仅社区所有者可调用 `deleteCategory` 方法删除频道分组。社区所有成员(除操作者外)会收到 `onCategoryEvent` 回调,事件为 `destroy`。频道分组删除后,分组下的频道会移至当前社区的默认分组下。
-
-示例代码如下:
-
-```javascript
-WebIM.conn.deleteCategory({serverId: 'serverId', categoryId: 'categoryId',}).then(res => {
- console.log(res)
-})
-```
-
-### 分页获取社区下的频道分组列表
-
-社区中的所有成员可以调用 `getCategorylist` 方法获取社区下的频道分组列表。
-
-示例代码如下:
-
-```javascript
-WebIM.conn.getCategorylist({serverId: 'serverId',pageSize:'20',cursor:''}).then(res => {
- console.log(res)
-})
-```
-
-### 更换指定频道的频道分组
-
-仅社区所有者和管理员可以调用 `transferChannel` 方法将指定频道从一个频道分组转移至另一个频道分组。频道分组更换后,社区所有成员(除操作者外)会收到 `onCategoryEvent` 回调,事件为 `transferChannel`。
-
-:::tip
-调用该方法时,若 `newCategoryId` 参数传入 `null`、空字符串(``)或者不传,表示将频道归入社区默认的频道分组。
-:::
-
-示例代码如下:
-
-```javascript
-WebIM.conn.transferChannel({serverId: 'serverId',channelId: 'channelId',newCategoryId:'newCategoryId'}).then(res => {
- console.log(res)
-})
-```
-
-### 监听频道分组事件
-
-Circle 提供 `addEventHandler` 方法用于注册监听事件。开发者可以通过设置此监听,获取频道分组中的事件。
-
-```javascript
-WebIM.conn.addEventHandler('CIRCLE',{
- onServerEvent:(msg) => {
- switch (msg.operation){
- case "create":
- //创建频道分组。社区所有成员(除创建者外)会收到该事件。
- break;
- case "update":
- //修改了频道分组名称。社区所有成员(除创建者外)会收到该事件。
- break;
- case "destroy":
- //删除了频道分组。社区所有成员(除创建者外)会收到该事件。
- break;
- case "transferChannel":
- //频道更换了分组。社区所有成员(除创建者外)会收到该事件。
- break;
- default:
- break;
- }
- },
-});
-```
\ No newline at end of file
diff --git a/docs/product/circle/channel_mgmt_android.md b/docs/product/circle/channel_mgmt_android.md
deleted file mode 100644
index b609e7e3..00000000
--- a/docs/product/circle/channel_mgmt_android.md
+++ /dev/null
@@ -1,589 +0,0 @@
-# 管理频道
-
-
-
-频道(Channel)是一个社区下不同子话题的讨论分区,因此一个社区下可以有多个频道。社区创建时会自动创建默认频道,该频道中添加了所有社区成员,用于承载各种系统通知。从可见性角度看,频道社区分为公开和私密频道;从功能角度看,频道分为文字频道和语聊频道。社区创建者可以根据自己需求创建频道。
-
-**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:**
-
-**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。**
-**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。**
-**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。**
-**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_android.html#解散社区)和[删除频道](#解散频道)等 API。**
-
-## 技术原理
-
-环信 Circle Android SDK 提供 `EMCircleManager` 类和 `EMCircleChannel` 类用于频道管理,支持你通过调用 API 在项目中实现如下功能:
-
-- 创建和管理频道;
-- 管理频道成员;
-- 监听频道事件。
-
-## 前提条件
-
-开始前,请确保满足以下条件:
-
-- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/initialization.html)。
-- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。
-- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。
-
-## 实现方法
-
-本节介绍如何使用环信即时通讯 IM Android SDK 提供的 API 实现上述功能。
-
-### 创建和管理频道
-
-#### 创建频道
-
-1. 社区所有者可以调用 `createChannel` 方法在社区中创建公开或私密频道。参与频道创建的初始成员会收到 `EMCircleChannelListener#onChannelCreated` 事件。
-
-每个社区默认最多可创建 100 个频道。如需调整该阈值,请联系商务。
-
-示例代码如下:
-
-```java
-EMCircleChannelAttribute attribute = new EMCircleChannelAttribute();
- attribute.setName(name);
- attribute.setDesc(desc);
- attribute.setMaxUsers(2000);
- attribute.setType(EMCircleChannelStyle.EMChannelStylePublic);
-
-EMClient.getInstance().chatCircleManager().createChannel(serverId, categoryId, attribute, EMCircleChannelModeChat, new EMValueCallBack() {
-
- @Override
- public void onSuccess(EMCircleChannel value) {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
-});
-```
-
-创建频道时,需设置社区 ID、频道分组 ID、频道模式以及频道属性 `EMCircleChannelAttribute`,如下表所示。
-
-| 参数 | 类型 | 描述 | 是否必需 |
-| :--------- | :----------------------- | :------------------ |:------------------ |
-| serverId | String | 社区 ID。 | 是 |
-| categoryId | String | 频道分组 ID。 | 否 |
-| mode | EMCircleChannelMode | 频道模式:
- `EMCircleChannelModeChat`:文字频道;
- `EMCircleChannelModeVoice`:语聊频道。 | 是 |
-| EMCircleChannelAttribute.name | String | 频道名称,不超过 50 个字符。 | 是 |
-| EMCircleChannelAttribute.desc | String | 频道描述,不超过 500 个字符。 | 否 |
-| EMCircleChannelAttribute.maxUsers | Int | 频道最大成员数量:
- 对于语聊频道,该属性的取值范围为 [1,20],默认值为 `8`;
- 对于文字频道,该属性的取值范围为 [1,2000],默认值为 `2000`。 | 否 |
-| EMCircleChannelAttribute.type | EMCircleChannelStyle | 频道类型:
- (默认)`EMChannelStylePublic`:公开频道;
- `EMChannelStylePrivate`:私密频道。 | 否 |
-| EMCircleChannelAttribute.ext | String | 频道自定义扩展信息,不超过 500 个字符。 | 否 |
-| EMCircleChannelAttribute.rtcChannelId | String | RTC 频道 ID。该参数仅在创建语聊频道时需设置。若不设置,服务器使用创建的语聊频道的 ID 作为该参数的值返回。 | 否 |
-
-2. 邀请用户加入频道。
-
-社区中的用户可以自由加入社区下的公开频道,私密频道只能由频道成员邀请用户加入。
-
-频道创建者调用 `inviteUserToChannel` 方法邀请用户加入频道。受邀用户收到 `EMCircleChannelListener#onReceiveInvitation` 事件。
-
-```java
-EMClient.getInstance().chatCircleManager().inviteUserToChannel(serverId, channelId, inviteeUserId, "welcome", new EMCallBack() {
- @Override
- public void onSuccess() {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
- });
-```
-
-3. 受邀用户确认是否加入频道。
-
- - 用户调用 `acceptChannelInvitation` 方法同意加入频道,邀请人收到 `EMCircleChannelListener#onInvitationBeAccepted` 事件,频道所有成员(不包括该新加入的成员)收到 `EMCircleChannelListener#onMemberJoinedChannel` 事件。示例代码如下:
-
- ```java
- EMClient.getInstance().chatCircleManager().acceptChannelInvitation(serverId, channelId, inviterUserId, new EMValueCallBack() {
- @Override
- public void onSuccess(EMCircleChannel circleChannel) {
-
- }
-
- @Override
- public void onError(int code, String message) {
-
- }
- });
- ```
-
-- 用户调用 `declineChannelInvitation` 方法拒绝加入频道,邀请人收到 `EMCircleChannelListener#onInvitationBeDeclined` 事件。示例代码如下:
-
- ```java
- EMClient.getInstance().chatCircleManager().declineChannelInvitation(serverId,channelId, inviterUserId, new EMCallBack() {
- @Override
- public void onSuccess() {
-
- }
-
- @Override
- public void onError(int code, String message) {
-
- }
- });
- ```
-
-4. 用户加入频道后,可在频道中发送和接收消息。
-
-#### 修改频道信息
-
-仅社区所有者和管理员可调用 `updateChannel` 方法修改频道属性 `EMCircleChannelAttribute`,包括频道名称、类型(公开/私有)、描述、最大成员数量和自定义扩展信息。频道所有成员(除操作者外)会收到 `EMCircleChannelListener#onChannelUpdated` 事件。频道创建后,频道模式(文字或语聊)不能修改。
-
-若更换频道所属的频道分组,需调用 [transferChannel](category_mgmt_android.html#更换指定频道的频道分组)方法。
-
-示例代码如下:
-
-```java
-EMCircleChannelAttribute attribute = new EMCircleChannelAttribute();
- attribute.setName(name);
- attribute.setDesc(desc);
-
-EMClient.getInstance().chatCircleManager().updateChannel(serverId, channelId, attribute, new EMValueCallBack() {
-
- @Override
- public void onSuccess(EMCircleChannel value) {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
-});
-```
-
-#### 解散频道
-
-仅社区所有者可以调用 `destroyChannel` 方法解散社区中的频道。频道内其他成员收到 `EMCircleChannelListener#onChannelDestroyed` 事件并被移出频道。
-
-示例代码如下:
-
-```java
- EMClient.getInstance().chatCircleManager().destroyChannel(serverId, channelId, new EMCallBack() {
- @Override
- public void onSuccess() {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
-});
-```
-
-#### 获取频道详情
-
-社区成员可以调用 `fetchChannelDetail` 方法获取频道的详情。
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().fetchChannelDetail(serverId, channelId, new EMValueCallBack() {
- @Override
- public void onSuccess(EMCircleChannel value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
-});
-```
-
-#### 获取频道列表
-
-##### 获取社区的公开频道列表
-
-社区成员可以调用 `fetchPublicChannelsInServer` 方法获取社区下的所有公开频道的列表,示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().fetchPublicChannelsInServer(serverId, 20, null, new EMValueCallBack>() {
- @Override
- public void onSuccess(EMCursorResult value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
-});
-```
-
-##### 获取社区的私密频道列表
-
-社区成员可以调用 `fetchVisiblePrivateChannelsInServer` 方法获取社区下所有私密频道的列表。
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().fetchVisiblePrivateChannelsInServer(serverId, 20, null, new EMValueCallBack>() {
- @Override
- public void onSuccess(EMCursorResult value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
-});
-```
-
-##### 获取社区中加入的频道
-
-社区成员可以调用 `fetchJoinedChannelIdsInServer` 方法获取社区下加入的频道列表。
-
-```java
-EMClient.getInstance().chatCircleManager().fetchJoinedChannelIdsInServer(serverId, 20, null, new EMValueCallBack>() {
- @Override
- public void onSuccess(EMCursorResult value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
-});
-```
-
-##### 获取频道分组的公开频道列表
-
-社区成员可以调用 `fetchPublicChannelsInCategory` 方法获取频道分组下所有公开频道的列表,示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().fetchPublicChannelsInCategory(serverId, categoryId,20, null, new EMValueCallBack>() {
- @Override
- public void onSuccess(EMCursorResult value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
-});
-```
-
-##### 获取频道分组下的私密频道列表
-
-调用 `fetchPrivateChannelsInCategory` 方法获取频道分组下的所有私密频道的列表,示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().fetchPrivateChannelsInCategory(serverId, categoryId,20, null, new EMValueCallBack>() {
- @Override
- public void onSuccess(EMCursorResult value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
-});
-```
-
-### 发送消息
-
-在频道中发送消息与在群组中发送消息的方式类似,唯一的区别在于接收方需要设置为频道 ID。详见 [发送群聊消息](/document/android/message_send_receive.html)。
-
-### 管理频道成员
-
-#### 频道加人
-
-用户加入频道分为两种方式:主动申请和频道成员邀请。
-
-邀请用户加入频道,详见 [创建频道](#创建频道)。本节对用户申请加入频道进行详细介绍。
-
-只有公开频道支持用户申请加入,私有频道不支持。若申请加入公开频道,用户需执行以下步骤:
-
-1. 用户可获取社区下的[公开频道列表](#获取社区的公开频道列表)。
-
-2. 调用 `joinChannel` 方法传入社区 ID 和频道 ID,申请加入对应频道。用户加入频道后,频道所有成员(不包括该新加入的成员)会收到 `EMCircleChannelListener#onMemberJoinedChannel` 事件。
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().joinChannel(serverId, channelId, new EMValueCallBack() {
- @Override
- public void onSuccess(EMCircleChannel value) {
-
- }
-
- @Override
- public void onError(int error, String errorMsg) {
-
- }
-});
-```
-
-3. 用户加入频道后可以在频道中发送和接收消息。
-
-#### 退出频道
-
-##### 频道成员主动退出频道
-
-频道所有成员可调用 `leaveChannel` 方法退出频道。频道内的其他成员会收到 `EMCircleChannelListener#onMemberLeftChannel` 事件。退出频道的成员不会再收到频道消息。
-
-:::tip
-社区内的默认频道不允许成员主动退出。
-:::
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().leaveChannel(serverId, channelId, new EMCallBack() {
- @Override
- public void onSuccess() {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
-});
-```
-
-##### 频道成员被移出频道
-
-仅频道所有者和管理员可以调用 `removeUserFromChannel` 方法将指定成员移出频道。被移出的频道的成员会收到 `EMCircleChannelListener#onMemberRemovedFromChannel`事件,其他成员会收到 `EMCircleChannelListener#onMemberLeftChannel` 事件。被移出频道的成员不会再收到频道消息。
-
-:::tip
-社区内的默认频道不允许踢出成员。
-:::
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().removeUserFromChannel(serverId, channelId, userId, new EMCallBack() {
- @Override
- public void onSuccess() {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
-});
-```
-
-#### 将成员加入频道禁言列表
-
-社区所有者和社区管理员可以调用 `muteUserInChannel` 方法将频道成员加入禁言列表。被禁言的频道成员、社区所有者和管理员(除操作者外)会收到 `EMCircleChannelListener#onMemberMuteChanged` 事件。
-
-禁言列表中的成员无法在频道中发送消息,但可以接收频道中的消息。
-
-```java
-long muteDuration = 24 * 60 * 60 * 1000;//毫秒
-EMClient.getInstance().chatCircleManager().muteUserInChannel(serverId, channelId, username, muteDuration, new EMCallBack() {
- @Override
- public void onSuccess() {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
-});
-```
-
-#### 将成员移出频道禁言列表
-
-社区所有者和社区管理员可以调用 `unmuteUserInChannel` 方法,将频道禁言列表上的频道成员移出频道禁言列表。被移出禁言列表的频道成员、社区所有者和管理员(除操作者外)会收到 `EMCircleChannelListener#onMemberMuteChanged` 事件。频道成员被移出禁言列表后可在频道中正常发送和接收消息。
-
-示例代码如下:
-
-```java
-EMClient.getInstance().chatCircleManager().unmuteUserInChannel(serverId, channelId, username, new EMCallBack() {
- @Override
- public void onSuccess() {
-
- }
-
- @Override
- public void onError(int code, String error) {
-
- }
-});
-```
-
-#### 获取频道禁言列表
-
-社区所有者和社区管理员可以调用 `fetchChannelMuteUsers` 方法获取频道下的禁言列表。
-
-```java
-EMClient.getInstance().chatCircleManager().fetchChannelMuteUsers(serverId, channelId, new EMValueCallBack