随着观众、主播、开发者对RTC软件的要求越来越高,仅仅实现了一对一视频通话和多人聊天室的App纷纷失去了生存的土壤,越来越多的RTC App争先恐后加入了背景音乐、配音音效和美声变声功能,选择一个合适的第三方服务成了一个App 蒸蒸日上或者黯然失色的关键点。
声网Agora的SDK不但可以让App和网站实现高质量的音视频通话全互动直播,还能够通过背景音乐混动、美声变声实现丰富的声动互娱功能。我试着通过该SDK实现一个双人视频通话应用,来演示Agora声动互娱的简单使用。
快速集成
Agora的集成方式是傻瓜式的一键集成,只需要在project的build.gradle里进行如下配置:
dependencies {
……
implementation 'io.agora.rtc:full-sdk:4.1.1'
}
然后在module的build.gradle里进行如下配置:
buildscript {
repositories {
mavenCentral()
}
}
最后sync一下,声网Agora.io的SDK就集成到项目中来了。
SDK集成完毕后,为了保证SDK能正常运行,我们需要在AndroidManisfest.xml 文件中声明以下权限:
<!--允许程序连接网络-->
<uses-permission android:name="android.permission.INTERNET" />
<!--允许程序录制音频-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!--允许程序使用照相设备-->
<uses-permission android:name="android.permission.CAMERA" />
<!--允许程序修改全局音频设置-->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许对存储空间进行读写-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!--允许程序连接到已配对的蓝牙设备-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 对于 Android 12.0 及以上设备,还需要添加如下权限: -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
集成SDK并声明了权限后,就该考虑混淆的问题了,我们需要在project的文件里添加以下代码:
# 避免声网Agora SDK 的代码被混淆
-keep class io.agora.**{*;}
申请AppID和免费Token
Agora申请AppID和免费Token的入口在“Agora官网首页>控制台>项目管理”路径下,点击“新建项目”,就可以给你分配AppID
申请AppID是不需要应用包名的,因为不同包名的app可以互相通信,比如电商软件的商家端和买家端,直播软件的主播端和观众端等等。点击“生成临时Token”,就会生成一个有效期24小时的免费Token
基础功能(音视频聊天室)的快速开发
首先我们写一个布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http:///apk/res/android"
xmlns:app="http:///apk/res-auto"
xmlns:tools="http:///tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- 对方的预览画面铺满全屏 -->
<FrameLayout
android:id="@+id/remote_video_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" />
<!-- 本人的预览画面放在右上角 -->
<FrameLayout
android:id="@+id/local_video_view_container"
android:layout_width="160dp"
android:layout_height="320dp"
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>
然后把这一段代码,复制粘贴到你的MainActivity里:
private String appId = "刚才申请的appId";
private String token = "刚才申请的免费Token";
private String channelName = "HelloAgoraAdvanced";
private RtcEngine mRtcEngine;
private void setupRemoteVideo(int uid) {
FrameLayout container = findViewById(R.id.remote_video_view_container);
// 生成一个SurfaceView,并添加到布局文件中预览FrameLayout的子节点
SurfaceView surfaceView = new SurfaceView (getBaseContext());
surfaceView.setZOrderMediaOverlay(true);
container.addView(surfaceView);
// 显示对方的视图
mRtcEngine.setupRemoteVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid));
}
private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
@Override
// 监听频道内的其他用户,获取他的uid
public void onUserJoined(int uid, int elapsed) {
runOnUiThread(new Runnable() {
@Override
public void run() {
setupRemoteVideo(uid);
}
});
}
};
因为这是一个简单的demo,不需要做登录功能,启动时根据手机的OAID生成uid,这是因为Android Q以后的版本,Android禁止获取IMEI,所以作者本人用中国信通院联合华为、小米、OPPO、VIVO等厂商共同推出的设备识别字段OAID代替。这与本文内容无关,不多赘述。以下是初始化并加入频道的代码:
// 初始化并加入频道
// 这个方法在onCreate()和权限申请的回调中调用
// 实际开发建议在Application中异步初始化,然后打开聊天室Activity的时候加入频道
private void initializeAndJoinChannel() {
try {
// 配置参数
RtcEngineConfig config = new RtcEngineConfig();
config.mContext = getBaseContext();
config.mAppId = appId;
config.mEventHandler = mRtcEventHandler;
// 初始化核心类RtcEngine
mRtcEngine = RtcEngine.create(config);
} catch (Exception e) {
throw new RuntimeException("Check the error.");
}
// 启用视频流(视频默认禁用)
mRtcEngine.enableVideo();
// 开启本地视频预览。
mRtcEngine.startPreview();
FrameLayout container = findViewById(R.id.local_video_view_container);
// 创建一个 SurfaceView 对象,作为Framework的子节点
SurfaceView surfaceView = new SurfaceView (getBaseContext());
container.addView(surfaceView);
// 渲染本地视频。
// 你需要自行指定用户 ID,并确保其在频道内的唯一性。
mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, myAgoraUid));
ChannelMediaOptions options = new ChannelMediaOptions();
// 视频通话场景下,设置频道场景为 BROADCASTING。
options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
// 将用户角色设置为 BROADCASTER。
options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
// 使用临时 Token 加入频道。
mRtcEngine.joinChannel(token, channelName, myAgoraUid, options);
}
最后Override onDestory()方法的时候记得停止预览、退出频道,这样可以避免内存泄漏:
// Agora官方建议先退出频道,后停止本地预览
// 本人亲测两个方法调用先后顺序不影响GC结果
@Override
protected void onDestroy() {
super.onDestroy();
// 退出频道
mRtcEngine.leaveChannel();
// 停止本地预览
mRtcEngine.stopPreview();
}
接下来我们用两台手机测试一下效果,视频里主画面(我的正脸)是对方视角,副画面(我的侧脸)是本人视角
我们已经完成了Agora的基础功能的简单使用,接下来要进行Agora的声动互娱功能的学习。我们接下来学习的内容是如何使用背景音乐混动(AudioMixing)