Client-side stream relay and mixing

更新时间:
复制 MD 格式

You can use the client-side SDK to manage stream relay and stream mixing tasks directly from your application, instead of using server-side API operations. For the server-side approach, see stream relay.

Enable stream relay

After you enable stream relay, audio and video streams are relayed to an Alibaba Cloud ApsaraVideo Live origin server. You can then use a streaming domain to play the live stream and configure transcoding, recording, and snapshot capture.

  1. Log in to the ApsaraVideo Live console.

  2. In the navigation pane on the left, choose Live + > ApsaraVideo Real-time Communication > Applications. Find your application and click Manage in the Actions column.

  3. Click Stream Relay.

  4. Turn on the Stream Relay switch, and configure the following parameters:

    Parameter

    Value

    Description

    Streaming Domain

    Example: play.example.com

    The streaming domain used to play the relayed live stream and configure transcoding and recording. If you do not have one, go to Domain Management to add one. For instructions, see Add a domain name.

    Note

    Do not enable the half-second latency mode for Real-Time Streaming (RTS) on the streaming domain. Otherwise, the stream relay will fail.

    AppName

    Default value: live. You can specify a custom name.

    The AppName in the URL of the relayed live stream. To apply transcoding, recording, or snapshot capture templates to the stream, this AppName must match the one specified in the templates.

    Global SEI Settings

    • Insert SEI at Regular Intervals: Inserts SEI frames at a specified interval from 1,000 ms to 5,000 ms.

    • Insert SEI in I-frames: Inserts SEI into the I-frames of the video stream.

    Supplemental enhancement information (SEI): Embeds user information, such as user IDs and stream mixing layout parameters, into the video stream. In a co-streaming scenario, the client application can parse SEI data in real time to adjust the UI when the layout changes. For more information, see Supplemental enhancement information (SEI) format.

Generate the 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)}`;
};

Update a stream relay task

To switch between single-stream relay and stream mixing, set the mixed parameter to true for stream mixing or false for single-stream relay.

Show code

import {
  AliRtcLiveTranscodingParam,
  AliRtcLiveTranscodingMixMode,
  AliRtcLiveTranscodingTaskProfile,
  AliRtcLiveTranscodingCropMode,
  AliRtcLiveTranscodingMediaProcessMode,
  AliRtcLiveTranscodingEncodeParam,
  AliRtcTranscodingUser,
  AliRtcLiveTranscodingMixParam,
  AliRtcLiveTranscodingSingleParam,
} from 'aliyun-rtc-sdk';
// 'instance' is an AliRtcEngine instance that you must have already created.
const updateStream = (mixed: boolean) => {
    if (!instance) {
      message.error('Instantiate the engine first.');
      return;
    }
    if (!instance.isInCall()) {
      message.error('Call joinChannel to join a channel first.');
      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('Update successful.');
      })
      .catch((err) => {
        message.error(`Update failed: ${err.message}`);
      });
  };