目录

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版本, 。

二 基本配置

  1. 创建Android项目,集成 RTC SDK

创建一个 Android 项目,名为“ CameraMicrophoneDemo ”,将 repo 中 releases 目录下的 jar 包和动态库分别拷贝到下面的文件中

https://i-blog.csdnimg.cn/blog_migrate/c117efa7d873a14448231bc68617ad49.png

拷贝完成之后,需要在项目的 build.gradle 脚本中添加 SDK 的依赖,我们看到项目组织架构中有两个 build.gradle 脚本文件,外层的表示 root project 的 gradle 文件,里面的表示项目的 gradle 文件。我们所要配置的是项目的也就是里面的 gradle 脚本文件。

https://i-blog.csdnimg.cn/blog_migrate/bf1a28e3eb5920b09baa49892536e8c3.png

  1. 添加相关权限

在工程的 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 权限,需要你想了解更加,可以参考 。

  1. 创建一个 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 等等,不要怕不理解也没关系,官网文档有详细说明。

https://i-blog.csdnimg.cn/blog_migrate/5f868610fb43a537e024e14c8c3444c8.png

实现音视频通话,总共需要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++层的一些资源。

连麦效果如下:

https://i-blog.csdnimg.cn/blog_migrate/cfbc3a5e0552b34815dc80c1802adf94.png

如果你想获取完整代码,可以看看下方【小曾的IT之旅】回复“demo”即可获取。

68747470733a2f2f626c6f672e:6373646e2e6e65742f77656978696e5f34323138323539392f:61727469636c652f64657461696c732f313335313332333336