七牛实时音视频云 微信小程序 SDK

七牛实时音视频云 微信小程序 SDK

Android SDK 文档

iOS SDK 文档

Windows SDK 文档

Web SDK 文档

RTN 文档

  • 文档

›开始

开始

  • SDK 概述
  • 开发准备
  • 快速开始

API参考

  • 模块

快速开始

初始化房间并加入房间

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

如果您还不知道如何生成 RoomToken,请先阅读 七牛实时音视频云接入指南

import { RoomSession } from 'pili-rtc-wxapp'
const session = new RoomSession()
// 先拿到 roomToken
session.joinRoomWithToken(roomToken, userData)
  .then(() => {
    // 加入房间成功,接下来可以调用 session.publish 和 session.subscribe
  })
  .catch((err) => {
    // 加入房间失败
    console.log(err)
  })

发布流

使用 qiniu-wx-player 组件中 <pusher> 发布流,这里使用的参数 min-bitrate="200" 最小码率 max-bitrate="400" 最大码率 mode="RTC" RTC模式,加入房间之后我们需要调用 publish 返回一个 rtmp 推流地址。

<!-- index.wxml -->
<pusher
  autopush
  min-bitrate="200"
  max-bitrate="400"
  mode="RTC"
  url="{{publishPath}}"
>
</pusher>

先使用 wx.createLivePusherContext 创建 LivePusherContext,再使用 setData 设置好 publishPath 之后发布。

// index.js

Page({
  data: {
    publishPath: undefined,
  },
  publish() {
  // joinRoom 之后调用
  // 创建 LivePusherContext
  const pushContext = wx.createLivePusherContext()
  const path = session.publish()
  this.setData(
    { publishPath: path },
    () => {
      pushContext.start({
          success: () => {
            console.log('推流成功')
          },
          fail: () => {
            console.log('推流开始失败')
          }
        })
    })
  }
})

订阅流

注意:订阅流我们提供两个 api 。subscribe 返回一个 rtmp 拉流地址(该 api 只返回的是 master 为 true 的 rtmp 地址),getSubscribeAddressList 返回 rtmp 拉流地址列表(可以返回 master 为 ture 及 false 的 rtmp 拉流地址),该列表可以包含主讲的共享画面的拉流地址,从而可以显示主讲的共享画面。

subscribe

使用 qiniu-wx-player 组件中 <player> 订阅流,加入房间之后我们可以调用 subscribe 返回一个 rtmp 拉流地址。 下面我们使用了 wx:for 遍历 data.subscribeList 渲染一个订阅的列表。

<!-- index.wxml -->
<player
  autoplay
  wx:key="{{item.key}}"
  wx:for="{{subscribeList}}"
  min-cache="0.2"
  max-cache="0.8"
  src="{{item.url}}"
  mode="RTC"
>
</player>

一般来说有两个地方会触发订阅:

  1. joinRoomWithToken 之后;
  2. 监听 track-add 事件的回调中。

接下来我们实现一个自动订阅的逻辑:

// index.js
 
Page({
  data: {
    subscribeList: [],
  },
  subscribe(playerid) {
    const path = session.subscribe(playerid)
    if (path) {
      const sub = this.data.subscribeList.filter(v => v.key !== playerid)
      sub.push({
          url: path,
          key: playerid,
        })
      this.setData({
        subscribeList: sub,
      })
    }
  },
  onLoad() {
    // 1. joinRoom 之后订阅
    session.joinRoomWithToken(roomToken)
      .then(() => {
        // 加入房间成功,接下来可以调用 session.publish 和 session.subscribe
        session.users
          .filter(v => v.playerid !== app.session.userId)
          .forEach(v => {
            this.subscribe(v.playerid)
          })
      })

    // 2. 事件 track-add 之后订阅
    session.on('track-add', (tracks) => {
      console.log('track-add', tracks)
      const set = {}
      for (const track of tracks) {
        // 每个 playerid 只订阅一次
        if (!set[track.playerid]) {
          set[track.playerid] = true
          this.subscribe(track.playerid)
        }
      }
    })
  }
})

getSubscribeAddressList

使用 qiniu-wx-player 组件中 <player> 订阅流,加入房间之后我们可以调用 getSubscribeAddressList 返回 rtmp 拉流地址列表,该列表可以包含主讲的共享画面的拉流地址,从而可以显示主讲的共享画面。 下面我们使用了 wx:for 遍历 data.subscribeList 渲染一个订阅的列表。

<!-- index.wxml -->
<player
  autoplay
  wx:key="{{item.key}}"
  wx:for="{{subscribeList}}"
  min-cache="0.2"
  max-cache="0.8"
  src="{{item.url}}"
  mode="RTC"
>
</player>

一般来说有两个地方会触发订阅:

  1. joinRoomWithToken 之后;
  2. 监听 track-add 事件的回调中。

接下来我们实现一个自动订阅的逻辑:

// index.js
 
Page({
  data: {
    subscribeList: [],
  },
  subscribe(playerid) {
    const addressList = session.getSubscribeAddressList(playerid)
    if (addressList.length > 0) {
      const sub = this.data.subscribeList.filter(v => v.userid !== playerid)
      const urlList = []
      addressList.forEach(((item, index)=> {
        urlList.push(Object.assign({}, item, {
          key:playerid + Math.random().toString(36).slice(-8),
          userid:playerid
        }))
      }))
      urlList.forEach(e => {
        sub.push(e)
      })
      this.setData({
        subscribeList: sub,
      }, () => {
        console.log('subscribeList:', this.data.subscribeList)
      })
    }
  },
  onLoad() {
    // 1. joinRoom 之后订阅
    session.joinRoomWithToken(roomToken, userData)
      .then(() => {
        // 加入房间成功,接下来可以调用 session.publish 和 session.getSubscribeAddressList
        session.users
          .filter(v => v.playerid !== app.session.userId)
          .forEach(v => {
            this.subscribe(v.playerid)
          })
      })

    // 2. 事件 track-add 之后订阅
    session.on('track-add', (tracks) => {
      console.log('track-add', tracks)
      const set = {}
      for (const track of tracks) {
        // 每个 playerid 只订阅一次
        if (!set[track.playerid]) {
          set[track.playerid] = true
          this.subscribe(track.playerid)
        }
      }
    })
  }
})

合流

合流操作中涉及 createMergeJob, updateMergeTracks, stopMerge 三个操作。应该先调用 createMergeJob 创建合流的任务。接着在合流任务中添加/删除媒体流,此时在合理任务对应的订阅流中已经能够看到合流后的效果。最后调用 stopMerge 来停止合流。考虑到一般用户添加和删除媒体流操作一般不同时进行,另外添加了 addMergeTracks 和 removeMergeTracks 两个接口方便用户操作。

  • createMergeJob 创建合流任务,需要指定发布流地址、任务ID,媒体宽、高等,此外还可以指定水印、背景等信息。
  • updateMergeTracks 更新合流中的媒体流。添加时,需要指定媒体流的 trackid、宽(w)、高(h)、横轴偏移(x)、纵轴偏移(y)、深度偏移(z)、画面填充方式( stretchMode,可选值,为空继承 createMergeJob 中 stretchMode 的值)。删除时,只需要指定 trackid 。
  • addMergeTracks 合流任务中添加媒体流
  • removeMergeTracks 合流任务中删除媒体流
  • stopMerge 停止合流,需要指定合流任务的 ID

涉及到的相关信息

  • 媒体流:session实例中的 tracks 为远程媒体流,包括所有连上麦的其他用户的媒体流, localTracks 为本地媒体流,连上麦以后才能获到。
  • 合流任务:session实例中的 mergeJobs 包含了本次回话中创建的所有的合流任务。调用 stopMerge 或者回话结算后,合流任务自动销毁。
  const mergeJobParam = {
    id: '1234',
    publishUrl: 'rtmp://10.200.20.28:1935/devtest/merge_test_job?domain=pili-publish.devtest.qbox.net',
    width: 480,
    height: 320,
    x: 0,
    y: 0,
    fps: 60,
    kbps: 1000
  }

  function createMergeJob() {
    session.createMergeJob(mergeJobParam.id, mergeJobParam)
  }

  function addMergeTracks() {
    // 获取所有远程媒体流和本地媒体流
    const allTracks = session.tracks.concat(session.localTracks)
    const addTracks = allTracks.map((track, idx) => ({ trackid: track.trackid, w: 200, h: 120, x: 0, y: 120 * idx  }) )
    session.addMergeTracks(addTracks, mergeJobParam.id)
  }

  function removeMergeTracks() {
    // 获取所有远程媒体流和本地媒体流
    const allTracks = session.tracks.concat(session.localTracks)
    const removeTracks = allTracks.map(track => ({ trackid: track.trackid }) )
    session.removeMergeTracks(removeTracks, mergeJobParam.id)
  }

  function stopMerge() {
    session.stopMerge(mergeJobParam.id)
  }

离开房间

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

Page({
  onUnload() {
    session.leaveRoom()
  }
})

断网重连

SDK 会承担一部分重连工作,当 SDK 自动重连失败时(比如RoomToken过期),会抛出 error 事件。 此时应该重新获取 RoomToken 再 joinRoom。

session.on('error', () => {
  // 重新获取 RoomToken -> joinRoom
  reconnect()
})
// 注意一定在 reconnected 事件后重新推流与拉流,SDK自动重连之后也会触发 reconnected 事件
session.on('reconnected', () => {

  pushContext.start({
    success: () => {
      console.log('推流成功')
    },
    fail: () => {
      console.log('推流失败')
    },
  })
  for (const track of this.data.subscribeList) {
    const ctx = wx.createLivePlayerContext(track.key)
    if (ctx) {
      ctx.play()
    }
  }
})

结语

到了这里我们已经了解 SDK 的基本使用方式。 更多请参考我们的 github 开源 Demo

← 开发准备模块 →
  • 初始化房间并加入房间
  • 发布流
  • 订阅流
    • subscribe
    • getSubscribeAddressList
  • 合流
  • 离开房间
  • 断网重连
  • 结语
七牛实时音视频云 微信小程序 SDK
文档
快速开始API 参考
其他平台
QiniuRTN iOS SDKQiniuRTN Android SDKQiniuRTN Windows SDKQiniuRTN Web SDKQiniuRTN
更多
GitHubStar
Copyright © 2022 Qiniu Hermes Team