human: 如何处理七牛云的实时音视频发布和订阅

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > WXApp >发布和订阅

#  发布和订阅

最近更新时间: 2022-08-08 16:48:11

本部分介绍能够实现向房间发布媒体流与订阅媒体流等操作。

# 发布本地 Track

与其他 `SDK` 不同，小程序只需要在 `live-pusher` 组件中提供推流地址，当推流成功后，`SDK` 即可获得所发布的本地音视频
**Track** 。所以首先需要获取推流地址：

    
    
    import { QNPublishStatus } from "pili-rtc-wxapp"
    client.publish((status, data) => {
        if(status === QNPublishStatus.READY) {
            this.setData({
                publishPath: data.url
            })
        }
    })
    

其中 `publish` 的回调状态有三种：

  * `READY` 该状态中可以获取对应的推流地址
  * `COMPLETED` 当推流成功后，该状态可以获取推流所发布的音视频 **Track**
  * `ERROR` 该状态表示推流失败

当获取到推流地址后，传入 `live-pusher` 组件：

    
    
    <!-- index.wxml -->
    <live-pusher
        autopush
        mode="RTC"
        url="{{publishPath}}"
    >
    </live-pusher>
    

当推流成功后，`publish` 回调收到 `COMPLETED` 状态，同时返回所发布的 **Track** ，完整代码如下：

    
    
    import { QNPublishStatus } from "pili-rtc-wxapp"
    client.publish((status, data) => {
        if(status === QNPublishStatus.READY) {
            this.setData({
                publishPath: data.url
            })
        }else if(status === QNPublishStatus.COMPLETED) {
            this.setData({
                localTracks: data.tracks
            })
        }else if(status === QNPublishStatus.ERROR) {
            console.log("发布失败")
        }
    })
    

`live-pusher` 设置 autopush 时，填入对应推流地址即会自动推流，如果需要监听是否推流成功，可以使用小程序所提供的事件函数
`bindstatechange` ，根据
[官网](https://developers.weixin.qq.com/miniprogram/dev/component/live-
pusher.html) 所提供的 `code` 码判断状态：

    
    
    <!-- index.wxml -->
    <live-pusher
        autopush
        mode="RTC"
        url="{{publishPath}}"
        bindstatechange="handleStateChange"
    >
    </live-pusher>
    
    
    
    Page({
        handleStateChange(e) {
            console.log('live-pusher code:', e.detail.code)
        }
    })
    

> `live-pusher` 除了 autopush，还支持对应 API 操作推流与否，详情可见
> [官方文档](https://developers.weixin.qq.com/miniprogram/dev/api/media/live/LivePusherContext.html)
> 。

当推流成功后，远端用户在监听 [user-
published](https://developer.qiniu.com/rtc/10950/WXAppQNRTCClient#USER_PUBLISHED)
后会收到如下事件通知：

    
    
    client.on('user-published', (userID, track) => {
        console.log('user-published', userID, track)
    });
    

# 取消发布本地 Track

发布成功后，只有当离开房间才表示取消发布本地 **Track** 。

取消发布成功后，远端用户在监听 [user-
unpublished](https://developer.qiniu.com/rtc/9090/WXAppQNRTCClient#USER_UNPUBLISHED)
后会收到如下事件通知：

    
    
    client.on('user-unpublished', (userID, track) => {
        console.log('user-unpublished', userID, track);
    });
    

> 有一个例外，当调用 `wx.createLivePusherContext().stop()` ，再调用
> `wx.createLivePusherContext().start()` 后，远端用户亦会监听到 `user-unpublished`
> 事件触发，紧随着监听到 `user-published` 事件。

# 订阅远端 Track

当收到远端用户发布的信息后，可以调用
[subscribe](https://developer.qiniu.com/rtc/10950/WXAppQNRTCClient#subscribe)
方法订阅该 **Track** 。

    
    
    client.on('user-published', async (userID, tracks) => {
        const url = await client.subscribe({
            videoTrack: tracks.find(track => track.isVideo()),
            audioTrack: tracks.find(track => track.isAudio())
        })
        this.setData({
            subscribeList: [...this.data.subscribeList, url]
        })
    });
    

订阅成功后，返回对应 **QNRemoteTrack** 所生成的拉流地址，然后在 `live-player` 组件中设置对应的拉流地址即可：

    
    
    <!-- index.wxml -->
    <live-player
      autoplay
      wx:for="{{subscribeList}}"
      src="{{item}}"
      mode="RTC"
    >
    </live-player>
    

需要注意的是，`subscribe` 方法所传入的音视频 **QNRemoteTrack** 必须为同一个用户所发布的。另外，如果小程序与其他
`七牛音视频SDK` 进行通讯时，一个用户可能不单单只发布一个音频 **Track** 和一个视频 **Track** ，很有可能有多个
**Tracks** ，这时需要使用者根据 **QNRemoteTrack** 的 `tag` 属性来判断应该订阅哪一个 **QNRemoteTrack**
。

> 在 `小程序SDK` 中，发布的 **Track** 的 `tag` 值默认为 `debug`，在其他 `SDK` 中可以根据使用者需要进行自定义。

# 取消订阅远端 Track

在小程序中，关闭 `live-player` 即表示取消订阅 `live-player` 中拉流地址所对应的 `Track`。

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