====== Android 访客端demo集成说明(含UI设计) ====== ==== 代码下载 ==== 您可以通过以下两种方式获取到源代码: * 下载代码压缩包:客服云sdk 及 Demo 下载 http://www.easemob.com/download/cs * 下载源代码:github源码地址 https://github.com/easemob/kefu-android-demo ==== 项目集成:详细内容参考demo ==== **app模块主体类介绍:** * LoginActivity:处理登录相关的逻辑,必须先登录环信服务器获取相关信息 * SettingFragment:通过扫码配置appkey相关信息 * CallActivity:视频通话页面 * CallReceiver:用于接收视频邀请相关的信令 * DemoApplication:继承Application类,需要在AndroidManifest.xml内指定 * DemoHelper:初始化相关信息配置和注册 * HMSPushHelper:配置华为HMS推送相关的工具类 **kefu-easeui模块主体类介绍:** * ChatFragment:聊天界面,app也可继承此fragment续写,参数传入示例可查看demo里的ChatActivity * AgoraRtcEngine:音视频通话相关(基于声网sdk) ==== 主要功能介绍 ==== kefu-easeui模块:包含聊天、图片、表情、音视频相关内容的输入选择,可以实现自定义 音视频(基于声网音视频服务,使用环信 IM 作为信令通道的开源音视频模块) **相关音视频api介绍及使用如下:** 创建视频引擎AgoraRtcEngine /** * 创建视频数据 * @param context Context * @param appId String * @param handler IAgoraRtcEngineEventHandler */ AgoraRtcEngine engine = AgoraRtcEngine.builder() .addVideoWatermark() // 该方法将一张 PNG 图片作为水印添加到本地发布的直播视频流上 .setVideoEncodingDimension() // 视频编码像素。参数使用查看SDK里方法注解 .setVideoEncoderConfiguration() // 视频编码属性的定义。参数使用查看SDK里方法注解 .setRenderMode() // 设置视频渲染模式。参数使用查看SDK里方法注解 .setMirrorMode() // 设置视频镜像模式。参数使用查看SDK里方法注解 .setClientRole() // 设置直播场景下的用户角色。参数使用查看SDK里方法注解 .setChannelProfile() // 设置频道场景。参数使用查看SDK里方法注解 .build(getApplication(), "appid", new IAgoraRtcEngineEventHandler() { @Override public void onUserJoined(int uid, int elapsed) { // 有人员加入时回调 } @Override public void onJoinChannelSuccess(String channel, int uid, int elapsed) { // 自己加入成功时回调 } @Override public void onLeaveChannel(RtcStats stats) { // 离开channel时回调 } @Override public void onUserOffline(int uid, int reason) { // 人员离开时回调 } }); /** * 创建 RendererView视图 * * 请在主线程调用该方法 * @return SurfaceView */ engine.createRendererView(); engine.createRendererView(Context context); /** * 初始化远端用户视图 * * 如果 App 不能事先知道对方的用户 ID,可以在 APP 收到 onUserJoined 事件时设置。 * 如果启用了视频录制功能,视频录制服务会做为一个哑客户端加入频道,因此其他客户端也会收到它的 onUserJoined 事件, * App 不应给它绑定视图(因为它不会发送视频流),如果 App 不能识别哑客户端,可以在 onFirstRemoteVideoDecoded 事件时再绑定视图。 * 解除某个用户的绑定视图可以把 view 设置为空。退出频道后,SDK 会把远程用户的绑定关系清除掉。 * 注意:请在主线程调用该方法。如果你希望在通话中更新远端用户的渲染或镜像模式,请使用 setRemoteRenderMode 方法 * 如果你希望在通话中更新远端用户的渲染或镜像模式,请使用 setRemoteRenderMode 方法 * @param videoCanvas VideoCanvas * @return 0: 方法调用成功。小于 0: 方法调用失败。 */ engine.setupRemoteVideo(VideoCanvas videoCanvas); engine.setupRemoteVideo(View surfaceView, int uid) /** * 更新远端视图显示模式 * * @param uid uid * @param renderMode 详细说明查看setRenderMode()方法注解 * @param mirrorMode 详细说明查看setMirrorMode()方法 * @return 0: 方法调用成功。小于 0: 方法调用失败。 */ engine.setRemoteRenderMode(int uid, int renderMode, int mirrorMode); /** * 启用视频模块 * * 该方法用于打开视频模式。可以在加入频道前或者通话中调用,在加入频道前调用,则自动开启视频模式,在通话中调用则由音频模式切换为视频模式。调用 disableVideo 方法可关闭视频模式。 * 成功调用该方法后,远端会触发 onUserEnableVideo(true) 回调 * 该方法设置的是内部引擎为开启状态,在频道内和频道外均可调用,且在 leaveChannel 后仍然有效。 * 该方法重置整个引擎,响应速度较慢,因此 Agora 建议使用如下方法来控制视频模块: * enableLocalVideo:是否启动摄像头采集并创建本地视频流 * muteLocalVideoStream:是否发布本地视频流 * muteRemoteVideoStream:是否接收并播放远端视频流 * muteAllRemoteVideoStreams:是否接收并播放所有远端视频流 * @return 0: 方法调用成功。小于 0: 方法调用失败 */ engine.enableVideo(); /** * 关闭视频模块 * * 该方法用于关闭视频。可以在加入频道前或者通话中调用,在加入频道前调用,则自动开启纯音频模式,在通话中调用则由视频模式切换为纯音频频模式。调用 enableVideo 方法可开启视频模式。 * 成功调用该方法后,远端会触发 onUserEnableVideo(false) 回调。 * 该方法设置的是内部引擎为禁用状态,在频道内和频道外均可调用,且在 leaveChannel 后仍然有效。 * 该方法重置整个引擎,响应速度较慢,因此 建议使用如下方法来控制视频模块: * enableLocalVideo:是否启动摄像头采集并创建本地视频流 * muteLocalVideoStream:是否发布本地视频流 * muteRemoteVideoStream:是否接收并播放远端视频流 * muteAllRemoteVideoStreams:是否接收并播放所有远端视频流 * @return 0: 方法调用成功。小于 0: 方法调用失败 */ engine.disableVideo(); /** * 启用音频模块(默认为开启状态) * * 该方法设置的是音频模块为开启状态,在频道内和频道外均可调用,且在 leaveChannel 后仍然有效 * 该方法开启整个音频模块,响应速度较慢,因此建议使用如下方法来控制音频模块: * enableLocalAudio:是否启动麦克风采集并创建本地音频流。 * muteLocalAudioStream:是否发布本地音频流。 * muteRemoteAudioStream:是否接收并播放远端音频流。 * muteAllRemoteAudioStreams:是否接收并播放所有远端音频流。 * @return 0: 方法调用成功。小于 0: 方法调用失败 */ engine.enableAudio(); /** * 关闭音频模块 * * 该方法设置的是音频模块为禁用状态,在频道内和频道外均可调用,且在 leaveChannel 后仍然有效 * 该方法关闭整个音频模块,响应速度较慢,因此建议使用如下方法来控制音频模块 * enableLocalAudio:是否启动麦克风采集并创建本地音频流。 * muteLocalAudioStream:是否发布本地音频流。 * muteRemoteAudioStream:是否接收并播放远端音频流。 * muteAllRemoteAudioStreams:是否接收并播放所有远端音频流。 * @return 0: 方法调用成功。小于 0: 方法调用失败 */ engine.disableAudio(); /** * 开启/关闭本地音频采集。 * * 当 app 加入频道时,它的语音功能默认是开启的。该方法可以关闭或重新开启本地语音,即停止或重新开始本地音频采集 * 该方法不影响接收远端音频流,enableLocalAudio(false) 适用于只听不发的用户场景。 * 语音功能关闭或重新开启后,会收到回调 onLocalAudioStateChanged ,并报告 LOCAL_AUDIO_STREAM_STATE_STOPPED(0) 或 LOCAL_AUDIO_STREAM_STATE_CAPTURING(1) * 该方法与 muteLocalAudioStream 的区别在于: * enableLocalAudio 开启或关闭本地语音采集及处理。使用 enableLocalAudio 关闭或开启本地采集后,本地听远端播放会有短暂中断。 * muteLocalAudioStream 停止或继续发送本地音频流。 * @param enabled 是否开启 * @return 0: 方法调用成功。小于 0: 方法调用失败。 */ engine.enableLocalAudio(boolean enabled); /** * 取消或恢复订阅指定远端用户的音频流 * * 该方法需要在加入频道后调用 * @param uid 指定用户的用户 ID * @param muted 是否取消订阅指定远端用户的音频流,true:取消订阅。false:(默认)订阅 * @return 0: 方法调用成功。小于 0: 方法调用失败 */ engine.muteRemoteAudioStream(int uid, boolean muted); /** * 取消或恢复订阅所有远端用户的音频流 * * 成功调用该方法后,本地用户会取消或恢复订阅所有远端用户的音频流,包括在调用该方法后加入频道的用户的音频流 * @param muted 是否取消订阅所有远端用户的音频流。true: 取消订阅。false:(默认)订阅 * @return 0: 方法调用成功。小于 0: 方法调用失败 */ engine.muteAllRemoteAudioStreams(boolean muted); /** * 取消或恢复发布本地音频流 * * 该方法仅设置用户在 RtcChannel 频道中的音频发布状态。 * 成功调用该方法后,远端会触发 onRemoteAudioStateChanged 回调。 * 同一时间,本地的音视频流只能发布到一个频道。如果你创建了多个频道,请确保你只在一个频道中调用 muteLocalAudioStream(false),否则方法会调用失败并返回 -5 (ERR_REFUSED)。 * @param muted 是否取消发布本地音频流,true:取消发布,false:发布 * @return 0: 方法调用成功。小于 0: 方法调用失败。-5 (ERR_REFUSED):调用被拒绝 */ engine.muteLocalAudioStream(boolean muted); /** * 开启/关闭扬声器播放 * * 你可以调用 setEnableSpeakerphone 切换当前的音频路由。 成功切换音频路由后,SDK 会触发 onAudioRouteChanged 回调提示音频路由已更改。 * 该方法只设置用户在当前频道内使用的音频路由,不会影响 SDK 默认的音频路由。 如果用户离开当前频道并加入新的频道,则用户还是会使用 SDK 默认的音频路由 * 该方法需要在 joinChannel 后调用。 * 如果用户使用了蓝牙耳机、有线耳机等外接音频播放设备,则该方法的设置无效,音频只会通过外接设备播放。当有多个外接设备时,音频会通过最后一个接入的设备播放。 * @param enabled 设置是否开启扬声器播放,true:开启。音频路由为扬声器。false:关闭。音频路由为听筒。 * @return 0:方法调用成功。小于 0:方法调用失败 */ engine.setEnableSpeakerphone(boolean enabled); /** * 取消或恢复发布本地视频流。 * * 成功调用该方法后,远端会触发 onUserMuteVideo 回调。 * 同一时间,本地的音视频流只能发布到一个频道。如果你创建了多个频道,请确保你只在一个频道中调用 muteLocalVideoStream(false), 否则方法会调用失败并返回 -5 (ERR_REFUSED)。 * 该方法不会改变视频采集设备的使用状态。该方法的调用是否生效受 joinChannel 和 setClientRole 方法的影响 * @param muted 是否取消发布本地视频流。true:取消发布。false:发布。 * @return 0:方法调用成功。小于 0:方法调用失败。-5 (ERR_REFUSED):调用被拒绝 */ engine.muteLocalVideoStream(boolean muted); /** * 切换前置/后置摄像头。 * * 该方法需要在相机启动(如通过调用 startPreview 或 joinChannel 实现)后调用。 * @return 0: 方法调用成功。小于 0: 方法调用失败。 */ engine.switchCamera(); /** * 使用 uid 加入频道 * * 该方法不支持相同的用户重复加入同一个频道,如果想要从不同的设备同时接入同一个频道,请确保每个设备上使用的 UID 是不同的 * 请确保用于生成 Token 的 App ID 和创建 IRtcEngine 对象时用的 App ID 一致 * @param token 在 app 服务端生成的用于鉴权的 Token * @param channelName 要加入的渠道名 * @param optionalUid 用户 ID,32 位无符号整数。建议设置范围:1 到 (232-1),并保证唯一性。如果不指定(即设为 0),SDK 会自动分配一个, 并在 onJoinChannelSuccess 回调方法中返回,App 层必须记住该返回值并维护,SDK 不对该返回值进行维护 * @return 0:调用成功,小于 0:方法调用失败 * 调用失败将返回如下: * ERR_INVALID_ARGUMENT(-2) * ERR_NOT_READY(-3) * ERR_REFUSED(-5) * ERR_NOT_INITIALIZED(-7) * ERR_JOIN_CHANNEL_REJECTED(-17):加入频道被拒绝。由于 SDK 不支持用户重复加入同一个 RtcChannel 频道, 当已经加入某个 RtcChannel 频道的用户再次调用该 RtcChannel 对象的加入频道方法时,会返回此错误码 */ engine.joinChannel(String token, String channelName, int optionalUid); /** * 使用 uid 加入频道 * * 该方法不支持相同的用户重复加入同一个频道,如果想要从不同的设备同时接入同一个频道,请确保每个设备上使用的 UID 是不同的 * 请确保用于生成 Token 的 App ID 和创建 IRtcEngine 对象时用的 App ID 一致 * @param token 在 app 服务端生成的用于鉴权的 Token * @param channelName 要加入的渠道名 * @param optionalInfo 开发者需加入的任何附加信息。一般可设置为空字符串,或频道相关信息。该信息不会传递给频道内的其他用户。 * @param optionalUid 用户 ID,32 位无符号整数。建议设置范围:1 到 (232-1),并保证唯一性。如果不指定(即设为 0),SDK 会自动分配一个, 并在 onJoinChannelSuccess 回调方法中返回,App 层必须记住该返回值并维护,SDK 不对该返回值进行维护 * @param options 频道媒体设置选项:ChannelMediaOptions * @return 0:调用成功,小于 0:方法调用失败 * 调用失败将返回如下: * ERR_INVALID_ARGUMENT(-2) * ERR_NOT_READY(-3) * ERR_REFUSED(-5) * ERR_NOT_INITIALIZED(-7) * ERR_JOIN_CHANNEL_REJECTED(-17):加入频道被拒绝。由于 SDK 不支持用户重复加入同一个 RtcChannel 频道, 当已经加入某个 RtcChannel 频道的用户再次调用该 RtcChannel 对象的加入频道方法时,会返回此错误码 */ engine.joinChannel(String token, String channelName, String optionalInfo, int optionalUid, ChannelMediaOptions options); /** * 离开当前频道 * * 成功调用该方法离开频道后,会触发如下回调: * 本地:onLeaveChannel. * 远端:通信场景下的用户和直播场景下的主播离开频道后,触发 onUserOffline。 * @return 0:方法调用成功。小于 0:方法调用失败 */ engine.leaveChannel(); 接听通话 /** * 接听通话 */ engine.joinChannel(String token, String channelName, int uid) 发起视频通话 /** * 发起视频通话 * @param chatInviteShoe msg内容 * @param toChatUsername IM服务号 */ ChatClient.getInstance().callManager().callVideo(String chatInviteShoe, String toChatUsername); 拒绝接听 /** * 拒接视频 * @param callId callId * @param isConnected 是否已接通,false未接通 */ ChatClient.getInstance().callManager().endCall(int callId, boolean isConnected); 拒绝接听 /** * 挂断视频 * @param callId callId * @param isConnected 是否已接通,true接通 */ ChatClient.getInstance().callManager().endCall(int callId, boolean isConnected); 音视频(基于声网音视频服务,使用环信 IM 作为信令通道的开源音视频模块)相关详细方法及参数说明参考声网api地址:https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/index.html