human: 如何处理七牛云的实时音视频实现视频通话

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 快速入门 > Android >实现视频通话

#  实现视频通话

最近更新时间: 2024-07-15 14:41:05

本文将介绍如何快速实现一个基本的实时音视频应用。该应用会展示 SDK 基本的连麦功能，包括 **加入房间** ，**采集** ，**发布** ，**订阅**
等过程。

>   * 若您的开发环境还没有搭建完成，SDK
> 还未导入，请先参考[开发准备](https://developer.qiniu.com/rtc/quick_start/8765/prepare-
> android-development)文档进行 SDK 的导入等工作。
>   * 若您对实时音视频的**发布、订阅**
> 等基本流程还不熟悉，请先参考[基本概念](https://developer.qiniu.com/rtc/quick_start/9909/the-
> rtc-basic-concept)对实时音视频通话过程中的相关概念略作了解。
>

# 初始化

首先，在进行 SDK 接口调用之前，需要在 Activity 生命周期中的 onCreate() 中进行初始化操作：

    
    
    QNRTC.init(context, new QNRTCEventListener());
    

# 添加视频渲染控件

用户需要在布局文件中期望的位置添加两个
[QNSurfaceView](https://developer.qiniu.com/rtc/api/8690/QNSurfaceView)
分别用来做本地视频画面预览窗口和远端视频画面渲染窗口。

示例代码如下：

    
    
    <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" />
    
    
    
    mLocalWindow = findViewById(R.id.local_surface_view);
    mRemoteWindow = findViewById(R.id.remote_surface_view);
    

# 创建音视频通话核心类

本操作推荐在 Activity 生命周期中的 onCreate() 中完成

    
    
    QNRTCClient mClient = QNRTC.createClient(new QNClientEventListener());
    

其中，[QNClientEventListener](https://developer.qiniu.com/rtc/api/8643/QNClientEventListener)
为音视频通话过程中必须的事件监听回调。

# 创建音视频采集 Track

[Track](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-basic-
concept#track) 代表了音视频通话过程中的一路音频或者一路视频，本文仅介绍一路音视频连麦的场景，创建方式如下：

    
    
    QNCameraVideoTrack mCameraVideoTrack = QNRTC.createCameraVideoTrack();
    QNMicrophoneAudioTrack mMicrophoneAudioTrack = QNRTC.createMicrophoneAudioTrack();
    

创建好本地视频 [Track](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-
basic-concept#track) 后即可设置渲染窗口，代码如下：

    
    
    mCameraVideoTrack.play(mLocalWindow);
    

> **注意** ：创建 Track 需要 App 获取 `CAMERA`、`RECORD_AUDIO`
> 等采集相关的权限，请确保您的应用已经获取该权限，否则数据采集将会失败。权限申请可参考 [QNRTC-API-
> Examples](https://github.com/pili-engineering/QNRTC-
> Android/blob/master/QNRTC-API-
> Examples/app/src/main/java/com/qiniu/droid/rtc/api/examples/utils/PermissionChecker.java)

为了更好的控制采集的流程，可以在生命周期函数中添加如下调用：

    
    
    @Override
    protected void onResume() {
        super.onResume();
        // 开始视频采集
        if (mCameraVideoTrack != null) {
            mCameraVideoTrack.startCapture();
        }
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        // 停止视频采集
        if (mCameraTrack != null) {
            mCameraTrack.stopCapture();
        }
    }
    

# 加入房间

完成初始化和本地音视频 Track 的创建后，您就可以调用
[QNRTCClient.join](https://developer.qiniu.com/rtc/api/8684/QNRTCClient#join%5B1/2%5D)
接口加入房间了。

> 加入房间需要携带相应的
> [RoomToken](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-basic-
> concept#room_token)：
>
>   1. [RoomToken](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-
> basic-concept#room_token) 建议通过您的服务端生成，签算方式可参考 [RoomToken
> 签发服务](https://developer.qiniu.com/rtc/development_guidelines/8813/roomToken)。
>   2.
> 若您的服务端还没有实现相关代码，可参考[管理实时音视频](https://developer.qiniu.com/rtc/9858/applist#4)文档在
> [portal](https://portal.qiniu.com/rtn/app) 上生成临时的 token，需要注意 **UserID 不可重复**
> 。
>

[RoomToken](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-basic-
concept#room_token) 准备好后，即可通过如下代码加入房间：

    
    
    mClient.join(token);
    

加入房间成功后会触发
[QNClientEventListener.onConnectionStateChanged](https://developer.qiniu.com/rtc/api/8643/QNClientEventListener#onConnectionStateChanged)
回调 QNConnectionState.CONNECTED 状态。此时，即可通过发布、订阅等操作来实现音视频的推送和接收。

在进入音视频通话房间之后，用户可以根据业务场景的需求在适当的时间调用离开房间的接口退出连麦，详情请见[房间管理](https://developer.qiniu.com/rtc/development_guidelines/8768/room-
management-android)。

> **注意** ：加入、离开房间代表一次音视频通话的开始和结束，一次会话仅需调用一次加入、离开的操作即可，无需重复调用。

# 发布本地音视频 Track

成功加入房间后，即可在
[QNClientEventListener.onConnectionStateChanged](https://developer.qiniu.com/rtc/api/8643/QNClientEventListener#onConnectionStateChanged)
回调中调用以下代码进行本地 Track 的发布：

    
    
    @Override
    public void onConnectionStateChanged(QNConnectionState state, @Nullable QNConnectionDisconnectedInfo info) {
        if (state == QNConnectionState.CONNECTED) {
            mClient.publish(new QNPublishResultCallback() {
                @Override
                public void onPublished() {
                    // Track 发布成功时回调
                }
    
                @Override
                public void onError(int errorCode, String errorMessage) {
                    // Track 发布失败时回调
                }
            }, mCameraVideoTrack, mMicrophoneAudioTrack);
        }
    }
    

发布成功后，本地会收到
[QNPublishResultCallback.onPublished](https://developer.qiniu.com/rtc/api/8673/QNPublishResultCallback#onPublished)
回调。远端用户会收到
[QNClientEventListener.onUserPublished](https://developer.qiniu.com/rtc/api/8643/QNClientEventListener#onUserPublished)
回调。

取消发布可以通过调用
[QNRTCClient.unpublish](https://developer.qiniu.com/rtc/api/8684/QNRTCClient#unpublish%5B1/2%5D)
方法实现。取消发布后，本地音视频数据将停止发送，但仍可以接收远端的音视频数据。更多内容可参考[发布和订阅](https://developer.qiniu.com/rtc/development_guidelines/8769/publish-
and-subscribe-android)。

# 订阅远端音视频 Track

当远端成功发布音视频数据后，SDK 默认会进行自动订阅，订阅成功后将会收到
[QNClientEventListener.onSubscribed](https://developer.qiniu.com/rtc/api/8643/QNClientEventListener#onSubscribed)
的回调，在此回调内可设置 [Track](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-
basic-concept#track) 的渲染窗口：

    
    
    @Override
    public void onSubscribed(String remoteUserID, List<QNRemoteAudioTrack> remoteAudioTracks, List<QNRemoteVideoTrack> remoteVideoTracks) {
        for(QNRemoteVideoTrack track : remoteVideoTracks) {
            track.play(remoteWindow);
        }
    }
    

在成功订阅之后，用户可以根据业务场景的需求在适当的时间调用取消订阅的接口取消订阅相应的
Track，详情请见[发布与订阅](https://developer.qiniu.com/rtc/development_guidelines/8769/publish-
and-subscribe-android)

# 离开房间

当音视频通话结束，调用以下代码离开房间：

    
    
    mClient.leave()
    

离开房间成功后会触发
[QNClientEventListener.onConnectionStateChanged](https://developer.qiniu.com/rtc/api/8643/QNClientEventListener#onConnectionStateChanged)
回调 `QNConnectionState.DISCONNECTED` 状态，对应
[QNConnectionDisconnectedInfo.Reason](https://developer.qiniu.com/rtc/api/8644/QNConnectionDisconnectedInfo#Reason)
为 `LEAVE`。

> **注意** ：离开房间代表本次音视频通话的结束，离开后将无法发布本地音视频，也无法订阅远端音视频。

# 销毁

在整个 Activity 销毁时，用户需要调用以下代码对资源进行释放，一般此操作建议在 Activity 生命周期的 `onDestroy()`
中进行，示例代码如下：

    
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        QNRTC.deinit();
    }
    

# 示例代码

按照上述流程即可实现一个基本的实时音视频通话应用，完整的示例代码可参考 [QNRTC-API-
Examples](https://github.com/pili-engineering/QNRTC-Android/blob/master/QNRTC-
API-
Examples/app/src/main/java/com/qiniu/droid/rtc/api/examples/activity/CameraMicrophoneActivity.java)。

以上内容是否对您有帮助？