Plugin integration

Updated at:

This topic describes how to integrate the ApsaraVideo Real-time Communication plugin for Alipay mini programs.

The plugin supports three integration modes:

  • Full screen: When invoked, the plugin automatically redirects to the full-screen video call page.

  • Flex: Embed the video call interface into a specific area of your miniapp.

  • Answer: Embed the video call interface into a specific area of your miniapp. You can customize and overwrite existing UI styles. This mode cannot be used with the Flex mode.

Note

  • If you disable both the camera and microphone in the configuration, the subscription fails. The client logic requires at least one of them to be enabled.

  • When you import the component, it guides you through the permission settings for the microphone and camera. The component also provides a method to check permissions before use.

Full-screen mode (called using JS API)

Sample code

const { rtc } = requirePlugin('rtc')

// A video call has two roles:
// - Initiator: The person who starts the video call.
// - Participant: The person who joins the call.

// Flow
// - 1. The initiator calls start(config) to get the roomId and token.
// - 2. Send the roomId and token to participants through channels such as push notifications or text messages.
// - 3. Other participants invoke the plugin and call join(roomId, config) to join the call.

// The initiator calls this API.
rtc.start(config).then(roomInfo => {
  const { roomId, token } = roomInfo
  // Get the created roomId and token for other participants to use.
})

// ======================

// Participants call this API.
rtc.join(roomId, config) // config is a required parameter. 
Note

For more information about the config parameter, see Config parameters.

Call flow

A video call has two roles: an initiator and participants.

  • The initiator starts a video call by invoking start(config) to obtain a roomId and a token.

  • Send the roomId and token to participants through channels such as push notifications or text messages.

  • Other participants invoke join(roomId, config) to join the call.

API reference

const { rtc, EventType } = requirePlugin('rtc')
  • Start a video call: start(config: Config): Promise<RoomInfo>.

  • Join a video call: join(roomId: string, config: Config): Promise<RoomInfo>.

  • Listen for call events: on(type: EventType, handler: data => void).

Methods to get RoomInfo

One user initiates a video call and obtains the RoomInfo object. Other participants use this object to join the call. You can use one of the following two methods to obtain the RoomInfo object.

  • Use the API call. The call returns a Promise<RoomInfo>.

    rtc.start(config).then(roomInfo => {
      const { roomId, token } = roomInfo
      // Get the created roomId and token for other participants to use.
    })
  • This is obtained from the ROOM_CREATED event.

    rtc.on(EventType.ROOM_CREATED, data => {
      // Get the roomId and token created by the initiator for other participants to use.
      const { roomId, token } = data
    })

Flex mode (called using a component)

Import the component

{
  "usingComponents": {
    "rtc": "plugin://rtc/flex"
  }
}

Use the component

<rtc
  config="{{ config }}"
  currentUserId="{{ currentUserId }}"
  onPlayerChange="handlePlayerChange"
  onUserChange="handleUserChange"
  onHangup="handleHangup"
  onError="handleError"
/>
  • For more information about the config object, see Key parameters.

  • currentUserId: Pass a userId to this parameter to switch the currently playing stream.

  • onPlayerChange(userId: string, preUserId: string): void: The event that is triggered when the video playback switches to a different user.

  • onUserChange(state: UserState): void: The event that is triggered when a user's state changes.

  • onError(error: Error): void: A general error event.

  • onHangup(): void: The event that is triggered when a user hangs up.

interface UserState {
  joined: string[]  // List of users who joined
  exited: string[]  // List of users who exited
  users: string[]   // List of users in the current channel
  current?: string  // ID of the user whose stream is currently playing
}

API Operation

const { rtc, EventType } = requirePlugin('rtc')
  • Start a video call: start(config: Config): Promise<RoomInfo>.

  • Join a video call: join(roomId: string, config: Config): Promise<RoomInfo>.

  • Listen for call events: on(type: EventType, handler: data => void).

  • Invite a user: invite(userId: string, data?: InviteInfo): Promise<Result>.

For more information about the Config object, see Key parameters.

  • InviteInfo

The following optional parameters for the invite interface specify the content displayed to the invitee.

interface InviteInfo {
  nickName?: string // Inviter's nickname
  page?: string // Landing page of the miniapp
  inviteType?: InviteType // Invitee type (0: web, 1: app). Default is 1.
  roomType?: RoomType // Channel type (1: audio and video call, 2: audio-only call). Default is 1.
  params?: Record<string, unknown> | null
}

Answer mode (called using a component)

Import the component

{
  "usingComponents": {
    "answer": "plugin://rtc/answer"
  }
}

Use the component

<answer
  screenname="{{screenname}}" // Overwrites the class name of the screen. Default: 'screen'.
  namespace="{{namespace}}" // Class name for UI styles. Default: "answer".
  config="{{ config }}"
  currentUserId="{{ currentUserId }}"
  onPlayerChange="handlePlayerChange"
  onUserChange="handleUserChange"
  onHangup="handleHangup"
  onError="handleError"
/>

Specify the CSS styles that you want to overwrite in the project's app.acss file.

/* CSS to overwrite */
.screen {
  position: relative;
  background: rgba(31,33,41,0.95);
}
.screen.full {
  height: 100vh;
}
.screen.full .content {
  height: 100vh;
}
.screen.flex {
  height: 100%;
}
.screen.flex .content {
  height: 100%;
}
.screen .content {
  position: relative;
}
.screen .actions {
  position: absolute;
  bottom: 100rpx;
  height: 260rpx;
  width: 100%;
  display: flex;
}
.screen .actions .action {
  flex: 1;
  height: 100%;
  position: relative;
}
.answer .pusher-view,
.answer .player-view {
  width: 100%;
  height: 100%;
}
.answer .pusher-view.mini,
.answer .player-view.mini {
  position: absolute;
  top: 168rpx;
  right: 4px;
  width: 240rpx;
  height: 426rpx;
  z-index: 1;
}
.answer .pusher-view.hidden,
.answer .player-view.hidden {
  width: 0;
  z-index: -999;
}
.answer .pusher-view .message,
.answer .player-view .message {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(31,33,41,0.95);
  color: #fff;
}
.answer .live-player,
.answer .live-pusher {
  width: 100%;
  height: 100%;
}
.answer .user-list {
  white-space: nowrap;
  position: absolute;
  display: flex;
  bottom: 360rpx;
  height: 180rpx;
  width: 100%;
}
.answer .user-list-item {
  width: 160rpx;
  height: 160rpx;
  margin: 0 10rpx;
  background: #333;
  overflow: hidden;
  flex-shrink: 0;
  flex-grow: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 8px;
}
.answer .user-list-item:first-child {
  margin-left: 25rpx;
}
.answer .user-list-item:last-child {
  margin-right: 25rpx;
}
.answer .user-list-item-text {
  color: #fff;
  word-wrap: break-word;
}
.answer .user-list-item.selected .user-list-item-text {
  color: #1677ff;
}
.answer .btn {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  width: 106rpx;
  height: 106rpx;
  line-height: 106rpx;
  border-radius: 50%;
  text-align: center;
  color: #fff;
  background: #262a32;
}
.answer .btn .icon {
  width: 50%;
  height: 50%;
  margin: 25% auto;
}
.answer .btn-mute .icon {
  background: url("xxxx") center center no-repeat;
  background-size: contain;
}
.answer .btn-mute .icon.disable {
  background: url("xxx") center center no-repeat;
  background-size: contain;
}
.answer .btn-speaker .icon {
  background: url("xxx") center center no-repeat;
  background-size: contain;
}
.answer .btn-camera .icon {
  background: url("xxx") center center no-repeat;
  background-size: contain;
}
.answer .btn-camera .icon.disable {
  background: url("xx") center center no-repeat;
  background-size: contain;
}
.answer .btn-hangup {
  background: #fa4b4b;
}
.answer .btn-hangup .icon {
  background: url("xxx") center center no-repeat;
  background-size: contain;
}
.answer .btn-switch-camera .icon {
  background: url("xxx") center center no-repeat;
  background-size: contain;
}
.answer .btn-screenshot .icon {
  background: url("xxx") center center no-repeat;
  background-size: contain;
}

API reference

const { rtc, EventType } = requirePlugin('rtc')
  • Start a video call: start(config: Config): Promise<RoomInfo>.

  • Join a video call: join(roomId: string, config: Config): Promise<RoomInfo>.

  • Listen for call events: on(type: EventType, handler: data => void).

  • Invite a user: invite(userId: string, data?: InviteInfo): Promise<Result>.

  • Check and request permissions: async authCheck().

  • Hang up a call: hangup(roomId?: string): void.

For more information about the Config object, see Key parameters.