功能简介
此示例演示了如何使用 SDK 加入频道进行音视频通话的功能
界面展示
API 调用时序图
在介绍实现音视频通话的具体代码之前,可参照下图对 API 的调用顺序建立基本概念。
对于一个完整的视频通话,一般将会包含以下几个流程:
- 初始化 RtcEngine
- 设置本地视图
- 加入频道
- 设置远端视图
- 离开频道
- 销毁 RtcEngine
代码路径
本节相关的实例代码请访问 src/main/java/io/agora/api/example/examples/basic/JoinChannelVideo.java
代码解析
初始化 RtcEngine
engine = RtcEngine.create(context.getApplicationContext(),
getString(R.string.agora_app_id), iRtcEngineEventHandler);
相关参数
参数 | 解释 |
---|---|
context | Android Activity 的 Context |
appID | App ID 是 Agora 为开发项目生成的字符串,是项目的唯一标识。从 Agora 的开发者后台获取:https://docs.agora.io/cn/Agora%20Platform/term_appid?platform=Android |
handler | IRtcEngineEventHandler 是一个提供默认实现的抽象类,SDK使用这个类来向应用程序报告SDK运行时的事件 |
设置本地视图
参考以下代码,对本地视图进行设置。
// Create render view by RtcEngine
// 通过 RtcEngine 创建渲染视图
SurfaceView surfaceView = RtcEngine.CreateRendererView(context);
if(fl_local.getChildCount() > 0)
{
fl_local.removeAllViews();
}
// Add to the local container
// 添加到本地容器
fl_local.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// Setup local video to render your local camera preview
// 设置本地视图来渲染本地摄像头预览
engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0));
// Set audio route to microPhone
// 将默认音频路由设置成听筒(如设置为 true,则音频路由为扬声器)
engine.setDefaultAudioRoutetoSpeakerphone(false);
设置 RtcEngine 的 Profile
根据你的使用场景,对 RtcEngine 的 Profile 进行设置,具体情况如下。
CHANNEL_PROFILE_COMMUNICATION(0): 通信场景(默认)
用于常见的一对一通话或群聊,频道中的任何用户可以自由说话。CHANNEL_PROFILE_LIVE_BROADCASTING(1): 直播场景
直播场景有主播和观众两种用户角色,可以通过 setClientRole 方法设置主播和观众的角色。主播可以收发语音/视频流,而观众只能接收语音/视频,无法发送。 ```java engine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);
engine.setClientRole(IRtcEngineEventHandler.ClientRole.CLIENT_ROLE_BROADCASTER); // Enable video module // 启用视频模块。在加入频道前调用,则自动开启视频模式,在通话中调用则由音频模式切换为视频模式。 engine.enableVideo();
<a name="ggHOL"></a>
### 配置 accessToken
请在 string_config 文件中配置 accessToken
- 在开发者控制台中生成的临时令牌。临时 Token 的有效期为24小时。详情请见:[https://docs.agora.io/cn/Agora%20Platform/token?platform=All%20Platforms#get-a-temporary-token](https://docs.agora.io/cn/Agora%20Platform/token?platform=All%20Platforms#get-a-temporary-token)
- 在服务器上生成 Token ,适用于有高安全要求的场景。详情请见:[https://docs.agora.io/cn/Video/token_server?platform=Android](https://docs.agora.io/cn/Video/token_server?platform=Android)
```java
String accessToken = getString(R.string.agora_access_token);
if (TextUtils.equals(accessToken, "") || TextUtils.equals(accessToken, "<#YOUR ACCESS TOKEN#>"))
{
accessToken = null;
}
加入频道
完成初始化和设置本地视图后(视频通话场景),你就可以调用 joinChannel 方法加入频道。
ChannelMediaOptions option = new ChannelMediaOptions();
option.autoSubscribeAudio = true;
option.autoSubscribeVideo = true;
int res = engine.joinChannel(accessToken, channelId, "Extra Optional Data", 0, option);
if (res != 0)
{
// Usually happens with invalid parameters
// Error code description can be found at:
// en: https://docs.agora.io/en/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_error_code.html
// cn: https://docs.agora.io/cn/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_error_code.html
showAlert(RtcEngine.getErrorDescription(Math.abs(res)));
return;
}
- autoSubscribeAudio/autoSubscribeVideo:设置是否自动订阅频道内所有远端音频/视频流。
调用 joinChannel 方法需要传入的参数包括:
参数 | 解释 |
---|---|
token | 可设为临时 Token 或者在你的服务器端生成的 Token 。 |
channelName | 标识通话的频道名称,长度在 64 字节以内的字符串。 |
optionalInfo | (非必选项)预留参数。 |
optionalUid | (非必选项)本地用户的 ID。数据类型为整型,且频道内每个用户的 uid 必须是唯一的。若将 uid 设为 0,则 SDK 会自动分配一个 uid,并在 onJoinChannelSuccess 回调中报告。用户成功加入频道后,会默认订阅频道内其他所有用户的音频流和视频流,因此产生用量并影响计费。如果想取消订阅,可以通过调用相应的 mute 方法实现。 |
设置远端视图
当远端用户加入频道,会触发 onUserJoined 回调,对此进行处理并进行远端视图的设置。
public void onUserJoined(int uid, int elapsed)
{
super.onUserJoined(uid, elapsed);
Log.i(TAG, "onUserJoined->" + uid);
showLongToast(String.format("user %d joined!", uid));
/**Check if the context is correct*/
/**检查 context 是否正确*/
Context context = getContext();
if (context == null) {
return;
}
if(remoteViews.containsKey(uid)){
return;
}
else{
handler.post(() ->
{
/**Display remote video stream*/
/**显示远端视频流*/
SurfaceView surfaceView = null;
// Create render view by RtcEngine
// 通过 RtcEngine 创建远端视图
surfaceView = RtcEngine.CreateRendererView(context);
surfaceView.setZOrderMediaOverlay(true);
ViewGroup view = getAvailableView();
remoteViews.put(uid, view);
// Add to the remote container
// 加入远端容器
view.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// Setup remote video to render
// 设置远端视图进行渲染
engine.setupRemoteVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, uid));
});
}
}
离开频道
根据场景需要,如结束通话、关闭 App 或 App 切换至后台时,调用 leaveChannel 离开当前通话频道。
public void onDestroy()
{
super.onDestroy();
/**leaveChannel and Destroy the RtcEngine instance*/
/**离开频道并销毁 RtcEngine 实例*/
if(engine != null)
{
engine.leaveChannel();
}
handler.post(RtcEngine::destroy);
engine = null;
}