共计 9337 个字符,预计需要花费 24 分钟才能阅读完成。
1. 简介
在现在的挪动互联网时代,音视频相干利用曾经深刻到咱们日常生活的方方面面。
而在它背地的音视频技术也是十分成熟了,短视频编辑、带货直播、视频语音通话等利用模式无不体现着音视频技术给咱们生存带来的便当。
而这次就去理论体验一下,接入声网的音频 SDK,并打造一个音视频通话利用。
2. 账户注册与我的项目创立
首先要做的就是在声网(https://www.agora.io/cn)上注册账号,并实现实名认证。
登录之后就进到治理界面了,在左侧有一系列选项能够操作,间接进到项目管理,创立咱们的 VideoChat 我的项目。
在我的项目创立的平安模式上,抉择 APPID + Token 的形式。为了进步我的项目的安全性,Agora 后续会勾销对 APP ID 鉴权计划的反对。
当我的项目创立实现后就有了对应的 APP ID,这个在后续代码开发中会用到的。
除此之外,咱们还须要生成 Token,在项目管理页去生成一个长期 Token。
这个长期 Token 是有时效的,仅供测试应用,如果有本人的后端开发,到生产环境再去生成正式 Token。同样,这个 Token 字符串在后续开发中也会用到的。
3. SDK 下载与集成
创立我的项目并筹备好 APP ID 和 Token 之后,就能够在官网上下载音频 SDK 了。
下载解压后的内容如上所示。libs 文件夹内有对应不同 CPU 架构的 so 动静库,还有动静库对应的头文件以及 Java 版本的 Jar 包,可别离进行 C++ 版本和 Java 版本的集成。
这里就只用到 Java 版本来演示了,其实 Java 版本外面很多办法都是走到 native 调用了,而 native 调用的就是 so 动静库外面的办法。用 C++ 版本集成的话,还须要本人写 JNI 代码将 Java 与 C++ 连接起来,不如间接用 Java 版本来的快。
SDK 集成有两种形式,一种是间接应用 JCenter 来集成,在 build.gradle 外面增加一行代码就行。
dependencies {implementation 'io.agora.rtc:full-sdk:3.1.3'}
版本号能够在官网上查问,目前最新版本就是 3.1.3 了。
当然还能够通过加载 jar 包和 so 动静库的形式进行集成,把 agora-rtc-sdk.jar 和各版本 so 拷贝到对应目录下,如下图所示:
另外别忘了在 app 目录下的 build.gradle 中增加如下代码:
dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])
}
少了这行代码,可解析不到增加的 jar 包。
以上,就实现了整个 SDK 的工程接入,接下来就是代码开发环节了。
4. 利用开发
咱们要开发的是一款音视频通话利用,就像微信视频一样,想想会有哪些内容。
首先要通过 Camera 采集咱们的画面,而后通过麦克风录制咱们的声音,再通过网络传输给到对方,并且可能听到对方的声音,在屏幕上显示画面。
想一想这些内容要是纯 Android 开发的话,那波及的货色可多了,四五个人都不肯定能 hold 住,而应用业余的音视频 SDK,一个人就能搞定大部分工作了。
接下来就要去实现这样的开发工作,具体代码能够在 Github 上获取:
https://github.com/glumes/ago…
4.1 权限申请
首先是权限申请,波及到 Camera、网络、存储、录制等等内容,在官网上也有给出具体权限列表,如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.agora.tutorials1v1acall">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<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.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
// 如果你的场景中波及读取内部存储,需增加如下权限:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
// 如果你应用的是 Android 10.0 及以上设施,还须要增加如下权限:<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
...
</manifest>
具体代码可见 Github :
https://github.com/glumes/agora-sdk-demo/blob/main/app/src/main/java/com/glumes/videochat/MainActivity.kt
4.2 引擎创立
接下来就是创立 RtcEngine,SDK 的很多办法都是通过 RtcEngine 来调用的。
// 申明 RtcEngine
private RtcEngine mRtcEngine;
// 创立 RtcEngine
private void initializeEngine() {
try {mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.agora_app_id), mRtcEventHandler);
} catch (Exception e) {Log.e(TAG, Log.getStackTraceString(e));
throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
}
}
在创立 RtcEngine 的时候须要用到 APP ID,后面曾经提过,在创立我的项目时就曾经有了。
最初一个参数是 mRtcEventHandler
,它是一个 IRtcEngineEventHandler
类型的抽象类,类外面定义了很多办法,去响应 RtcEngine 不同状态的回调,比方连贯胜利,连贯失败、退出频道、来到频道、网络状态扭转等等。如果有须要对利用的性能做一些监督,那么就能够在 IRtcEngineEventHandler 的回调办法做相干统计和埋点。
4.3 实现 Camera 画面预览
RtcEngine 把 Camera 相干操作都封装在 SDK 内了,通过几行代码就能实现 Camera 画面预览。
4.3.1 创立 Camera 画面预览控件 View
首先要有一个控件去承接显示 Camera 的画面输入内容,能够用 SurfaceView 也能够用 TextureView,但并不需要咱们去创立控件,而是用 Agora SDK 提供的办法。
// 应用 SurfaceView 的场景
SurfaceView mLocalView = RtcEngine.CreateRendererView(getBaseContext());
// 应用 TextureView 的场景
TextureView mLocalView = RtcEngine.CreateTextureView(getBaseContext());
TextureView 是 Agora SDK 在 3.1.0 版本才提供的,它与 SurfaceView 的区别在于 TextureView 能够对画面进行缩放、旋转和平移,而 SurfaceView 更适宜在视频通话和直播场景应用。
有了显示的 View 之后,要把它增加到以后 Activity 的控件树上,前面 Camera 画面就会输入到这里。
4.3.2 配置 Camera 输入并开启预览
接下来就是让 Camera 输入画面了,可实际上不必写一行对于 Camera 的代码,三行代码就能够搞定。
// 开启视频
mRtcEngine.enableVideo();
// 初始化本地视图
mRtcEngine.setupLocalVideo(new VideoCanvas(mLocalView, VideoCanvas.RENDER_MODE_HIDDEN, 0));
// 开启预览
mRtcEngine.startPreview();
通过以上代码就能在屏幕上显示咱们的画面了,默认是前置摄像头的内容。
具体代码可见 Github :
https://github.com/glumes/agora-sdk-demo/blob/main/app/src/main/java/com/glumes/videochat/CameraPreviewActivity.kt
在代码开发中,首先要启用视频模块,默认是敞开的,通过 disableVideo 也能够敞开。而音频模块默认就是开启的,也能够通过 enableAudio 和 disableAudio 来开启敞开音频模块。
之后就是通过 setupLocalVideo 办法来初始化本地视图,次要是设置本地用户视频信息的,也就是咱们的画面要在 SurfaceView 中如何显示,配置信息都是通过 VideoCanvas 类下发的,它有多种参数类型。
// VideoCanvas 构造函数类型
VideoCanvas (View view)
VideoCanvas (View view, int renderMode, int uid)
VideoCanvas (View view, int renderMode, String channelId, int uid)
VideoCanvas (View view, int renderMode, int uid, int mirrorMode)
VideoCanvas (View view, int renderMode, String channelId, int uid, int mirrorMode)
其中 renderMode 就是指定咱们的画面在 SurfaceView 如何显示,有如下类型:
-
RENDER_MODE_HIDDEN
- 优先保障视窗被填满。视频尺寸等比缩放,直至整个视窗被视频填满。如果视频长宽与显示窗口不同,多出的视频将被截掉。
-
RENDER_MODE_FIT
- 优先保障视频内容全副显示。视频尺寸等比缩放,直至视频窗口的一边与视窗边框对齐。如果视频长宽与显示窗口不同,视窗上未被填满的区域将被涂黑
-
RENDER_MODE_FILL
- 视频尺寸进行缩放和拉伸以充斥显示视窗
默认状况下都是应用 RENDER_MODE_HIDDEN 模式的。另外还有 mirrorMode 这样的属性来设置是否要画面镜像。
实现了画面显示配置之后,间接调用 startPreview 就能在屏幕上看到画面啦,是不是很简略!
4.3.3 Camera 更多的配置操作
简略的背地其实是 Agora SDK 做了很多封装工作,比方 Camera1 和 Camera2 的调用逻辑、Camera 输入的分辨率策略、前后摄像头抉择等等。
咱们能够在开启预览前通过 setCameraCapturerConfiguration 办法来配置本人想要的 Camera 信息。
// 配置 Camera 信息
mRtcEngine.setCameraCapturerConfiguration(new CameraCapturerConfiguration(CAPTURER_OUTPUT_PREFERENCE_AUTO,CAMERA_FRONT));
Camera 参数信息次要是在 CameraCapturerConfiguration 类中,它的两个参数都是枚举类型,其中第二个参数指定了应用前置还是后置摄像头。
第一个参数就是对于 Camera 输入分辨率的一些策略,Agora SDK 并没有给出接口让咱们指定 Camera 输入宽是多少,长是多少,而且依据应用场景组合了三个策略,更方面咱们去调用了。
-
CAPTURER_OUTPUT_PREFERENCE_AUTO
- (默认)主动调整采集参数。
-
CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE
- 优先保障设施性能。
-
CAPTURER_OUTPUT_PREFERENCE_PREVIEW
- 优先保障视频预览品质。
通过以上操作,就实现了 Camera 画面预览显示。
4.4 退出通话频道
接下来就要去退出一个频道,并和同一频道内的敌人进行通信。
// 函数原型
joinChannel (String token,String channelName,String optionalInfo,int optionalUid)
// 具体调用
private void joinChannel() {
// 失去 Token
String token = getString(R.string.agora_access_token);
// Token 和 频道名要匹配
mRtcEngine.joinChannel(token, "demoChannel1", "", 0);
}
通过 joinChannel
办法退出,其中 token 就是咱们之前创立好的,而频道名称也是创立 token 时指定的,这两者要匹配起来。optionalInfo 是可选的字符串。optionalUid 是用户 ID,也是可选项,如果不指定(设为 0),SDK 会主动调配一个,并在 onJoinChannelSuccess 回调办法中返回。
当咱们退出频道胜利后,会回调 IRtcEngineEventHandler 中的 onJoinChannelSuccess 办法。
通过 leaveChannel
办法,咱们能够来到以后频道,同样会回调 IRtcEngineEventHandler 中的 onLeaveChannel 办法。
4.5 音视频数据编码格局参数设置
退出频道后,咱们就要和频道内的敌人们通信。要把咱们的画面和声音发送给对方,那必定要将数据进行编码,而后通过网络传输送给对方。
留神:音频和视频的参数都肯定要在退出频道前设定好,也就是 joinChannel 办法调用之前,在其之后调用是不失效的。
4.5.1 视频编码参数设置
这里咱们要指定视频编码的分辨率、帧率、码率、视频等信息,通过 setVideoEncoderConfiguration
办法。
mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
// 视频分辨率
VideoEncoderConfiguration.VD_640x360,
// 帧率
VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
// 码率
VideoEncoderConfiguration.STANDARD_BITRATE,
// 视频方向
VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT));
在更早的 Agora SDK 版本中是通过 setVideoProfile 来设定的,还能够指定具体的宽高、帧率数值。
最新版本换成了 VideoEncoderConfiguration 来配置,并且配置的参数是都曾经定义好了相干的常量,不必本人写 720、1280 这样的 Magic Number 了。
参数的设置并不是变化无穷的,因为网络或者性能等因素会有一些稳定,但还是会取最靠近咱们设定的值。
4.5.2 音频编码参数设置
而音频相干的参数,则是通过 setAudioProfile
办法来设置。
mRtcEngine.setAudioProfile(
// 设置音频采样率、码率、编码模式和声道数
Constants.AudioProfile.DEFAULT.ordinal(),
// 设置音频的利用场景
Constants.AudioScenario.DEFAULT.ordinal());
音频咱们能够设置采样率、码率、编码模式以及声道数。和视频参数设置一样,咱们不必指定具体的数值,Agora SDK 都依据业务应用场景做了封装,依据须要来设置就好啦。
音频 AudioProfile 有如下的配置:
-
DEFAULT
- 通信场景下,该选项代表指定 32 kHz 采样率,语音编码,单声道,编码码率最大值为 18 Kbps。
- 直播场景下,该选项代表指定 48 kHz 采样率,音乐编码,单声道,编码码率最大值为 64 Kbps。
-
SPEECH_STANDARD
- 指定 32 kHz 采样率,语音编码, 单声道,编码码率最大值为 18 Kbps。
-
MUSIC_STANDARD_STEREO
- 指定 48 kHz 采样率,音乐编码, 单声道,编码码率最大值为 64 Kbps。
-
MUSIC_HIGH_QUALITY
- 指定 48 kHz 采样率,音乐编码, 单声道,编码码率最大值为 96 Kbps。
-
MUSIC_HIGH_QUALITY_STEREO
- 指定 48 kHz 采样率,音乐编码, 双声道,编码码率最大值为 128 Kbps。
音频的利用场景也有如下:
-
DEFAULT
- 默认的音频利用场景
-
CHATROOM_ENTERTAINMENT
- 娱乐利用,须要频繁高低麦的场景
-
EDUCATION
- 教育利用,晦涩度和稳定性优先
-
GAME_STREAMING
- 高音质语聊房利用
-
SHOWROOM
- 秀场利用,音质优先和更好的业余外设反对
-
CHATROOM_GAMING
- 游戏开黑
一般来说,咱们应用默认的配置 DEFAULT 就好了。
4.6 用户退出并显示对方画面
当设置好了本人的数据编码参数,并且也胜利退出了频道,接下来就是去接管频道内其他人的画面和信息了。
具体代码可见 Github:
https://github.com/glumes/agora-sdk-demo/blob/main/app/src/main/java/com/glumes/videochat/VideoChatActivity.kt
4.6.1 判断是否有用户退出频道
当 IRtcEngineEventHandler 中的 onUserJoined 办法回调时,代表有人退出了以后频道,此时就能够建设并初始化远端用户视图了。
如果启用了视频录制性能,视频录制服务也会回调 onUserJoined 办法,相当于有个机器人退出该频道,此时要辨别开来,不能为机器人建设远端视频,而后它不会发送视频流的,建设了也是黑屏的。
为了防止机器人退出带来的误判,在 2.9.0 版本后更倡议在 onRemoteVideoStateChanged 办法回调中去建设远端用户视图。
onRemoteVideoStateChanged 办法顾名思义就是当远端用户状态产生扭转时就会调用,其中定义了如下几个状态:
-
REMOTE_VIDEO_STATE_STARTING
- 本地用户已接管远端视频首包
-
REMOTE_VIDEO_STATE_DECODING
- 远端视频流正在解码,失常播放
-
REMOTE_VIDEO_STATE_STOPPED
- 远端视频默认初始状态
-
REMOTE_VIDEO_STATE_FROZEN
- 远端视频流卡顿
-
REMOTE_VIDEO_STATE_FAILED
- 远端视频流播放失败
当状态是 REMOTE_VIDEO_STATE_STARTING 或者 REMOTE_VIDEO_STATE_DECODING 时,咱们认定有敌人退出频道了,此时建设远端用户视图。
@Override
public void onRemoteVideoStateChanged(final int uid, int state, int reason, int elapsed) {if (state == Constants.REMOTE_VIDEO_STATE_STARTING){runOnUiThread(new Runnable() {
@Override
public void run() {setupRemoteVideo(uid);
}
});
}
}
其中 onRemoteVideoStateChanged 回调办法中 state 参数代表状态,uid 用来标识远端用户 id,如果有多个敌人退出了该频道,咱们就要用 uid 来辨别一下用户,防止漏了或者反复建设远端用户视图。
4.6.2 建设远端用户视图
接下来建设远端用户视图,和建设 Camera 预览视图办法基本一致。
// 由 Agora SDK 创立 SurfaceView
mRemoteView = RtcEngine.CreateRendererView(getBaseContext());
// 把 SurfaceView 增加到以后 Activity 的布局控件树上
mRemoteContainer.addView(mRemoteView);
// Camera 画面预览就用 setupLocalVideo 办法,远端用户就用 setupRemoteVideo 办法
mRtcEngine.setupRemoteVideo(new VideoCanvas(mRemoteView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
同样是由 Agora SDK 去创立 SurfaceView,把它增加到控件容器上,最初通过 setupRemoteVideo 办法实现建设,整个逻辑和 Camera 视图建设是相似的,就是最初调用的办法不一样了。
4.7 利用运行并视频通话
当建设好了远端用户视图,实践上当初就能够显示本人和对方的画面了,并相互听到声音了。
用两台手机别离运行程序,能够验证成果如下:
另外在官网上还能够查看以后我的项目的流量应用状况:
每个月有 10000 分钟的流量赠送,能够放心使用
5. 我的项目开发总结
通过以上的 SDK 接入和代码示例就曾经实现了一个简略的双人音视频通话。
而 Agora SDK 提供的性能远非如此。
咱们还能够对以后频道的音视频进行管制,抉择是否静音、是否敞开画面等等;咱们还能够切换频道,参加频道的通话;咱们还能够将我的项目打造成多人的音视频通话,为每个退出频道的用户建设远端视图。
更多的音视频相干性能都能够通过 Agora SDK 来实现了。
总结一下整体的接入流程也是十分不便的:
SDK 集成 -> 权限设置 -> Camera 预览 -> 退出频道 -> 显示画面 -> 在线通话
以上的每个步骤在文章中都有解说,心愿在你的应用过程中会有一些帮忙!!!
「本文为集体原创,首发于 声网开发者社区」
详情: https://rtcdeveloper.com/t/topic/20054