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

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

#  实现视频通话

最近更新时间: 2022-08-08 16:49:13

# 初始化房间并加入房间

到这里您应该已经完成了开发准备，您已经可以拿到 RoomToken 。SDK 通过传入 RoomToken 来完成加入房间。RoomToken
是一个包含了一次连麦所需要的主要信息的 token，这些信息包括 七牛的账户标识、连麦的应用 ID(appId)、连麦的房间号
(roomName)、连麦的用户名(userId)、有效期等等。

> 如果您还不知道如何生成 RoomToken，请先阅读
> [七牛实时音视频云接入指南](https://developer.qiniu.com/rtc/8802/pd-overview) 。
    
    
    import { QNRTC } from 'pili-rtc-wxapp'
    // 初始化客户端
    const client = QNRTC.createClient()
    // 加入房间
    await client.join(roomToken, userData);
    

# 发布流

加入房间之后我们需要调用
[publish](https://developer.qiniu.com/rtc/10950/WXAppQNRTCClient#publish)
，该方法的回调会返回推流 **rtmp** 地址，将该地址传入 **live-pusher** 组件，即可完成流的发布。

    
    
    <!-- index.wxml -->
    <live-pusher
      autopush
      mode="RTC"
      url="{{publishPath}}"
    >
    </live-pusher>
    
    
    
      import { QNPublishStatus } from "pili-rtc-wxapp"
    
      client.publish((status, data) => {
          /** 
           * status 共有 READY 、COMPLETED、ERROR 三种状态
           * 其中 READY 表示推流就绪，返回推流的 rtmp 地址
           * COMPLETED 表示推流成功，返回推流生成的音频轨和视频轨
           * ERROR 则表示推流失败
           */
          if(status === QNPublishStatus.READY) {
              this.setData({
                  publishPath: data.url
              })
          }
      })
    

# 订阅流

从上文发布的过程中我们可以知道，推流成功后一般会生成一个视频 `Track` 和一个音频 `Track` ，但是除了 **小程序 SDK** 外，在使用
**七牛Web SDK** 或其余 **SDK** 时， 一个用户可以发布多个音视频 `Track` ，在实际需求中我们不一定会把他所有发布的
`Track` 都订阅（可能只订阅音频之类的），所以订阅的目标是以 `Track` 为单位的。

### 获取 `Track`

那么，我怎么知道房间中有哪些 `Track` ，这些 `Track` 又分别对应哪些用户呢？这就是我们接下来讲述的重点。

我们可以通过 SDK 的 `user-published` 事件获取当前房间的 `Track` 列表：

> 需要在join房间之前监听对应事件，`join` 加入房间成功后，`user-published` 会返回当前所有房间内已发布 `Track`
> 列表以及用户 `userID` 。

进入房间后，当一个远端用户发布了自己的 `Track` ，此时在我们这边也会触发 `user-published` 事件，事件会带上远端用户的
`userID` 以及所发布的 `Track` 列表。

### 订阅

当我们获取到 `Track` 后，可以通过调用
[subscribe](https://developer.qiniu.com/rtc/10950/WXAppQNRTCClient#subscribe)
传入需要订阅的 `Track` ，将该方法返回推流的 **rtmp** 地址传入 **live-player** 组件，即可完成流的拉取。

    
    
    <!-- index.wxml -->
    <live-player
      autoplay
      wx:for="{{subscribeList}}"
      src="{{item}}"
      mode="RTC"
    >
    </live-player>
    
    
    
    // index.js
     // 初始化客户端
    const client = QNRTC.createClient();
    client.on("user-published", async (user, tracks) => {
      console.log("event: user-published - 用户发布", user, tracks);
      let config = {};
      let videoTrack = tracks.find((item) => item.isVideo());
      let audioTrack = tracks.find((item) => item.isAudio());
      if (videoTrack) {
        config.videoTrack = videoTrack;
      }
      if (audioTrack) {
        config.audioTrack = audioTrack;
      }
      const url = await client.subscribe(config);
      this.setData({
        subscribeList: [...this.data.subscribeList,url],
      });
    });
    // 加入房间
    await client.join(roomToken, userData);
    

> 需要注意的是：subscribe 所传入的 `Track` 必须是同一个用户所推流的。

# 离开房间

离开房间，断开信令，一般在 生命周期 onUnload 里调用。

    
    
    Page({
      onUnload() {
        client.leave()
      }
    })
    

# 断网重连

默认情况下，当发生网络异常等情况，SDK 会进入自动重连状态，此时房间连接状态会变为 RECONNECTING，表示重连中。之后就会两种可能：

第一种，此后如果网络状态恢复正常，则 SDK 会完成自动重连，房间连接状态会变为 RECONNECTED，表示重连成功。。

第二种，如果 SDK 自动重连后，仍然无法正常连接网络，则 SDK 会自动退出房间，此时房间连接状态变为
DISCONNECTED，表示断开连接。在断开连接状态时，[回调函数](https://developer.qiniu.com/rtc/10950/WXAppQNRTCClient#CONNECTION_STATE_CHANGED)中会带有第二个参数
[QNConnectionDisconnectedInfo](https://developer.qiniu.com/rtc/10943/WXAppQNConnectionDisconnectedInfo)，用来表示断开的原因。此时应当根据断开原因不同，做不同的逻辑处理。具体见如下代码。

    
    
    client.on('connection-state-changed', (connectionState, info) => {
      console.log('connection-state-changed', connectionState);
    
      // 当进入连接断开状态
      if (connectionState === QNConnectionState.DISCONNECTED) {
    
        // 监控断开原因
        switch(info.reason) {
    
          // 当异常断开时
          case QNConnectionDisconnectedReason.ERROR:
            break;
    
          // 当被踢出房间时
          case QNConnectionDisconnectedReason.KICKED_OUT:
            break;
    
          // 当调用接口，主动离开房间时
          case QNConnectionDisconnectedReason.LEAVE:
            break;
    
        }
    })
    

此时，最需要关注的是异常断开的情况。一般处理模式有两种：

  * 通知用户：展示 UI，通知用户网络异常，用户可选择调整网络后重试
  * 自动重连：可以在收到异常断开的通知后，主动调用重新加入房间的方法，主动再次重试

# 结语

到了这里我们已经了解 SDK 的基本使用方式。 更多请参考我们的 github 开源 [Demo](https://github.com/pili-
engineering/QNRTC-WxApp)

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