客户端旁路混流

通常阿里云建议您使用服务端OpenAPI旁路转推来管理旁路转推任务,如果您不希望通过服务端OpenAPI的方式来管理旁路转推,本文将说明如何使用客户端SDK的接口来管理旁路转推任务。

开启旁路转推

开启旁路转推后,音视频将被转推至阿里云的直播中心源站,您可以基于播放域名配置转码、录制、截图等功能,或进行直播拉流观看。

  1. 登录视频直播控制台

  2. 单击左侧导航栏场景服务 > 实时音视频 > 应用管理,选择需要配置的应用,单击对应操作列管理

  3. 单击旁路转推,您可以选择以下方式配置旁路转推。

  4. 开启旁路转推开关配置转推参数:

    image

    参数

    配置选项

    参数含义

    播放域名

    示例:play.example.com

    转推至标准直播后的播放域名,可以基于此域名播放直播流、配置转码、录制等。若您还没有播放域名,请去域名管理添加,具体操作请参见添加域名

    说明

    播放域名不能开启超低延时直播RTS2.0,否则将会导致转推失败。

    AppName

    默认为live,允许自定义。

    转推后直播流地址中的AppName,若您需要为转推后的流绑定转码、录制、截图等模板,需要设置该AppName与模板中的AppName一致模板才会生效。

    全局自动SEI设置

    • 定时插入SEI:根据指定时间间隔,定时插入SEI帧,允许设置时间为1000ms~5000ms。

    • 在I帧中插入SEI:在视频流的I帧中插入SEI。

    媒体补充增强信息(SEI) : 将用户的基本信息如uid、混流布局参数等通过系统SEI的形式插入流中。例如直播连麦场景中,当混流转推布局发生变化时,对于麦下直播观众的APP可以实时解析SEI中的布局信息,以便调整交互样式 。具体请参见媒体增强信息(SEI)格式

获取MPUTaskId

import md5 from 'md5';

const genMPUTaskId = (appid?: string, channel?: string, userId?: string) => {
  if (!appid || !channel || !userId) return '';

  const SDK_PLAY_DOMAIN = 'live.aliyun.com';
  const prefix = 'rtmp://';

  const stream = `${appid}_${channel}_${userId}_camera`;
  const url = `${prefix}${SDK_PLAY_DOMAIN}/live/${stream}`;

  return `AL-${md5(url)}`;
};

更新旁路任务

mixedtrue表示单流切混流,传false表示混流切单流。

展开查看代码

import {
  AliRtcLiveTranscodingParam,
  AliRtcLiveTranscodingMixMode,
  AliRtcLiveTranscodingTaskProfile,
  AliRtcLiveTranscodingCropMode,
  AliRtcLiveTranscodingMediaProcessMode,
  AliRtcLiveTranscodingEncodeParam,
  AliRtcTranscodingUser,
  AliRtcLiveTranscodingMixParam,
} from 'aliyun-rtc-sdk';

// instance 为 AliRtcEngine 实例,需要先创建
const updateStream = (mixed: boolean) => {
    if (!instance) {
      message.error('请先实例化引擎');
      return;
    }
    if (!instance.isInCall()) {
      message.error('请先调用 joinChannel 入会');
      return;
    }
    const { appId, channelId, userId } = useStore.getState();
    const taskId = genMPUTaskId(appId, channelId, userId);
    const param = new AliRtcLiveTranscodingParam();
    if (mixed) {
      param.mixMode = AliRtcLiveTranscodingMixMode.LiveTranscodingMix;
      const mixParam = new AliRtcLiveTranscodingMixParam(
        AliRtcLiveTranscodingTaskProfile.LiveTranscoding_Profile_9IN_1080P,
      );
      const width = 1920;
      const height = 1080;
      const screen = new AliRtcTranscodingUser(
        userId!,
        0,
        0,
        width,
        height,
        1,
        1,
      );
      const camera = new AliRtcTranscodingUser(
        userId!,
        width - width / 4 - 10,
        10,
        width / 4,
        height / 4,
        2,
      );
      mixParam.encodeParam = new AliRtcLiveTranscodingEncodeParam(
        width,
        height,
      );
      mixParam.users = [screen, camera];
      param.mixParam = mixParam;
      console.log('param', param);
    } else {
      param.mixMode = AliRtcLiveTranscodingMixMode.LiveTranscodingSingle;
      param.singleParam = new AliRtcLiveTranscodingSingleParam(
        userId,
        AliRtcLiveTranscodingStreamType.LiveTranscodingOrigin,
      );
    }
    instance
      .updatePublishLiveStreamWithTaskId(taskId, param)
      .then(() => {
        message.success('更新成功');
      })
      .catch((err) => {
        message.error(`更新失败: ${err.message}`);
      });
  };