2024-12-05-手把手教你实现音视频通话Android-Demo
手把手教你实现音视频通话Android Demo
前言
目前音视频应用越来越丰富,而且各厂商都提供功能丰富的 SDK ,如何集成第三方音视频SDK,这是我们这篇文章主要的分享内容。本次我们选择七牛 RTC SDK 作为演示,将手把手教大家如何集成 RTC SDK 实现 1v1 的
Android demo
。
QNDroidRTC 是七牛推出的一款适用于 Android 平台的音视频通话 SDK,提供了包括美颜、滤镜、音视频通话等多种功能,提供灵活的接口,支持高度定制以及二次开发,可以很方便地在 Android 平台上开发出一款基于实时音视频的应用。
一 环境搭建
在开始集成之前,我们应该先搭建一套Android开发环境,比如
- JDK
- Android Studio
- RTC SDK 版本
- 加房token
以上具体的信息可以参考 ,RTC SDK版本 本文用的是v5.2.7版本, 。
二 基本配置
- 创建Android项目,集成 RTC SDK
创建一个 Android 项目,名为“
CameraMicrophoneDemo
”,将 repo 中 releases 目录下的 jar 包和动态库分别拷贝到下面的文件中
拷贝完成之后,需要在项目的 build.gradle 脚本中添加 SDK 的依赖,我们看到项目组织架构中有两个 build.gradle 脚本文件,外层的表示 root project 的 gradle 文件,里面的表示项目的 gradle 文件。我们所要配置的是项目的也就是里面的 gradle 脚本文件。
- 添加相关权限
在工程的
AndroidManifest.xml
中增加 uses-permission 声明,例如摄像头、麦克风、蓝牙等权限
<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.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
在 Android 6.0(API 23)开始,用户需要在应用运行时授予权限,而不是在应用安装时授予,同时权限分为正常权限和危险权限两种类型,在实时音视频SDK中,用户需要在进入音视频通话前选择一个适当的时机动态申请 CAMERA、RECORD_AUDIO、BLUETOOTH_CONNECT 权限,需要你想了解更加,可以参考 。
- 创建一个 activity,名为:
CameraMicActivity.java
,如上图所示。
public class CameraMicActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_mic);
}
}
三 音视频实现逻辑
在实现音视频通话之前,应该先了解下音视频通话的实现流程以及专业术语,比如,创建 track、加房、采集、发布 track、订阅 track 等等,不要怕不理解也没关系,官网文档有详细说明。
实现音视频通话,总共需要9步,接下来会详细的手把手开始实践。
第一步 初始化视图
初始化视图包括本地预览视频和远端视频,在初始化之前,应该先设置好本地和远端对应视图的控件,在 res→layout→activity_camera_mic.xml 中设置布局,详细如下
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.qiniu.droid.rtc.QNSurfaceView
android:id="@+id/local_surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.qiniu.droid.rtc.QNSurfaceView
android:id="@+id/remote_surface_view"
android:layout_width="150dp"
android:layout_height="150dp" />
</FrameLayout>
然后在
CameraMicActivity.java
中初始化视图。
// 初始化视图
private void initView() {
// 初始化本地预览视图
mLocalWindow = findViewById(R.id.local_surface_view);
mLocalWindow.setZOrderOnTop(true);
// 初始化远端预览视图
mRemoteWindow = findViewById(R.id.remote_surface_view);
mRemoteWindow.setZOrderOnTop(true);
}
// 在onCreate中调用initView()
initView();
第二步 初始化RTC
QNRTC 提供 SDK 的入口方法,可以通过它进行 SDK 的初始化,各个类型 Track 的创建等操作。
// 在onCreate()中初始化RTC
QNRTC.init(this, new QNRTCEventListener() {
@Override
public void onAudioRouteChanged(QNAudioDevice qnAudioDevice) {
}
});
第三步 创建 QNRTCClient 对象
QNRTCClient 提供和房间相关的一些列方法,通过它我们可以实现加入房间,在房间内发布或者订阅相应的音视频轨道等操作。
在 Activity 生命周期中的
onCreate()
中完成,
为音视频通话过程中必须的事件监听回调。
mClient = QNRTC.createClient(mClientEventListener);
第四步 创建本地音视频Track
通过
createCameraVideoTrack()
创建视频Track;通过
createMicrophoneAudioTrack()
创建音频Track。
mCameraVideoTrack = QNRTC.createCameraVideoTrack();
mMicrophoneAudioTrack = QNRTC.createMicrophoneAudioTrack();
为了更好的控制采集的流程,可以在生命周期函数中添加如下调用:
@Override
protected void onResume() {
super.onResume();
// 开始视频采集
if (mCameraVideoTrack != null) {
mCameraVideoTrack.startCapture();
}
}
@Override
protected void onPause() {
super.onPause();
// 停止视频采集
if (mCameraVideoTrack != null) {
mCameraVideoTrack.stopCapture();
}
}
第五步 加入房间
mClient.join("QxZuxxxxxx");
LocalWindow = findViewById(R.id.local_surface_view);
mRemoteWindow = findViewById(R.id.remote_surface_view);
//渲染
mCameraVideoTrack.play(mLocalWindow);
另外,创建 Track 这件事可以放在加房之前,也可以放在加房之后。
join()
需要填写token信息,可以在官方文档注册获取。
第六步 发布本地音视频 Track
private final QNClientEventListener mClientEventListener = new QNClientEventListener() {
@Override
public void onConnectionStateChanged(QNConnectionState qnConnectionState, @Nullable QNConnectionDisconnectedInfo qnConnectionDisconnectedInfo) {
if (qnConnectionState == QNConnectionState.CONNECTED) {
mClient.publish(new QNPublishResultCallback() {
@Override
public void onPublished() {
// Track 发布成功时回调
}
@Override
public void onError(int errorCode, String errorMessage) {
// Track 发布失败时回调
}
}, mCameraVideoTrack, mMicrophoneAudioTrack);
}
}
....
....
第七步 订阅远端音视频 Track
@Override
public void onSubscribed(String s, List<QNRemoteAudioTrack> list, List<QNRemoteVideoTrack> remoteVideoTracks) {
for (QNRemoteVideoTrack track : remoteVideoTracks){
track.play(mRemoteWindow);
}
}
第八步 离开房间
mClient.leave();
第八步 销毁并释放资源
在整个 Activity 销毁时,用户需要调用以下代码对资源进行释放,一般此操作建议在 Activity 生命周期的
onDestroy()
中进行,示例代码如下:
protected void onDestroy() {
super.onDestroy();
if (mClient != null) {
mClient.leave();
mClient = null;
}
QNRTC.deinit();
}
在离开房间前后加了一个判断,主要是防止出现空指针问题;另外,七牛RTC SDK提供了一个 deinit() 反初始化方法,虽然java中有垃圾回收机制,但是还需要释放底层,或者C++层的一些资源。
连麦效果如下:
如果你想获取完整代码,可以看看下方【小曾的IT之旅】回复“demo”即可获取。
68747470733a2f2f626c6f672e:6373646e2e6e65742f77656978696e5f34323138323539392f:61727469636c652f64657461696c732f313335313332333336