Polyv Help Center

Help Center

WeChat Mini Program SDK 3.10

Updated: 2025-08-13 16:34:48

DEMO URL

Demo Download URL

Product Introduction

Overview

The polyv Mini Program SDK provides live streaming playback, on-demand playback, document rendering, and other features for WeChat Mini Programs. It also offers a set of components that allow users to flexibly combine their own business logic.

Configure WeChat Live Streaming Permissions

The SDK uses WeChat's live-player for live streaming and live-pusher for co-hosting. You need to first pass the category review (see WeChat Mini Program SDK Category Application Qualification Requirements), and then enable the corresponding component permissions in the Mini Program Management Console under "Development" - "Interface Settings".

Features

Feature Description
Video Supports live streaming and on-demand video playback. Encrypted videos are not supported.
Document Supports document display and annotation. PPT animations are not supported.
Teaching & Live Interaction Supports voice and video live interaction. Supports 1v1 live interaction.
Online Chat Supports online chat.

Target Audience

This document is a technical document intended for readers who:

  • Have basic mini-program development skills.
  • Are preparing to integrate or have already integrated with POLYV Video Cloud.
  • Have a basic understanding of how to use POLYV Video Cloud.

Usage Steps

Development Preparation

Obtain Access Key

Log in to the POLYV Live Streaming Backend - Cloud Live Streaming - Development Settings - Identity Authentication

WeChat Interface Whitelist Configuration

request合法域名
https://miniapp.agoraio.cn
https://uni-webcollector.agora.io
https://router.polyv.net
https://api.polyv.net
https://prtas.videocc.net
https://rtas.videocc.net
https://hls.videocc.net
https://player.polyv.net
https://livestatic.videocc.net
https://livejson.polyv.net
https://live.polyv.net
https://doc-2.polyv.net
https://doc.polyv.net
https://img.videocc.net
https://liveimages.videocc.net

使用连麦功能需加上以下域名:
https://uap-ap-web-1.agora.io
https://uap-ap-web-2.agoraio.cn
https://uap-ap-web-3.agora.io
https://uap-ap-web-4.agoraio.cn
https://report-ad.agoralab.co
https://rest-argus-ad.agoralab.co
https://uni-webcollector.agora.io

https://cloud.tencent.com
https://yun.tim.qq.com
https://webim.tim.qq.com

socket合法域名
wss://chat.polyv.net
wss://miniapp.agoraio.cn

SDK Usage

The SDK uses TypeScript code, so you need to download the latest developer tools to support it. Native TypeScript Support

The SDK provides custom components. Polyv offers a complete set of business logic for users to use out of the box. It also provides player components, PPT document components, chatroom components, etc., allowing users to flexibly combine their own business logic.

Before use, you need to call the setApp method in app.js的onLaunch中.

import plv from '*/sdk/core/index';
onLaunch() {
    plv.setApp({
        apiId: '',
        verifyUrl: ''
    });
}
verifyUrl Verification Interface Rules

(1) When the mini-program requests the verifyUrl interface, it will include the following parameters (the number of parameters/parameter names are not fixed). All parameters except the sign parameter must be sorted alphabetically, then combined with the appSecret according to the rules for MD5 encryption, and the result should be returned to the mini-program.

Request Parameter Description
Parameter Name Type Description
appId string Account appId [See Obtaining Secret Key]
timestamp number 13-digit millisecond-level timestamp
sign string verifyUrl verification sign reference (2) verifyUrl verification
Response Parameter Description
Parameter Type Description
code Integer Response status code, 200 for success, non-200 for failure [see Global Error Description]
status String Response status text
message String Response description, when code is 400 or 500, provides additional error details
data Object Returns account available live streaming minutes on success [see data field description]

verifyUrl API PHP Code Example:

<?php
$appSecretKey = 'Your appSecretKey';
$sign = $_GET['sign'];
$appId = $_GET['appId'];
$timestamp = $_GET['timestamp'];

// 获取url query并转换成数组
parse_str($_SERVER["QUERY_STRING"], $params);

// 获取除sign外的其他参数的拼接字符串
$concated = sort_param($params);

// STEP 1
// 计算接口请求是否合法
$outPutData = '';

$verifyUrlSign = strtoupper(md5("plyMinApp".$concated."plyMinApp"));
if ($sign != $verifyUrlSign) {
  $outPutData = '{"code": 200, "message" : "invalid sign", "status": "error", "data": ""}';
  echo($outPutData);
  return;
}

// STEP 2
// 输出正确sign返回给小程序
$outPutSign = strtoupper(md5($appSecretKey.$concated.$appSecretKey));
$outPutData = '{"code": 200, "message" : "", "status": "success", "data": {"sign": "'.$outPutSign.'"}}';
echo($outPutData);


/**
 * 将参数按照ASCKII升序 key + value + key + value ... +value 拼接
 * @return [type] [description]
 */
function sort_param($params){

  ksort($params);

  $sort_result = "";

  foreach ($params as $key => $val) {
    if(!is_null($val) && $key != 'sign'){
      $sort_result=$sort_result.$key.$val;
    }
  }
  return $sort_result;
}

?>

(2) verifyUrl validation

Sign Verification Rules:

  1. concated takes the value of concatenating the parameters appId, timestamp, and other parameters in ascending ASCII order as key + value + key + value ... + value.

  2. verifyUrlSign value: plyMinApp${concated}plyMinApp uppercase MD5 value after string concatenation

$verifyUrlSign = strtoupper(md5("plyMinApp".$concated."plyMinApp"));

Successful Example

{
    "code":200,
    "status":"success",
    "message":"",
    "data":{
        "sign":"3DDE7222C4264F225931053A661889BA"
    }
}

Exception Example

{
    "code": 400,
    "status": "error",
    "message": "invalid signature.",
    "data": ""
}

Method 2: Pass the access key of the Polyv Cloud Live Streaming

Since the apiSecret is displayed in plaintext in the mini-program code, there is a risk of the mini-program being decompiled. Therefore, Method 1 is recommended.

import plv from '*/sdk/core/index';
onLaunch() {
    plv.setApp({
        apiId: '',
        apiSecret: ''
    });
}

Using Components

1. Using the polyv component. Refer to the polyv directory in the demo.

  1. Copy the SDK code into your own project, and import the component in the JSON file of the page that uses the SDK.

    {
      "usingComponents": {
         "polyv": "*/sdk/components/polyv/polyv"
      }
    }
    
  2. Using polyv components in wxml

    <view>
        <polyv />
    </view>
    
  3. Call the init method in the page's onload and the destroy method in onUnload.

The init method initializes the viewing process, retrieves channel details, initializes socket events, and so on.

import plv from '*/sdk/core/index';
// onLoad
onLoad() {
    const options = {
      channelId: '', // 频道ID
      openId: '', // 用户openId
      userName: '', // 用户名
      avatarUrl: '', // 用户头像
      param4: '', // 自定义参数
      param5: '', // 自定义参数
    };
    plv.init(options);
}
// onUnload
onUnload() {
   plv.destory();
 }

2. Flexible Component Composition. Refer to the demo's polyv-sub.

  1. Import the component in the JSON file of the page that uses the SDK.

    {
      "usingComponents": {
         "player": "*/sdk/components/player/player",
            "ppt": "*/sdk/components/ppt/ppt",
         ...
      }
    }
    
  2. Use the component in WXML and pass the necessary parameters.

    <view>
        <player
       videoOption="{{ videoOption }}"
       bind:onLiveStatusChange="playerLiveStatusChange"
     />
        <ppt />
    </view>
    
  3. Call the init method in the page's onload method.

    import plv from '*/sdk/core/index';
    Page({
        onLoad() {
            const options = { ... };
            options.plvInsideUse = true; // 区分是学一学还是sdk, 当为 true 时开启抽奖模块。
            plv.init(options)
                .then(data => {
                    const { detail, chat } = data;
                   // 处理业务逻辑
                })
                .catch(err => {
                            // 异常处理
                });
        },
        onUnload() {
           plv.destory();
        }
    });
    

Component Details

Before using the following components, you must first introduce them in the JSON through the usingComponents field.

1. polyv Component

Parameter Introduction

Parameter Type Required Default Description
userBanned Event No - Triggered when user is kicked out
onError Event No - An error occurred
allowDanmu Boolean No true Whether to allow danmaku
skinAlwaysShow Boolean No false Whether to always show player skin
usePlayerSkin Boolean No true Whether to use player skin
 <polyv
   bind:userBanned="handleUserBanned"
   bind:onError="handlePolyvError"
   allowDanmu="{{ false }}"
   skinAlwaysShow="{{ true }}"
   usePlayerSkin="{{ false }}"
   hasAnswerCard="{{ true }}"
 />

2. Player Component

The player component can play both live and on-demand content. Live streaming uses live-player, 模拟器不能播放,查看效果请用真机。 while the on-demand simulator cannot play 加密视频,查看效果请用真机。.

Parameter Introduction

Parameter Type Required Default Description
videoOption Object Yes Empty Player initialization parameters (see JS code below)
vodSeek Number No 0 Seek operation time point for playback video (effective only when mode is vod or during temporary storage)
onLiveStatusChange Event No - Live stream status (triggered when mode is live)
onLiveStorageProgress Event No - Current playback time of live temporary storage
onVodProgress Event No - Current playback time of VOD playback
onVodEnd Event No - VOD playback ended
onError Event No - An error occurred
allowDanmu Boolean No true Whether to allow danmaku
skinAlwaysShow Boolean No false Whether to always show the player skin
usePlayerSkin Boolean No true Whether to use the player skin
hasAnswerCard Boolean No false Whether to use the answer card
Note: The priority of skinAlwaysShow is higher than usePlayerSkin. If skinAlwaysShow is set to true, the usePlayerSkin parameter becomes invalid.
<player
 videoOption="{{ videoOption }}"
 allowDanmu="{{ false }}"
 skinAlwaysShow="{{ true }}"
 usePlayerSkin="{{ false }}"
 bind:onLiveStatusChange="playerLiveStatusChange"
 bind:playerVodProgress="playerVodProgress"
 bind:onVodEnd="playerVodEnd"
 bind:onLiveVodEnd="playerVodEnd"
 bind:onError="playerError"
/>
// ###### 播放直播或者暂存视频 #######
videoOption = {
   mode: 'live',
   uid: userId, // 直播频道uid
   cid: channelId, // 直播频道channelId
   isAutoChange: true, // 自动切换直播和暂存。
   vodsrc: '', // 指定回放地址。有暂存视频的情况下,传入暂存视频的mp4或者m3u8。
   pipMode: '', // 是否使用小窗模式,默认为undefined。相关参数设置详情参考注意2.2
   forceVideo: false, // 是否强制使用video标签作为播放器(播放m3u8),建议使用live-player
   statistics: { // 播放器自定义统计参数, 如需添加param4、param5参数,详情见下面init方法详解
     param1: 'param1', // 用户ID
     param2: 'param2', // 用户昵称
   },
   // logoConfig: {
   //   enable: false, // 是否显示logo
   //   position: 'tl',// logo位置1 左上,2 右上(默认)3左下 4 右下
   //   opacity: 0.5, // 透明度
   //   src: '' // logo图片的url
   // }
};

// 直播状态改变: 只有在mode为live时才会触发。
playerLiveStatusChange(e) {
    const status = e.detail.status;
    if (status === 'live') {
      // 开始直播
    }
    if (status === 'end') {
      // 结束直播
    }
}

// 获取回放播放进度
playerVodProgress(e) {
  console.info(e.detail.currentTime, '----currentTime---');
}

// 播放器异常捕获
playerError(e) {
  console.info(e.detail, '-----e-----');
}

/*
* 回放播放结束事件
* onVodEnd: 点播回放列表播放结束触发,返回当前播放结束点播视频vid
* onLiveVodEnd: 直播暂存播放结束时触发,返回当前暂存视频播放地址
*/
playerVodEnd(e) {
  console.info(e.detail.curVodVid, '---curVodVid---');
}

// ###### 播放点播视频 #######
videoOption = {
    mode: 'vod',
    vodVid: '' // 播回放时vodVid为videoPoolId
};
// 在mode为vod时,从点播切换到直播状态,云课堂和普通直播监听直播开始的方法不同。
// 1. 普通直播通过轮询api.getOrdinaryLiveStatus(stream)获取当前的状态
// 2. 云课堂通过chat.on(chat.events.SLICESTART, () => {})监听直播开始
Note:
2.1 Priority of skinAlwaysShow and usePlayerSkin

skinAlwaysShow takes precedence over usePlayerSkin. If skinAlwaysShow is set to true, the usePlayerSkin parameter becomes invalid.

2.2 pipMode

Parameter Range and Trigger Conditions: Refer to the official API live-player component parameters. According to the official documentation, the base library must be upgraded to version 2.11.0 to support the mini-window feature. It is recommended to log in to the official account platform, go to Settings -> Minimum Base Library Version Settings, and perform the upgrade.

3. PPT Document Component

Parameter Introduction

Parameter Type Required Default Description
chatData Object Yes - Channel details
videoId String No - videoId of current replay
vidCurrentTime Number No - Current replay play time
pptSize Object Yes - Document size { height, width }
<ppt
   chatData="{{ detail }}"
   videoId="{{videoId}}"
   vidCurrentTime="{{vodPlayerProgress}}"
   pptSize='{{pptSize}}'
/>
// 直播时传入chatData
// 播放点播时传入回放的videoId和当前回放播放时间

4. Concat Co-hosting Component

Parameter Introduction

Parameter Type Required Default Description
channelDetail Object Yes - Channel details
applyData Object Yes {show: false, txt: 'Request connection'}
show Event Yes - Room connection status: enabled/disabled
refreshStatus Event Yes - Connection status change: raise hand apply/wait for allow cancel/hang up stop
stop Event Yes - Stop connection
<concat
    id="test"
 channelDetail="{{ channelDetail }}"
    applyData="{{ applyData }}"
    bind:show="handleShowConcatApply"
    bind:refreshStatus="handleRefreshStatus"
    bind:stop="handleStop"
/>
 //js
 // 监听当前房间连麦状态
 // 弃用
 handleShowConcatApply(data) {
   // data.detail.status为open/close
   // open: 当前房间已开启连麦
   // close: 当前房间未开启连麦
 },

 // 监听当前用户连麦状态
 // 只有在房间开启了连麦功能后,用户才能进行连麦
 handleRefreshStatus(data) {
   // data.detail: {
   //  show: true/false, // 是否能连麦
   //  type: 'apply'/'cancel'/'stop', // 当前连麦类型:未举手/已举手/连麦中
   //  txt: '' //对应连麦类型:申请连线/取消申请/挂断连线
   //}
 },

 // 结束连麦
 handleStop(data) {
   console.info(data.detail, '---stop----');
 }
  • apply

Note: The method for controlling co-hosting. Both "Raise Hand" and "Cancel Request" require calling this method. After calling this method, the component will determine the current co-hosting status and trigger the corresponding event.

  • stop

Note: Disconnect the call.

5. Chatroom Component

<chatroom bind:onTapBulletin="handleShowBulletin" />
handleShowBulletin() {
  console.info('===点击聊天室公告按钮触发====');
}
Parameter Type Required Default Description
showBulletin Boolean No true Whether to show the bulletin button
skin String No black Skin (black, white)

6. Quiz Consultation Component

<quiz />

7. Playback History Component

Parameter Introduction

Parameter Type Required Default Description
playbackList Array No [ ] Playback list
nextVod String No '' Current playback videoPoolId
onTapPlayback Event No null Callback function for tapping playback
<playback
    playbackList="{{ playbackList }}"
    nextVod="{{ currentVodId }}"
 bind:onTapPlayback="handlePlayback"
/>
// 回放列表通过api.getPlayBackVideos(channelId)获取
// 播放下一个回放,nextVod传入当前的回放videoPoolId
// 点击某个回放时,通知player播放
handlePlayback(e) {
    const { videoPoolId, videoId } = e.detail;
}

8. Chapter Section Component

Parameter Introduction

Parameter Type Required Default Description
chapterList Array Yes [ ] Chapter list
vodCurTime Number Yes 0 Current play time
onTapChapter Event No Empty Chapter tap callback
<chapter
    bind:onTapChapter="handleChangeChapter"
 vodCurTime="{{ vodPlayerProgress }}"
 chapterList="{{ chapterList }}"
/>
// 回放列表通过api.getChapterRecords(channelId)获取
// vodCurTime: 当前播放器的播放时间
// onTapChapter
handleChangeChapter(e) {
 const chapter = e.detail.chapter;
}

9. menu-custom Custom Menu Component

Parameter Introduction

Parameter Type Required Default Description
parseHtml String Yes Empty Rich text string

10. Sign-in Interactive Feature Component

<sign bind:onSignShow="handleSignShow" />
handleSignShow() {
  console.info('====收到签到开始事件,显示签到弹窗时触发====');
}

11. Question Interactive Function Questionnaire Component

<question zIndex="2000" />
Parameter Type Required Default Description
zIndex Number No - Set popup layer

12. answer-card Interactive Quiz Card Component

<answer-card
  class="c-answer-card"
  answerCardSize="{{ answerCardSize }}"
  bind:onAnswerCardShow="handleShowAnswerCard" />
handleShowAnswerCard() {
  console.info('=====收到答题事件,显示答题卡弹窗时触发====');
}
Parameter Type Required Default Description
answerCardSize Object No Empty Set the answer card popup size { height: 400, width: 750 }
zIndex Number No - Set the popup z-index
class String No Empty Set the component style

13. Lottery Interactive Drawing Component

<lottery zIndex="{{ lotteryIndex }}"/>
Parameter Type Required Default Description
zIndex Number No - Set popup z-index

14. Bulletin Interactive Feature Announcement Component

<bulletin
  show="{{ true }}"
  zIndex="2001"
  bulletinStr="公告显示内容"
  bind:onClose="handleHideBulletin"/>
handleHideBulletin() {
  console.info('===点击关闭公告按钮触发===');
}
Parameter Type Required Default Description
show Boolean Yes false Controls when to display the announcement
bulletinStr String Yes '' Announcement content

Announcements can customize the displayed content. To display chat room announcement messages, you need to listen for the chat room's "BULLETIN" event to retrieve and show the announcement content.

Using the API

The core methods for using the feature are setApp, init, destroy, and api.

setApp

Set the appId and appSecret for Polyv Cloud Live Streaming. This is typically called in the onLaunch method of app.js.

init

On successful initialization, return 频道详情:detail, 聊天室:chat, 网络请求:api.

plv.init(options)
  .then(r => {
    // 初始化成功
    const { detail, chat } = r;
  })
  .catch(err => {
    // 初始化失败
    console.error(err);
  });
Custom Statistical Parameter Settings

If you need to pass custom interaction statistical data param4 and param5, add the parameters in options.

If you are directly referencing the Polyv component, simply add param4 and param5 in options. If you are referencing the player component separately, you need to set the videoOption parameter of the player component.

Directly reference the Polyv component example:

plv.init(options = {..., param4: 'param4', param5: 'param5'})
  .then(r => {
    // 初始化成功
    const { detail, chat } = r;
  })
  .catch(err => {
    // 初始化失败
    console.error(err);
  });

Example of Using the Player Component Alone

  <player
    videoOption="{{ videoOption }}"
  />
videoOption = {
  statistics: {
    param4: 'param4',
    param5: 'param5'
  }
}
plv.init(options = {..., param4: 'param4', param5: 'param5'})
  .then(r => {
    // 初始化成功
    const { detail, chat } = r;
  })
  .catch(err => {
    // 初始化失败
    console.error(err);
  });

Related Parameter Description

Parameter Type Required Description
appId String Yes Polyv Cloud Live appId
appSecret String Yes Polyv Cloud Live appSecret
channelId String|Number Yes Channel ID
openId String Yes Mini Program user openId
userName String Yes User nickname
avatarUrl String Yes User avatar

Channel Details: detail

Attribute Description
channelMenus Page menus set in the backend
scene Current live type: ppt (cloud classroom) / alone (standard live)
status Live status: Y (live) / N (not live)
name Live name
desc Live description
publisher Host
userId User ID
likes Like count
pageView View count
channelId Channel ID
playbackEnabled Whether playback is enabled
hasPlayback Whether playback exists
playbackList Playback list
recordFileSimpleModel Live recording temp
warmUpImg Warm-up image
warmUpFlv Warm-up video
coverImage Cover image
stream Live stream name
startTime Live start time
sessionId Session ID
chatToken Chat room authentication token

Chat Feature: chat

  • chat.events All Events
Parameter Description
CONNECT Connect socket
DISCONNECT Disconnect
ERROR Socket error
RECONNECT_ATTEMPT Reconnection attempt
CLOSE_ROOM Room closed
OPEN_ROOM Room opened
SYSTEM_MESSAGE System message
SPEAK User speaks
SPEAK_ERROR Speak error
SPEAK_CENSOR Speak review
FLOWERS Send flowers
CHAT_IMG Image
REWARD Reward info
CUSTOMER_MESSAGE Custom message
SERVER_ERROR Server error
KICK_USER User kicked
REMOVE_HISTORY Clear chat history
REMOVE_CONTENT Clear a specific message
HISTORY_MESSAGE Get historical chat messages
SEND_MESSAGE Message sent successfully
PROHIBIT_TO_SPEAK Mute user
LOGIN Login
LOGOUT Logout
LOGIN_REFUSE Login refused
SLICESTART Cloud class starts
MICROPHONE Microphone
ALLOW_MICROPHONE Allow microphone
SUCCESS_MICROPHONE Microphone connected
JOIN_CHANNEL_FAIL Failed to join channel
BAN_USER_ROOM Ban user from room
UPDATE_QUESTION_HISTROY UPDATE_QUESTION_HISTROY
S_QUESTION Student asks question
T_ANSWER Teacher/TA/Admin answers question
  • chat.socket Get socket object

  • chat.on listens to events

  • chat.off Uninstall events event

  • chat.trigger Trigger Event

  • chat.options passed in options

  • chat.roomClosed Whether the room is closed

  • chat.teacherData Teacher Information

  • Chat Room API Related

api params desc
historyCount None Get the number of chat room history messages
getHistoryMessage() start I int: Start row number
end | int: End row number
Request example:
chat.getHistoryMessage(end, start, data => {console.log(data)})
Get chat room records
return | Array
hasMoreHistory() None Check if there are more history records
getOnlineUserList() Request example:
chat.getOnlineUserList().then(res => {console.log(res)})
Get the online user list of the channel
return | Object
sendFlower() None Send a flower
sendLike() num | int: Number of likes
Request example:
chat.sendLike(1)
Send a like
send() msg | String: Text message
Request example:
chat.send('Hello,World')
Send a message
  • Consultation Room API Related

  • chat.getQuestionHistoryMessage() - Retrieve consultation history

  • chat.sendQuestion() - Send a consultation message

  • Co-hosting

  • chat.checkCurrentStatus() Query the current co-hosting status

  • chat.cancelJoinChannel() Cancel joining the co-hosting channel

destory

Call this method in the page's onUnload lifecycle hook to reset the data.

api

  • api.getUserId(openId) – Retrieve the user ID
  • api.getChannelDetail(channelId) – Retrieve channel details
  • api.getOrdinaryLiveStatus(channelId) – Retrieve the status of a regular live stream
  • api.getPlayBackVideos(channelId) – Retrieve the list of playback videos
  • api.getChapterRecords(params) – Retrieve chapter information
    • params.id – The file ID of a temporary file or the video ID of a playback video (when type is record, id is the file ID of the temporary file; when type is playback, id is the video ID of the playback video)
    • params.channelId – Channel ID
    • params.type – Type (record: temporary file type; playback: playback type)
  • api.getChannelKey(channelId) – Retrieve the co-hosting key

Error Message Description

Error Code Description
31000 Failed to retrieve on-demand video data
31001 vid cannot be empty
31002 On-demand video has expired
31003 Account has no traffic