声网 SDK 接入以及音视频通话应用开发指南

1. 简介

在现在的移动互联网时代,音视频相关应用已经深刻到咱们平常生活的方方面面。java

而在它背后的音视频技术也是很是成熟了,短视频编辑、带货直播、视频语音通话等应用形式无不体现着音视频技术给咱们生活带来的便利。android

而此次就去实际体验一下,接入声网的音频 SDK ,并打造一个音视频通话应用。git

2. 帐户注册与项目建立

首先要作的就是在声网(https://www.agora.io/cn)上注册帐号,并完成实名认证。github

登陆以后就进到管理界面了,在左侧有一系列选项能够操做,直接进到项目管理,建立咱们的 VideoChat 项目。后端

在项目建立的安全模式上,选择 APPID + Token 的方式。为了提升项目的安全性,Agora 后续会取消对 APP ID 鉴权方案的支持。安全

当项目建立完成后就有了对应的 APP ID ,这个在后续代码开发中会用到的。微信

除此以外,咱们还须要生成 Token ,在项目管理页去生成一个临时 Token 。网络

这个临时 Token 是有时效的,仅供测试使用,若是有本身的后端开发,到生产环境再去生成正式 Token。一样,这个 Token 字符串在后续开发中也会用到的。架构

3. SDK 下载与集成

建立项目并准备好 APP ID 和 Token 以后,就能够在官网上下载音频 SDK 了。app

下载解压后的内容如上所示。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

相关文章
相关标签/搜索