实时视频通话能够拉近人与人之间的距离,为用户提供沉浸式的交流体验,帮助你的 app 提高用户黏性。
本文介绍如何通过少量代码集成声网视频 SDK ,在你的 app 里实现高质量、低延迟的视频通话功能。
下图展示在 app 中实现声网视频通话的基本工作流程:
实现视频通话的步骤如下:
1. 设置角色
将用户角色均设置为主播。
2. 加入频道
调用 joinChannel
创建并加入频道。在 App ID 一致的前提下,传入相同频道名的用户会进入同一个频道。
3、4. 在频道内发布和订阅音视频
加入频道后,两位主播可以发布音视频并互相订阅。
按照以下步骤准备开发环境:
如需创建新项目,在 Android Studio 里,依次选择 Phone and Tablet > Empty Activity,创建 Android 项目。
使用 Maven Central 将声网视频 SDK 集成到你的项目中。
a. 在 /Gradle Scripts/build.gradle(Project: <projectname>)
文件中添加如下代码,添加 Maven Central 依赖:
buildscript {
repositories {
...
mavenCentral()
}
...
}
allprojects {
repositories {
...
mavenCentral()
}
}
b. 在 /Gradle Scripts/build.gradle(Module: <projectname>.app)
文件中添加如下代码,将声网视频 SDK 集成到你的 Android 项目中:
...
dependencies {
...
// x.y.z,请填写具体的 SDK 版本号,如:4.0.0 或 4.0.0.4。
// 通过发版说明获取最新版本号。
implementation 'io.agora.rtc:full-sdk:x.y.z'
}
添加网络及设备权限。
在 /app/Manifests/AndroidManifest.xml
文件中,在 </application>
后面添加如下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 对于 Android 12.0 及以上设备,还需要添加如下权限: -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
在 /Gradle Scripts/proguard-rules.pro
文件中添加如下行,以防止声网 SDK 的代码被混淆:
-keep class io.agora.**{*;}
本节介绍如何使用声网视频 SDK 在你的 app 里实现视频通话。
视频通话的用户界面中,通常有两个视图框,分别用于展示本地视频和远端视频。在 /app/res/layout/activity_main.xml
文件中,用如下代码进行替换:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/local_video_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" />
<FrameLayout
android:id="@+id/remote_video_view_container"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
android:background="@android:color/darker_gray"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
本节介绍如何导入所需的 Android 相关的类,获取 Android 权限。
导入 Android 相关的类。
在 /app/java/com.example.<projectname>/MainActivity
文件中,在 package com.example.<projectname>
后添加如下代码:
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.view.SurfaceView;
import android.widget.FrameLayout;
获取 Android 权限。
启动应用程序时,检查是否已在 app 中授予了实现视频通话所需的权限。如果未授权,使用内置的 Android 功能申请权限;如果已授权,则返回 true
。
在 /app/java/com.example.<projectname>/MainActivity
文件中,在 onCreate
函数前添加如下代码:
private static final int PERMISSION_REQ_ID = 22;
private static final String[] REQUESTED_PERMISSIONS = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA
};
private boolean checkSelfPermission(String permission, int requestCode) {
if (ContextCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
return false;
}
return true;
}
视频通话的 API 使用时序见下图:
按照以下步骤实现该逻辑:
导入声网相关的类。
在 /app/java/com.example.<projectname>/MainActivity
文件中,在 import android.os.Bundle;
后加入如下代码:
import io.agora.rtc2.Constants;
import io.agora.rtc2.IRtcEngineEventHandler;
import io.agora.rtc2.RtcEngine;
import io.agora.rtc2.RtcEngineConfig;
import io.agora.rtc2.video.VideoCanvas;
import io.agora.rtc2.ChannelMediaOptions;
创建变量,用于创建和加入频道。
在 /app/java/com.example.<projectname>/MainActivity
文件中,在 AppCompatActivity {
后加入如下代码:
// 填写项目的 App ID,可在声网控制台中生成。
private String appId = "";
// 填写频道名称。
private String channelName = "";
// 填写声网控制台中生成的临时 Token。
private String token = "";
private RtcEngine mRtcEngine;
private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
@Override
// 监听频道内的远端主播,获取主播的 uid 信息。
public void onUserJoined(int uid, int elapsed) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// 从 onUserJoined 回调获取 uid 后,调用 setupRemoteVideo,设置远端视频视图。
setupRemoteVideo(uid);
}
});
}
};
初始化 app 并加入频道。
在 MainActivity
类中,调用核心方法加入频道,输入你的 App ID、频道名以及临时 Token。
在如下示例代码中,核心方法封装于 initializeAndJoinChannel
函数中。
private void initializeAndJoinChannel() {
try {
RtcEngineConfig config = new RtcEngineConfig();
config.mContext = getBaseContext();
config.mAppId = appId;
config.mEventHandler = mRtcEventHandler;
mRtcEngine = RtcEngine.create(config);
} catch (Exception e) {
throw new RuntimeException("Check the error.");
}
// 视频默认禁用,你需要调用 enableVideo 启用视频流。
mRtcEngine.enableVideo();
// 开启本地视频预览。
mRtcEngine.startPreview();
FrameLayout container = findViewById(R.id.local_video_view_container);
// 创建一个 SurfaceView 对象,并将其作为 FrameLayout 的子对象。
SurfaceView surfaceView = new SurfaceView (getBaseContext());
container.addView(surfaceView);
// 将 SurfaceView 对象传入声网,以渲染本地视频。
mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, 0));
ChannelMediaOptions options = new ChannelMediaOptions();
// 视频通话场景下,设置频道场景为 BROADCASTING。
options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
// 将用户角色设置为 BROADCASTER。
options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
// 使用临时 Token 加入频道。
// 你需要自行指定用户 ID,并确保其在频道内的唯一性。
mRtcEngine.joinChannel(token, channelName, 0, options);
}
当远端用户加入频道时添加远端视频。
在 /app/java/com.example.<projectname>/MainActivity
文件中,在 initializeAndJoinChannel
函数后加入如下代码:
private void setupRemoteVideo(int uid) {
FrameLayout container = findViewById(R.id.remote_video_view_container);
SurfaceView surfaceView = new SurfaceView (getBaseContext());
surfaceView.setZOrderMediaOverlay(true);
container.addView(surfaceView);
mRtcEngine.setupRemoteVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid));
}
至此,你已经成功在你的 app 中添加了视频通话功能。当用户启动你的 app 时,视频通话开始;当用户关闭 app 时,视频通话结束。
检查 app 是否有正确的权限。如果已授予权限,调用 initializeAndJoinChannel
加入频道。
在 /app/java/com.example.<projectname>/MainActivity
文件中,用如下代码替换 onCreate
。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 如果已经授权,则初始化 RtcEngine 并加入频道。
if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID)) {
initializeAndJoinChannel();
}
}
关闭 app 或 app 切换至后台时,调用 leaveChannel
离开当前频道即可,以释放所有会话相关的资源。在 /app/java/com.example.<projectname>/MainActivity
文件中,添加如下代码。
destroy
清理你在 initializeAndJoinChannel
函数中创建的所有资源。 mRtcEngine.stopPreview();
mRtcEngine.leaveChannel();
按照以下步骤测试 app:
Run 'app'
。片刻后,项目便会安装到你的设备上。在测试或生产环境中,为保证通信安全,声网推荐从服务器中获取 Token,详情请参考使用 Token 鉴权。
本节提供了额外的信息供参考。
在 SDK 下载页面下载最新版本的声网视频 SDK ,并解压。
打开解压文件,将以下文件或子文件夹复制到你的项目路径中。
文件或子文件夹 | 项目路径 |
---|---|
agora-rtc-sdk.jar 文件 |
/app/libs/ |
arm64-v8a 文件夹 |
/app/src/main/jniLibs/ |
armeabi-v7a 文件夹 |
/app/src/main/jniLibs/ |
x86 文件夹 |
/app/src/main/jniLibs/ |
x86_64 文件夹 |
/app/src/main/jniLibs/ |
high_level_api 中的include 文件夹 |
/app/src/main/jniLibs/ |
Project Files/app/libs/agora-rtc-sdk.jar
文件,右键单击,选择 add as a library
。声网在 GitHub 上提供了一个开源的视频通话示例项目 JoinChannelVideo 供你参考。