通信集成指南—— Android
简介
本文档主要介绍使用 JusTalk Cloud SDK for Android(以下简称 SDK)实现基本的音频或视频通信功能的调用逻辑。请根据需要集成其他扩展功能。
本文涉及的接口类和对象有:
- JCEngine:SDK 接口类。
- JCParticipant:成员对象类。
- JCRoomInfo:房间对象类。
房间对象
房间对象包括房间信息、状态和参与成员信息。
房间
房间是通信的基础,当第一个成员进入房间时,自动创建。最后一个成员离开时,自动销毁。
成员
成员分为参与者和观察者。
- 参与者:即可以参与交互的成员。一个房间中参与者人数可以多达16人。
- 观察者:即仅能观看的普通成员。一个房间的观察者人数可以多达500名。参与者和观察者可以互相转化,但参与者最多不超过 16 人。
交互说明
SDK 封装了来自服务器的通知和异步执行的用户操作结果通知,开发者在初始化 SDK 时设置 JCEngineEventHandler
,SDK 会通过触发 JCEngineEventHandler
回调来通知事件。
eventHandler = new MyEventHandler();
mJCEngine = JCEngine.create(context.getApplicationContext(), MY_APP_KEY, eventHandler);
// state == JCEngine.STATE_INIT 表示初始化成功
int state = mJCEngine.getState();
private static class MyEventHandler implements JCEngineEventHandler {
...
// 回调实现
...
}
初始化时设置 JCEngineEventHandler
。具体回调信息请参考 SDK API Reference。
通信
加入房间
加入房间前,需要定义一个 roomId 作为该实例的唯一标识。在多个设备上使用同一个 AppKey 初始化 SDK,并使用同一个 roomId,即可加入同一个房间。
1.调用加入房间接口。加入房间接口为异步调用,调用后等待 eventHandler 回调:
int ret = mJCEngine.joinRoom(roomId, displayName);
2.处理回调:
private static class MyEventHandler implements JCEngineEventHandler {
...
void onJoinRoomSuccess() {
// 加入成功
}
void onError(int errorCode) {
switch (errorCode) {
case JCEngine.ERROR_JOIN_FAIL_BUSY:
case JCEngine.ERROR_JOIN_FAIL_INVALID_ROOM_ID:
case JCEngine.ERROR_JOIN_FAIL_NET_UNAVAILABLE:
case JCEngine.ERROR_JOIN_FAIL_TIMEOUT:
case JCEngine.ERROR_JOIN_FAIL_FULL:
case JCEngine.ERROR_JOIN_FAIL_CONNECT:
case JCEngine.ERROR_JOIN_FAIL_OTHER:
// 加入失败
}
...
}
3.音频
SDK 默认不发送音频,但会接受并播放其他成员的音频,您可以关闭声音外放:
mJCEngine.enableAudioOutput(false);
您也可以根据后续章节介绍,开启发送音频。
离开房间
离开房间只需调用离开接口,如下。您必须先离开房间才能加入下一个房间。
1.调用离开接口。离开接口为异步调用,调用后等待回调。
mJCEngine.leave();
2.处理回调: 主动调用离开接口或者被动离开房间都会收到此回调。
private static class MyEventHandler implements JCEngineEventHandler {
...
void onLeftRoom(int reason) {
// 离开房间。
// reason:离开原因。
}
...
}
成员变化
加入房间后,您可以调用以下接口获取房间中的成员列表:
ArrayList<JCParticipant> list = mJCEngine.getParticipants();
成员发生变化时都会触发成员变化相关回调。
private static class MyEventHandler implements JCEngineEventHandler {
...
void onParticipantJoin(String userId) {
// 成员加入
}
void onParticipantLeft(String userId, int reason) {
// 成员离开
}
void onParticipantUpdated(String userId) {
// 成员变化
}
...
}
打开/关闭摄像头
调用打开摄像头接口以打开摄像头:
mJCEngine.startCamera();
默认情况下,SDK 会打开前置摄像头,您可以在调用打开摄像头接口之前设置默认摄像头。
// 参数为是否前置摄像头,摄像头采集分辨率
mJCEngine.setupCapture(isFront, JCEngine.RESOLUTION_360);
调用关闭摄像头接口,即可关闭摄像头:
mJCEngine.stopCamera();
渲染本地预览
完成打开摄像头后,您可以开始渲染本地预览。 1.准备界面布局: 您可以预先在界面布局中留出视频渲染位置,也可以在界面上动态添加。以预先留出位置为例:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/video_container"
android:layout_width="100dp"
android:layout_height="100dp" />
</RelativeLayout >
2.开始渲染
在界面代码中找到 View,并参考以下示例添加渲染控件,并开始渲染:
FrameLayout layout = findViewById(R.id.video_container);
SurfaceView surfaceView = ZmfVideo.renderNew(getApplicationContext());
layout.addView(surfaceView);
mJCEngine.startRender(surfaceView, userId, ZmfVideo.RENDER_FULL_CONTENT);
3.停止渲染
需要停止渲染视频时,参考以下示例停止渲染并释放控件:
mJCEngine.stopRender(surfaceView);
layout.removeView(surfaceView);
订阅成员视频
默认情况下,SDK 不会接收其他成员的视频,您需要根据实际需求和成员状态决定是否订阅视频及视频大小。 1.订阅成员视频:
JCParticipant partp = mJCEngine.getParticipant(userId);
if (partp.hasVideo()) {
mJCEngine.requestVideo(userId, JCEngine.PICTURE_SIZE_LARGE);
}
2.取消订阅
mJCEngine.cancelVideoRequest(userId, JCEngine.PICTURE_SIZE_LARGE);
渲染成员视频
在渲染成员视频前,您需要订阅成员视频,以获取该成员的视频流。不要忘记停止渲染后需要取消成员视频的订阅。
1.准备界面布局: 您可以预先在界面布局中留出视频渲染位置,也可以在界面上动态添加。以预先留出位置为例:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/video_container"
android:layout_width="100dp"
android:layout_height="100dp" />
</RelativeLayout >
2.开始渲染
在界面代码中找到 View,并参考以下示例添加渲染控件,并开始渲染:
FrameLayout layout = findViewById(R.id.video_container);
SurfaceView surfaceView = ZmfVideo.renderNew(getApplicationContext());
layout.addView(surfaceView);
mJCEngine.startRender(surfaceView, userId, ZmfVideo.RENDER_FULL_CONTENT);
3.停止渲染
需要停止渲染视频时,参考以下示例停止渲染并释放控件:
mJCEngine.stopRender(surfaceView);
layout.removeView(surfaceView);
发送音频
加入房间后,默认是关闭语音发送的,此时房间中的其它成员是听不到该成员的声音。需要如下操作来开始发送音频数据。
1.调用打开/关闭音频发送接口
mJCEngine.enableLocalAudioStream(enable);
2.监听成员变化通知,关注自己的 onParticipantUpdated
成员状态变化。
private static class MyEventHandler implements JCEngineEventHandler {
...
void onParticipantUpdated(String userId) {
// 成员变化
if(JCUtils.isSelf(userId)) {
JCParticipant self = mJCEngine.getParticipant(userId);
if (self.hasAudio()) {
// 音频发送打开
} else {
// 音频发送关闭(失败)
}
}
}
...
}
发送视频
加入房间后,默认是关闭视频发送的,此时房间中的其它成员是订阅不到该成员的视频。需要如下操作来开始发送视频数据。
1.调用打开/关闭视频发送接口
mJCEngine.enableLocalVideoStream(enable);
2.监听成员变化通知,关注自己的 onParticipantUpdated
成员状态变化。
private static class MyEventHandler implements JCEngineEventHandler {
...
void onParticipantUpdated(String userId) {
// 成员变化
if(JCUtils.isSelf(userId)) {
JCParticipant self = mJCEngine.getParticipant(userId);
if (self.hasVideo()) {
// 视频发送打开
} else {
// 视频发送关闭(失败)
}
}
}
...
}