进阶用法

本文为您介绍Web RTS推流SDK的其他使用方法。

浏览器兼容性检查

可以检测当前浏览器环境是否支持相应的推流及采集能力。

说明

这是一个静态方法,可以在AliRTSPusher上直接调用,无需实例化。

const checkResult = await AliRTSPusher.checkSupport();
console.log('checkResult: ', checkResult);

检查结果,请参见 ISupportResult

设备管理

可以获取当前浏览器可以获取到的麦克风列表和摄像头列表。

const deviceManager = await pushClient.getDeviceManager();
// 获取摄像头列表
const cameraList = await deviceManager.getCameraList();
// 获取麦克风列表
const micList = await deviceManager.getMicList();

详细信息,请参见API DeviceManager

关注推流状态

通过监听connectStatusChange事件,请随时关注推流网络状态,给出相应提示,必要时做重试处理。

pushClient.on('connectStatusChange', (event) => {
  switch (event.status) {
    case 1:
      // 连接中
      break;
    case 2:
      // 已连接
      break;
    case 3:
      // 自动重连中,注意此时推流已暂时中断,应及时提示用户
      break;
    case 0:
      // 连接中断,推流结束,应提示用户,必要时重新调用 startPush 进行推流
      break;
  }
})

详细信息,请参见状态枚举 EConnectStatus

混流模式下设置推流码率

目前混流模式下setMixingConfig尚不支持设置最大码率,可以通过以下方式设置:

/**
 * 设置码率、发送帧率(请在推流成功后再调用)
 * @param pushClient 当前推流sdk实例
 * @param config 码率、帧率设置
 * @param config.maxBitrate 最大码率(kbps)
 * @param config.maxFramerate 最大帧率
 *
 *
 * @example
 * ```ts
 * setSenderParams(aliPusher, { maxBitrate: 3000, maxFramerate: 20 })
 * ```
 */

function setSenderParams(pushClient, config) {
  const pcm = pushClient.publisher?.peerconnection;
  if (pcm) {
    pcm.setVideoSenderParams(config);
  }
}

如何在推流中切换摄像头?

如果在推流过程中需要在不同摄像头之间切换(如摄像头A切换到摄像头B),可以参考以下操作:

非混流模式

  1. 获取可用的摄像头列表:

    const deviceManager = pushClient.getDeviceManager();
    // cameraList 中包含每个摄像头的 deviceId
    const cameraList = await deviceManager.getCameraList();
  2. 通过 startCamera 切换目标摄像头即可:

    // 如果正在使用摄像头A推流中,需要切换成摄像头B
    await pushClient.startCamera(deviceId); // 传入摄像头B的 deviceId 即可

混流模式

混流模式下,每一个摄像头、屏幕共享画面都是通过图层(layout)进行共享或播放的。若您需要切换摄像头,您只需要关闭摄像头A(SDK 会自动删除 A 的图层),并开启摄像头B、设置 B 图层的位置、大小即可完成切换。

  1. 关闭摄像头A:

    // 注意传参是 streamId 不是 deviceId,streamId 是之前摄像头A startCamera() 的返回值
    pushClient.stopCamera(streamIdA);
  2. 开启摄像头B

    const streamIdB = await pushClient.startCamera(deviceId); // 传入摄像头B的 deviceId
  3. 设置B图层的位置大小:

    videoEffectManager.setLayout([
      { streamId: streamIdB, x: 1280/2, y: 720/2, width: 1280, height: 720, zOrder: 1 }, // 按照需要设置摄像头B的大小
      ... // 其它图层设置
    ]);
说明

在不同屏幕共享中切换也是一样的原理,可参考上述摄像头切换方式操作。

在Vue3中使用

Vue3的响应式状态ref()会对对象进行深层次解包,将每一个子对象嵌套ref,这会导致推流实例对象的内部结构异常。请不要使用ref()来保存推流SDK的实例对象,可以改为使用一个普通的变量,或者shallowRef()。示例如下:

使用变量

<script setup lang="ts">
  import { onMounted } from 'vue';
  import { AliRTSPusher } from 'aliyun-rts-pusher';
  import type { RtsClient } from 'aliyun-rts-pusher';

  let pushClient: RtsClient;
  onMounted(() => {
    pushClient = AliRTSPusher.createClient();
  })
</script>

使用shallowRef

<script setup lang="ts">
  import { onMounted, shallowRef } from 'vue';
  import { AliRTSPusher } from 'aliyun-rts-pusher';
  import type { RtsClient } from 'aliyun-rts-pusher';

  const pushClient = shallowRef<RtsClient>();
  onMounted(() => {
    pushClient.value = AliRTSPusher.createClient();
  })
</script>

在 Electron 中进行屏幕共享

您可以下载示例代码

解压后示例代码目录如下:

+---demo-rts-pusher-electron
|       index.html ##html页面
|       main.js ##主进程初始化js,包含获取屏幕共享的sources
|       package-lock.json
|       package.json
|       preload.js
|       README.md
|       renderer.js ##渲染进程js,包含如何接收主进程传递的sources,创建屏幕共享并推流

获取屏幕共享源

若在 Electron 中进行屏幕共享,需要先获取屏幕共享源,可参考main.js中以下代码。更多获取屏幕共享源说明,请参见Electron获取屏幕共享源

  desktopCapturer.getSources({ types: ['screen', 'window'] })
    .then(async (sources) => {
      win.webContents.send('SET_SOURCE', sources);
    })
    .catch(e => {
      console.log(e);
    })
说明
  • 获取到源之后,才能在navigator.mediaDevices.getUserMedia中指定 chromeMediaSourceId 使用。如果您的业务不需要指定特定的共享源,可以不用获取屏幕共享源,由系统默认共享当前窗口。

  • 一般情况下我们建议您通过获取共享源列表,让使用者可以自主选择需要的共享源。

采集

renderer.js中包含采集代码

// 开始采集按钮
$startBtn.addEventListener('click', async () => {
 
  // 传过来的 sources
  console.log('ELECTRON API', window.electronAPI.sources);
  const sources = window.electronAPI.sources;

  const cameraStreamId = await pushClient.startCamera();
  const micStreamId = await pushClient.startMicrophone();

  // 屏幕共享的方案:使用原生 getUserMedia 获取流,然后使用 addCustomStream 方法添加到 sdk 中
  const stream = await navigator.mediaDevices.getUserMedia({
      video: {
        mandatory: {
          chromeMediaSource: 'desktop',
          // chromeMediaSourceId: sources[0].id,
          minWidth: 1280,
          maxWidth: 1280,
          minHeight: 720,
          maxHeight: 720
        }
      },
      // 注意:如果捕获屏幕声音,请不要开启本地预览的<video>声音,否则会因为循环采集造成回声,请保持<video>静音,正常推流,然后使用拉流地址进行拉流预览
      // audio: {
      //   mandatory: {
      //     chromeMediaSource: 'desktop',
      //   }
      // }
  });
  const screenStreamId = await pushClient.addCustomStream(stream);

  // 摄像头左上角,屏幕共享居中
  videoEffectManager.setLayout([
    { streamId: screenStreamId, x: 1280/2, y: 720/2, width: 1280, height: 720, zOrder: 1 },
    { streamId: cameraStreamId, x: 320/2, y: 180/2, width: 320, height: 180, zOrder: 2 },
  ]);
})
说明
  • pushClient.startCamera()采集摄像头。

  • pushClient.startMicrophone()采集麦克风。

  • 更多使用说明,请参见接口说明

推流

renderer.js包含推流代码,您可能需要直播地址生成器

// 开始推流按钮
$publishBtn.addEventListener('click', () => {
  pushClient.startPush('artc://xxxx');
})