# 介绍

短剧播放器是微信官方为微短剧类目小程序提供的播放器插件,旨在帮助短剧开发者降低开发及运营成本,提供短剧行业的运营组件能力,提升微信内短剧播放质量及优化用户体验。 开发者可引入短剧播放器插件后,基于自身需求进行开发配置。

具体介绍

短剧播放器介绍

接入示例

代码示例

# 接入流程

为了更好地使用短剧播放器插件,您需要按照以下步骤进行接入:

1.剧集内容授权:播放方小程序需要获得提审方剧集的授权,详见:

(1)剧目授权

(2)账号授权

2.申请添加插件:接入短剧播放器插件之前,您需要先完成插件的添加申请。

添加方式1:MP-设置-第三方设置-插件管理-添加插件

image.png

输入插件appid:wx94a6522b1d640c3b,即可添加完成。

image.png

添加方式2:开发者工具添加,详见3.1 插件如何引入

3.插件接入:开始进行插件的接入开发,详见文档 3.基础接入

4.其他自定义开发:除了基本的插件接入,您还可以根据自身需求接入播放器所提供的运营能力以及进行其他自定义开发,为用户提供更多的功能和特性。详见文档 4.运营能力

# 基础接入

在接入之前,可以先提前了解下面的问题:

  1. 在开发者工具调试时,需要先去掉app.json的设置"lazyCodeLoading": "requiredComponents",否则可能会碰到黑屏,或者是报错Plugin module "__wx__/plugin-private-api" is not defined.
  2. 有些使用框架的开发者,例如uniapp,如果碰到自定义运营区域组件,或者充值组件无法渲染的问题,可能是该组件被框架删除了。可通过创建一个空的页面,去引用对应的组件,页面的json文件可参考
{
  "usingComponents": {
    "charge-dialog": "/components/charge-dialog/charge-dialog",
    "open-area-left": "/components/open-area-left/open-area-left",
    "open-area-left-side": "/components/open-area-left-side/open-area-left-side",
    "open-area-right": "/components/open-area-right/open-area-right"
  }
}

# 插件如何引入

首先在小程序的 app.json 文件中添加插件的引入配置,示例代码如下:

{
  "plugins": {
    "playlet-plugin": {
      "version": "latest",
      "provider": "wx94a6522b1d640c3b"
    }
  }
}

"provider"字段为插件提供方的appid,设置为"wx94a6522b1d640c3b"即可。请确保将 "version" 字段设置为 "latest",以使用最新版本的插件。

image.png

在开发者工具Console里点击「添加插件」即可自动通过。 具体的接入流程可参考下面的步骤:

# 插件接入流程

下面的接入流程涉及的一些字段的含义,先提前说明下:

● srcAppid: 提审方appid,通过小程序媒资管理上传了剧目的账号appid

● dramaId: 剧目ID,通过小程序媒资管理提审的剧目id

● serialNo: 剧集ID,从1开始递增,比如第1集则serialNo是1,注意这里跟媒资管理的mediaNo是不一样的

● playerId: 播放器页面实例的唯一ID,由于可能页面栈上会存在多个播放器页面,所以需要通过这个唯一的ID来区分不同的页面,例如从播放器的推荐跳转到另外一个剧。

插件提供的能力说明:

● 插件提供了播放器页面,接入后,可以通过播放器页面的路径使用,播放器的路径前缀为plugin-private://wx94a6522b1d640c3b/pages/playlet/playlet

● 播放器页面和小程序之间有比较多的逻辑交互,例如某一集是否能解锁观看,需要开发者提供,插件提供了一些接口来让小程序去交互。接口通过const playletPlugin = requirePlugin('playlet-plugin')返回的插件实例来调用。

● 点击可查看详细接口文档

播放器里面是否可解锁等数据,需要开发者提供,开发者可以参考下面的步骤进行接入。

# app.js的代码示例

var PlayerManager = require('../playerManager')
// playlet-plugin必须和上面的app.json里面声明的插件名称一致
const playletPlugin = requirePlugin('playlet-plugin')
//app.js
App({
  onLaunch(options) {
    // 注册播放器页面的onLoad事件
    playletPlugin.onPageLoad(this._onPlayerLoad.bind(this))
  },
  _onPlayerLoad(info) {
    const playerManager = new PlayerManager()
    playerManager._onPlayerLoad(info)
  },
})

在onLaunch调用playletPlugin.onPageLoad(func),func是回调函数,这个回调函数会在播放器页面onLoad时触发,可以在该回调函数中进行其他信息的初始化。

# playerManager.js

上面的app.js里面引用了playerManager.js文件,为了更好地理解主逻辑 playerManager.js 的功能,请参考以下示例代码:

var plugin = requirePlugin("playlet-plugin");
// 点击按钮触发此函数跳转到播放器页面
function navigateToPlayer(obj) {
    // 下面的${dramaId}变量,需要替换成小程序管理后台的媒资管理上传的剧目的dramaId,变量${srcAppid}是提审方appid,变量${serialNo}是某一集,变量${extParam}是扩展字段,可通过
    const { extParam, dramaId, srcAppid } = obj
    wx.navigateTo({
      url: `plugin-private://wx94a6522b1d640c3b/pages/playlet/playlet?dramaId=${dramaId}&srcAppid=${srcAppid}&extParam=${extParam || ''}`
    })
}
const proto = {
  _onPlayerLoad(info) {
    const pm = plugin.PlayletManager.getPageManager(info.playerId)
    this.pm = pm
    // encryptedData是经过开发者后台加密后(不要在前端加密)的数据,具体实现见下面的加密章节
    this.getEncryptData({serialNo: info.serialNo}).then(res => {
      // encryptedData是后台加密后的数据,具体实现见下面的加密章节
      pm.setCanPlaySerialList({
        data: res.encryptedData,
        freeList: [{start_serial_no: 1, end_serial_no: 10}], // 1~10集是免费剧集,只针对已解锁剧集生效
      })
    })
    pm.onCheckIsCanPlay(this.onCheckIsCanPlay)
    // 关于分享的处理
    // 开启分享以及withShareTicket
    pm.setDramaFlag({
      share: true,
      withShareTicket: true
    })
    // 获取分享参数,页面栈只有短剧播放器一个页面的时候可获取到此参数
    // 例如从分享卡片进入、从投流广告直接跳转到播放器页面,从二维码直接进入播放器页面等情况
    plugin.getShareParams().then(res => {
      console.log('getLaunch options query res', res)
      // 关于extParam的处理,需要先做decodeURIComponent之后才能得到原值
      const extParam = decodeURIComponent(res.extParam)
      console.log('getLaunch options extParam', extParam)
      // 如果设置了withShareTicket为true,可通过文档的方法获取更多信息
      // https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share.html
      const enterOptions = wx.getEnterOptionsSync()
      console.log('getLaunch options shareTicket', enterOptions.shareTicket)
    }).catch(err => {
      console.log('getLaunch options query err', err)
    })
    // extParam除了可以通过在path传参,还可以通过下面的接口设置
    pm.setExtParam('hellotest')
    // 分享部分end
  },
  onCheckIsCanPlay(param) {
    // TODO: 碰到不可以解锁的剧集,会触发此事件,这里可以进行扣币解锁逻辑,如果用户无足够的币,可调用下面的this.isCanPlay设置
    console.log('onCheckIsCanPlay param', param)
    var serialNo = param.serialNo
    this.getEncryptData({serialNo: serialNo}).then(res => {
      // encryptedData是后台加密后的数据,具体实现见下面的加密章节
      this.pm.isCanPlay({
        data: res.encryptedData,
        serialNo: serialNo,
      })
    })
  },
  getEncryptData(obj) {
    const { serialNo } = obj
    // TODO: 此接口请求后台,返回下面的setCanPlaySerialList接口需要的加密参数
    const { srcAppid, dramaId } = this.pm.getInfo()
    console.log('getEncryptData start', srcAppid, dramaId, serialNo)
    return new Promise((resolve, reject) => {
      resolve({
        encryptedData: '' // TODO: 此参数需从后台接口获取到
      })
    })
  },
}
function PlayerManager() {
  var newProto = Object.assign({}, proto)
  for (const k in newProto) {
    if (typeof newProto[k] === 'function') {
      this[k] = newProto[k].bind(this)
    }
  }
}

PlayerManager.navigateToPlayer = navigateToPlayer
module.exports = PlayerManager

其中playerManager.js的这一段代码表示跳转到插件播放器页面

wx.navigateTo({
    url: 'plugin-private://wx94a6522b1d640c3b/pages/playlet/playlet?dramaId=${dramaId}&srcAppid=${srcAppid}&serialNo=${serialNo}&extParam=${extParam}'
})

播放器页面接收srcAppid参数、dramaId参数和serialNo等参数,其中:

●dramaId是开发者通过媒资管理的API上传的剧目id,必填

●srcAppid是提审方的appid,必填

●serialNo是指定播放的剧集id,从1开始递增(不是媒资管理的mediaNo),选填,如果不传,进入播放器页面则会从上次播放的剧集开始继续播放

●extParam是可选的扩展参数,选填,PlayletManager.getInfo()可获得传入的此参数,分享的时候也会带上此参数,可以作为上报的参数使用。

插件提供onPageLoad事件给开发者注册播放器页面的onLoad事件。

# 跳转到播放器页面

如果开发者需要从小程序首页跳转到播放器页面,请参考以下示例代码:

const plugin = requirePlugin('playlet-plugin')
// 引用的playerManager.js的代码可参考上面章节示例
const PlayerManager = require('./playerManager')

Page({
  onLoad(opt) {
  },
  onUnload() {
  },
  onJumpPlayer() {
    const { srcAppid, dramaId } = this.data
    // 调用playerManager.js提供的navigateToPlayer,可参考上面章节的示例代码
    PlayerManager.navigateToPlayer({
      srcAppid,
      dramaId,
      extParam: encodeURIComponent('a=b&c=d'), // 需要encode
    })
  },

})

# 实现后台接口初始化可播放剧集

在示例的 playerManager.js 文件的 _onPlayerLoad 方法中,通过调用 getEncryptData 方法获取加密后的数据,并将其传递给 pm.setCanPlaySerialList 方法来设置可播放的剧集。

具体实现步骤如下:

1.调用 getEncryptData 方法获取加密后的数据,示例代码如下:

this.getEncryptData({serialNo: info.serialNo}).then(res => {
  // encryptedData是后台加密后的数据,具体实现见下面的加密章节
  pm.setCanPlaySerialList({
    data: res.encryptedData,
    freeList: [{start_serial_no: 1, end_serial_no: 10}], // 1~10集是免费剧集,只针对已解锁剧集生效
  })
})
pm.onCheckIsCanPlay(this.onCheckIsCanPlay)

2.在 getEncryptData 方法中,您需要自己实现一个后台接口来获取加密后的数据,并将其返回encryptedData。

3.在 setCanPlaySerialList 中,将加密后的数据传递给播放器管理器来设置

setCanPlaySerialList({ data, freeList })接口设置当前可播放的剧集,data参数是就是上面提到的加密后的数据,表示那些集是可播放的,是LockDataReq类型对象经过JSON.stringify,然后再加密后得到的字符串。LockDataReq定义如下

参数名 类型 描述
openid string 当前观看用户的openid
src_appid string 提审方小程序的appid
drama_id string 提审的剧目id
serial_list Array SerialItem数组,SerialItem定义见下
data_expire_at number 数据有效期,时间戳(秒)。到时间过期不可用,建议当前时间戳+2小时

SerialItem类型定义

参数名 类型 描述
start_serial_no number 剧集编号,表示起始剧集编号,从1开始
end_serial_no number 结束剧集编号,包含此集
status number 上面的起始和结束区间内剧集是否可播放。// 1-可播放,2-不可播放

setCanPlaySerialList的freeList参数是免费剧集列表,是Array类型,FreeList定义如下:

参数名 类型 描述
start_serial_no number 起始免费剧集编号,从1开始
end_serial_no number 结束免费剧集编号,包含此集

注意:如果freeList设置的剧集是免费,而LockDataReq里面的剧集是付费,两者冲突,则LockDataReq里面的剧集优先,freeList只会影响下图的样式:

image.png

# 数据加密方案

为了避免小程序与开发者后台通信的数据被篡改,插件的接口接收的数据需要经过在开发者后台使用session_key的前16个字节作为密钥加密(不足16个字节后面补零),加密算法AES-128-ECB。

加密步骤:

(1)调用微信api获取当前登录用户的最新session_key

image.png

(2)使用LockDataReq结构组装待加密的明文数据(LockDataReq定义见实现后台接口初始化可播放剧集节的第三点介绍)

(3)将LockDataReq转成json字符串data

(4)使用AES-128-ECB算法对data进行加密,密钥是(1)获取的session_key的前16个字节

(5)对data加密后的密文进行base64编码

示例:

1)LockDataReq转成json的示例(以下示例表示解锁第10-12集,不解锁第13-15集)

{"openid":"xJad239kjafkjakdjfe","src_appid":"wx98293892389823","drama_id":"21212","serial_list":[{ "start_serial_no":10,"end_serial_no":12,"status":1},{"start_serial_no":13,"end_serial_no":15,"status":2}], "data_expire_at":1703474855}

2)加密示例

密钥key="89283sdkj1212121212"; 明文是1) 的示例 加密后的base64编码结果: LHb+riG/WsCP8wqQEIvJxCx59exL+Wjf23R/pTIbC9gZo3yrUrMMoqIb3/zviK0jtt2HBTk4Eke/bmSD/qKwfY277NK6YNv9wML8+loNnjIkPJHj3DHUALEcwxBTOUVqgTBNTFimtdU7qwkqMIMU1RSlQR+U9CFckbX46mCQoyA8VssxP5ej16+WIcnVqGbkZQdI5hoWZqvwRdnQtMV3s5ZDlGxxYS75XoTYMNdNYOS6bA9jt4K1AUWuEQcOw8ygs4a8EqYbwnA7uD6Ks+54O6xtEXmLyr5uPZKXcbyzjWs17+odJHI+e0gU5o79e3I6

(注:开发者可以使用解密代码解密以上实例,验证加解密逻辑是否正确)

# 解锁剧集

1.当用户切换到未购买的付费剧集时,会触发 onCheckIsCanPlay(func)注册的func回调函数。开发者需要在此回调函数中判断用户是否有足够的金币来播放该剧集。

2.如果用户有足够的金币,开发者可以进行扣币操作,并调用 PlayletManager 的 isCanPlay({ data, serialNo }) 函数,让播放器继续播放。其中,data 是加密后的数据,和 setCanPlaySerialList 的 data 参数定义一样。

3.如果用户没有足够的金币来播放剧集,则调用 PlayletManager 的 isCanPlay({ data, serialNo }) 函数,将 status 设置为 2(表示无法解锁)。此时,播放器会显示相应的 UI,提示用户需要充值才能继续观看。

image.png

# 充值组件

充值组件是一个小程序示例,会渲染在播放页面的半屏弹窗中。开发者需要自己实现此组件的充值逻辑,充值组件默认高度为屏幕高度的 75%,如果内容高度超过弹窗高度,需使用 scroll-view 组件实现滚动。开发者需提前获取到渲染弹窗内容所需要的数据,避免在弹窗拉起的时候内容变化导致弹窗高度发生变化。

image.png

1.在 app.json 文件中,需要定义组件 charge-dialog,指向开发者自己实现的充值组件。示例代码如下:

{
  "usingComponents": {
      "charge-dialog": "/components/charge-dialog/charge-dialog"
  },
  "plugins": {
    "playlet-plugin": {
      "version": "latest",
      "provider": "wx94a6522b1d640c3b",
      "genericsImplementation": {
        "playlet": {
          "charge-dialog": "/components/charge-dialog/charge-dialog"
        }
      }
    }
  }
}

注意:如果是在分包引入插件,上面定义的充值组件也需要在分包内。

2.开发者可以通过 PlayletManager 的 showChargeDialog() 方法来显示充值弹窗,并通过 onShowChargeDialog(func)以及 onHideChargeDialog(func) 方法注册显示隐藏弹窗的事件回调函数。 充值完成后,开发者onShowChargeDialog(func) 方法注册显示弹窗的事件回调函数。当充值弹窗拉起时,会触发此回调函数。

3.可以调用PlayletManager的hideChargeDialog()来关闭弹窗。

4.可以调用PlayletManager的updateChargeDialogHeight({height:500})来设置弹窗高度。

5.可以调用PlayletManager的updateChargeDialogInfo({isTransparentBackground: true})来设置充值弹窗背景透明。

6.播放器会将 srcAppid、dramaId、serialNo、playerId、extParam 作为属性传递给 charge-dialog 组件。开发者可以在组件中定义这些属性,并根据 serialNo 的变化,获取不同的充值数据进行渲染。

Component({
  properties: {
    playerId: {
      type: String,
      value: ''
    },
    srcAppid: {
      type: String,
      value: ''
    },
    dramaId: {
      type: String,
      value: ''
    },
    serialNo: {
      type: Number,
      value: 0
    },
    extParam: {
      type: String,
      value: ''
    },
  },
  observers: {
      serialNo(serialNo) {
          // 当集数发生改变的时候,触发此函数
      }
  }
})

7.事件系统 充值组件是在播放器页面引入的,开发者无法通过在wxml里面注册相关的事件,因此插件提供了事件函数,可使用下面的onCustomEvent注册事件,emitCustomEvent触发事件

// 例如在playerManager.js里面调用onCustomEvent注册事件
PlayletManager.onCustomEvent(name, func)
// 在充值组件内调用emitCustomEvent触发事件
PlayletManager.emitCustomEvent(name, args)

# 其它开放接口

# 暂停/继续播放

PlayletManager.play()和PlayletManager.pause()

# 获取剧目信息

getInfo()获取到当前剧的相关信息,具体返回的数据结构如下:

参数名 类型 描述
srcAppid string
dramaId string 剧id
serialNo number 当前播放集id
extParam string 可选,传入的扩展信息

PS:以上为固定常用字段,其他页面路径上的参数也会在此处返回。

# 更换剧目

// 请将{srcAppid}替换为提审方appid,{dramaId}替换为真实剧id
PlayletManager.changeDrama({
    queryString: 'srcAppid={srcAppid}&dramaId={dramaId}'
})

# 数据上报

PlayletManager.onDataReport(func)

开发者可通过此方法注册回调函数获得数据上报相关的回调,其中event表示上报的点,event是个枚举值,具体的取值如下。 每个上报事件,都会有一些公共的字段会带回给开发者:

字段名 描述
playerId 播放器id
srcAppid 提审方appid
extParam 分享扩展参数
serialNo 当前剧集索引,从1开始计数
playTime 当前播放到的时间
duration 当前剧集的总时长
totalCount 当前剧集总集数

每个事件还有自己额外的一些字段,具体如下:

描述 额外字段说明
LOAD 进入播放器页面
SHOW 播放器页面 show
START_PLAY 开始播放
UNLOAD_OR_HIDE 离开页面或者退后台 例如 { type: 1, like: {}, heart: {} }。type为1表示Unload,为 2 表示 hide;like 是 object 对象,表示用户在播放器内点赞、取消点赞的行为;heart 和 like 类似,表示用户在播放器内推荐、取消推荐的行为
VIDEO_END 播放视频结束
VIDEO_START_WAITING 视频缓冲中,对应 video 的 waiting 事件
VIDEO_WAITING 视频缓冲结束,stopTime 表示 VIDEO_START_WAITING 到首个 VIDEO_TIME_UPDATE 的时间 例如 { stopTime: 0 }。stopTime表示缓冲了多久才继续播放,单位 ms
VIDEO_ERROR 视频播放失败 例如{error: ''}。error表示错误信息
VIDEO_REMOVED 该剧已下架
CHANGE_SERIAL 切换剧集 例如 { isFinish: true, slideType: 1 }。isFinish 为 true 表示是播放结束自动切换到下一集。slideType 为 1 表示上一集播放结束自动切换,2 表示手势滑动切换,3 表示从选集弹窗切换
CLICK_CHANGE_SERIAL 点击拉起切换剧集弹窗
LIKE 点赞
UNLIKE 取消点赞 例如 { type: 2 }。type 为 2 表示双击屏幕点赞, 1 表示点击 icon 点赞
HEART 推荐
UNHEART 取消推荐
SHARE 分享 例如 { shareType: 1, shareId: '' }。shareType 为 1 表示分享好友,2 表示分享海报。shareId 表示每次分享唯一的字符串,会在分享的 path 上带出去
CLICK_ACTIVITY 点击活动位
CHANGE_SPEED 倍速播放 { source: 1, speedType: 1.5 }。source 为 1 表示点击倍速按钮切换,2 表示长按视频切换到 2 倍速,speedType 表示切换到的倍速,例如 1.5 倍速
VIDEO_PROGRESS progress事件 参数参考 video 组件的 progress 事件
VIDEO_TIME_UPDATE timeupdate事件 参数参考 video 组件的 timeupdate 事件
VIDEO_PLAY play 事件
VIDEO_PAUSE 暂停事件
REQUEST_ERROR 插件内部请求接口报错,ret 表示错误码 { ret: 21003 },ret 为 1 表示 dramaId 或 srcAppid 填错,21003 表示解密失败
ADD_FOLLOW_SUC 关注公众号
OPEN_OFFICIAL_ACCOUNT 打开公众号
WATCH_TIME 观看时长 { type: 1, playTime: 10, duration: 65 }。type 表示触发的时机,目前取值 1 表示 unload,2 表示 hide,3 表示某一集结束,4 表示用户手动拖动进度条,5 表示切换了剧集,playTime 是此次观看时长
TAP_UNLOCK 点击解锁按钮
BACKGROUND_PREVIEW_PLAY 剧集未解锁时的视频预览开始播放
BACKGROUND_PREVIEW_ENDED 剧集未解锁时的视频预览播放结束
CLICK_RECOMMEND_TAB 点击选集弹窗中的推荐 tab
CHANGE_RECOMMEND_TAB 选集弹窗汇总切到推荐 tab 可通过点击切换或手势切换到推荐 tab,如果是点击切换到推荐 tab,会有额外的 CLICK_RECOMMEND_TAB 事件
CLICK_SELECT_DRAMA_RECOMMEND 点击选集弹窗中推荐 tab 里的剧目 clickDramaid、clickDramaname、clickSrcAppid 表示被点击的剧目信息
RECOMMEND_END_SHOW 剧目最后一集播放结束后的推荐列表展示
CLICK_RECOMMEND_END 点击剧目最后一集播放结束后的推荐列表里的剧目 clickDramaid、clickDramaname、clickSrcAppid 表示被点击的剧目信息
CLICK_DETAIL_ENTRY_ACTOR 点击选集弹窗中的演员 actorIndex 表示被点击的演员下标
CLICK_DETAIL_ENTRY 点击选集弹窗中的剧目详情入口
CLICK_DETAIL_DRAMA 点击剧集详情页中的相关推荐剧目 clickDramaid、clickDramaname、clickSrcAppid 表示被点击的剧目信息
CLICK_PROFILE 点击小程序 profile 页入口
CLICK_SETTINGS 点击设置按钮
OPEN_CLEAR_SCREEN 打开清屏开关
CLOSE_CLEAR_SCREEN 关闭清屏开关
OPEN_BARRAGE 打开弹幕
CLOSE_BARRAGE 关闭弹幕
CLICK_BARRAGE_SETTINGS 点击弹幕设置
CLICK_COMMENT_ENTRY 点击评论按钮

每个event的取值,对应的参数也不一样。

# 自定义返回按钮

注意,不可以在onBack回调函数里面调用wx.navigateBack等路由接口,可改为navigator组件或下面的路由跳转的接口进行跳转

PlayletManager.onBack(function() {
    // 在这里做一下挽留逻辑
    console.log('用户点击了返回按钮')
})

# 路由跳转

由于在插件页,小程序不能调用wx.navigateTo等接口,所以插件提供下面的接口进行跳转 注意:这些接口调用成功的前提是用户必须至少点击过页面。

PlayletManager.navigateTo(obj) // 含义和参数同wx.navigateTo
PlayletManager.navigateBack(obj) // 含义和参数同wx.navigateBack
PlayletManager.redirectTo(obj) // 含义和参数同wx.redirectTo
PlayletManager.switchTab(obj) // 含义和参数同wx.switchTab
PlayletManager.reLaunch(obj) // 含义和参数同wx.reLaunch

# 防录屏/截屏

若不调用此接口,播放器默认设置visualEffect为hidden具体使用可参考文档

PlayletManager.setVisualEffectOnCapture({
    visualEffect: 'hidden',
})

# 设置免费剧集列表

开发者可以进入页面就通过setCanPlaySerialList(freeList: [])接口设置免费剧列表(只针对已解锁剧集生效),如果开发者需要在用户观看过程中重新设置免费剧列表,可通过setFreeList设置,注意:此接口仅改变目录中的剧集显示状态,并不会做真正的解锁处理。

PlayletManager.setFreeList({
    list: [{start_serial_no: 1, end_serial_no: 10}], // 1~10集是免费剧集
})

# 设置用广告解锁剧集

开发者可以进入页面就通过setUseAdUnlock(list: [])接口设置需要广告解锁的剧集id,设置后,解锁按钮的文案变为“看广告解锁当前剧集”,点击后不会拉起充值弹窗,会回调给开发者事件。

注意:通过此接口设置的剧集,在选集界面上的 ui 表现会和免费剧集一样。

PlayletManager.setUseAdUnlock({
    list: [{start_serial_no: 79, end_serial_no: 80}], // 79~80集会通过广告解锁
})

开发者可通过接口onUseAdUnlock注册点击按钮的事件,通过激励视频去解锁

pm.onUseAdUnlock(function() {
    console.log('>>>USE_AD_UNLOCK')
    // 拉起激励视频广告去解锁
})

# 设置剧集未解锁时的视频预览

开发者可以设置剧集未解锁时的视频预览。当用户进入未解锁剧集时,可以在展示解锁按钮的同时在后台播放剧集视频预览:

// 播放预览
pm.startBackgroundPreview({
	loop: true, // 是否循环
	mask: true, // 是否遮罩
	muted: true, // 是否静音
})

// 停止预览播放
pm.stopBackgroundPreview()

注意:预览播放会消耗商家流量,请按需使用。

# 退出横屏

在用户进入横屏之后,如果碰到需要充值的剧集,需要退出横屏的,可调用此接口。接口调用如下:

pm.setPageOrientationPortrait()

# 播放原始视频

开发者可通过后台接口选择播放上传未经转码的原始视频。

接口url : https://api.weixin.qq.com/wxadrama/setplayerdramarecmdswitch?access_token=

请求方法:POST

入参:json(不允许带注释)

属性 类型 默认值 必填 说明
entry_type number 此处填2002
switch_status bool true-打开 false-关闭,没有打开过的都默认为关闭
{
    "entry_type":2002,
    "switch_status": true
}

# 最近观看组件

提供最近观看以供开发者在小程序中引用。在页面的 page.json 里面引入组件:

{
  "usingComponents": {
    "recent-list": "plugin://playlet-plugin/recent-list"
  }
}

recent-list即是最近观看组件,在页面 wxml 中添加组件:

<recent-list
    showHeader="{{true}}"
    bind:tapempty="onTapEmpty"
    bind:click="onClick"
    url="/pages/charge/charge"
></recent-list>

组件的使用和小程序组件类似,两个组件接收参数 url,url 表示列表为空的时候,点击“去看剧”跳转的链接,tapempty 事件表示点击了“去看剧”。

click 事件表示点击了对应的剧。

showHeader 属性表示是否显示组件的标题。

# 刷剧组件

提供刷剧组件以供开发者实现类似短剧广场等类似功能。在页面的 page.json 里引入组件:

{
  "usingComponents": {
    "drama-feed-list": "plugin://playlet-plugin/drama-feed-list"
  }
}

在页面wxml中添加组件:

<drama-feed-list
  id="drama-feed-list"
  autoplay
  bind:videoPlay="onVideoPlay"
  bind:videoPause="onVideoPause"
  bind:videoEnded="onVideoEnded"
  bind:videoError="onVideoError"
  bind:change="onChange"
  bind:watchFullDrama="onWatchFullDrama"
></drama-feed-list>

其中组件支持的参数如下:

参数名 类型 默认值 描述
shareSrcAppid string 置顶短剧的 srcAppid
shareDramaId string 置顶短剧的 dramaId
autoplay boolean false 组件初创时是否需要自动播放
mode string 刷剧模式,默认为普通刷剧,可传入 custom-list 表示自定义刷剧
custom-list Array [] 当 mode 为 custom-list 时需传入,表示自定义的刷剧列表

组件支持的事件如下:

事件名 描述
videoPlay 视频播放事件
videoPause 视频暂停事件
videoEnded 视频播放结束
videoError 视频播放报错
change 切换视频
watchFullDrama 点击“看全集”按钮
willReachEnd 列表即将触底事件,当 mode 为 custom-list 时才会触发
reachEnd 列表触底事件

事件中的 detail 字段会带有下述参数:

参数名 类型 描述
dramaId string 当前短剧的 dramaId
srcAppid string 当前短剧的 srcAppid
desc string 当前短剧的描述
mediaCount number 当前短剧的总集数
dramaName string 当前短剧的剧名
playTime number 当前视频的播放时长
duration number 当前视频的总时长
err Object 错误对象,videoError 事件才会返回
index number 当前短剧在列表中的下标
direction number 划动方向,change 事件才会返回,1 表示向下划动,2 表示向上划动

如果需要控制刷剧组件的播放和暂停,可通过调用组件实例的方法实现:

this.selectComponent('#drama-feed-list').play()
this.selectComponent('#drama-feed-list').pause()

// 当 mode 为 custom-list 的时候,还支持以下接口
this.selectComponent('#drama-feed-list').appendCustomList([{ dramaId: '', srcAppid: '' }])
this.selectComponent('#drama-feed-list').replaceCustomList([{ dramaId: '', srcAppid: '' }])

使用刷剧组件有以下几点需要注意:

  1. 目前刷剧组件播放的都是短剧的第一集。
  2. 当前视频播放完后,刷剧组件并不会切到下一集/下一部短剧,而是自动重播当前视频。
  3. 点击“看全集”按钮时触发的 watchFullDrama 事件需要开发者处理,一般可处理为跳转到该短剧的实际播放页。

刷剧组件本身有两种模式,一种是普通模式,一种是自定义刷剧模式。其中普通模式为开发者通过下述后台接口设置刷剧剧目,然后刷剧组件会从后台拉取推荐列表进行展示;而自定义刷剧模式则完全由开发者提供刷剧列表,刷剧组件只补全对应的信息再进行展示。

# 刷剧剧目设置接口

●功能:开发者可通过后台接口设置刷剧剧目

●接口url : https://api.weixin.qq.com/wxadrama/developersetflushdrama?access_token=

请求方法:POST

入参:json(不允许带注释)

属性 类型 必填 说明
src_appid string 提审方小程序的appid
drama_id string 提审的剧目id
drama_name string 短剧名称
{
  "list": [
    {"src_appid":"example_src_appid", "drama_id":"123456", "drama_name":"example_drama_1"},
    {"src_appid":"example_src_appid", "drama_id":"123457", "drama_name":"example_drama_2"},
    {"src_appid":"example_src_appid", "drama_id":"123458", "drama_name":"example_drama_3"}
  ]
}

返回:json

{
  "errcode":0,
  "errmsg":"ok"
}

注1: 每次设置都会覆盖之前的设置,因此需要把所有想要接入刷剧组件的剧目一次加上;list不传或者传空数组,则将记录清空。

注2:所有src_appid,drama_id,drama_name都需要合法,不然会报错。另外,如果所传剧目没有授权给该调用账号的,也会失败报错。

注3:list当前的上限是1000个。

# 自定义刷剧模式

当组件属性 mode 传入 custom-list 字符串时表示切换到自定义刷剧模式,此时要求开发者必须传入 custom-list 属性:

<drama-feed-list
  id="drama-feed-list"
  mode="custom-list"
  custom-list="{{customList}}"
  autoplay
  bind:videoPlay="onVideoPlay"
  bind:videoPause="onVideoPause"
  bind:videoEnded="onVideoEnded"
  bind:videoError="onVideoError"
  bind:change="onChange"
  bind:watchFullDrama="onWatchFullDrama"
  bind:willReachEnd="onWillReachEnd"
  bind:reachEnd="onReachEnd"
></drama-feed-list>

其中 customList 的结构如下:

Component({
  data: {
    customList: [
      { dramaId: '', srcAppid: '' },
      { dramaId: '', srcAppid: '' },
      // ...
    ],
  },
})

因为短剧是通过 dramaId 和 srcAppid 来确定唯一一部剧,所以开发者只需要传入 dramaId 和 srcAppid 即可,刷剧组件会将这部剧的其余信息填补进去后进行展示。

当短剧列表即将被划动到底部时,刷剧组件会触发 willReachEnd 事件,开发者可在此事件中进行列表补充:

// 此处传入的列表会追加到现有的刷剧列表后面
this.selectComponent('#drama-feed-list').appendCustomList([
  { dramaId: '', srcAppid: '' },
  { dramaId: '', srcAppid: '' },
  // ...
])

注意:刷剧组件里会将列表中每 3 项计为一组,willReachEnd 事件目前会在划到倒数第二组的时候触发。建议传入的自定义列表至少为两组以上。

如果开发者想直接替换掉完整的刷剧列表,可以调用下述接口:

// 此处传入的列表会替换掉现有的刷剧列表
this.selectComponent('#drama-feed-list').replaceCustomList([
  { dramaId: '', srcAppid: '' },
  { dramaId: '', srcAppid: '' },
  // ...
])

# 运营能力

完成播放器插件基础接入流程后,可根据业务需求按需使用相关运营能力。

# 分享

# 分享开关

分享开关默认打开,您可以通过调用 PlayletManager 的 setDramaFlag 方法来打开或关闭分享开关。示例代码如下:

PlayletManager.setDramaFlag({
    share: true,
    withShareTicket: true
})

请注意,若小程序本身的分享能力受限,则分享入口则只有分享海报功能。withShareTicket为true可获取更多信息,具体使用可参考文档

# 分享海报

播放器支持生成剧目海报。

image.png

开发者需要先在MP完成隐私协议配置,否则将隐藏C端用户的海报生成入口。

隐私协议配置

路径:设置-基本设置-服务内容声明-用户隐私保护指引

image.png

点击“更新”/“去完善”,选择“相册(仅写入)权限”

image.png image.png

# 分享参数

您可以在 URL 中传入 extParam 参数,在分享时会将此参数带到分享出去的卡片上。有两种设置 extParam 的方式:

a. 在 navigateTo 跳转页面时,将此参数放到 URL 上。

b. 通过 PlayletManager.setExtParam(extParam)设置。注意,我们会对此参数进行 encodeURIComponent 编码,因此在获取此参数时,开发者需要进行 decodeURIComponent 解码操作后再解析。

# shareId

每次分享都会在分享出去的小程序卡片或者小程序码的path里面带参数shareId,而且此shareId会通过onDataReport事件报给开发者,当用户再从卡片进入播放器,开发者可通过plugin.getShareParams获得此参数,进一步关联之前分享的用户,做一些分享相关的运营活动。具体的示例可参考章节“主逻辑playerManager.js”代码:

image.png

# 分享组件

从1.1.1版本开始支持分享组件组件,具体使用如下: 首先在page.json里面引用分享组件

{
    "usingComponents": {
        "playlet-share": "plugin://playlet-plugin/share"
    }
}

在页面wxml引入分享组件

<playlet-share
    playerId="{{playerId}}"
    imageUrl="{{imageUrl}}"
    title="{{title}}"
    shareExt="ext%3D1%26extb%3D2"
>
    <text style="font-size:18px;color:red;line-height:1em;">点击分享</text>
</playlet-share>

playerId是播放器页面的id,在onPlayerLoad的时候可获取,或者是getInfo接口会返回。 imageUrl是分享卡片的图片,title是分享卡片的标题,shareExt是分享的自定义参数,会带在小程序的页面路径上。

# 运营位

在胶囊旁边显示“活动”运营位,icon可自定义。 可通过PlayletManager的setActivityInfo(info)来进行设置,具体的示例代码可参考

PlayetManager.setActivityInfo({
  url: '', // 活动页面的路径,必填
  logo: '', // 显示的icon的url
})

# 自定义开放区域

为了最大程度提高播放器的灵活性,目前开放了一些区域让开发者自定义,可开放的的区域如下图所示

image.png

open-area-left-side和open-area-left的区域是一样的,open-area-left-side可设置多个,可定义每个的宽高和left、top。open-area-left固定上图的区域。

具体接入类似充值弹窗的内容,首先在app.json内注册组件,如下所示

{
  "usingComponents": {
    "charge-dialog": "/components/charge-dialog/charge-dialog",
    "open-area-left": "/components/open-area-left/open-area-left",
    "open-area-left-side": "/components/open-area-left-side/open-area-left-side",
    "open-area-right": "/components/open-area-right/open-area-right"
  },
  "plugins": {
    "playlet-plugin": {
      "version": "latest",
      "provider": "wx94a6522b1d640c3b",
      "genericsImplementation": {
        "playlet": {
          "charge-dialog": "/components/charge-dialog/charge-dialog",
          "open-area-left": "/components/open-area-left/open-area-left",
          "open-area-left-side": "/components/open-area-left-side/open-area-left-side",
          "open-area-right": "/components/open-area-right/open-area-right"
        }
      }
    }
  }
}

open-area-left、open-area-left-side、open-area-right是开发者需要实现的组件,当需要展示这几个组件的时候,可调用PlayletManager的updateOpenArea({showLeft: true, showRight: true})来显示隐藏组件,接口的参数如下

updateOpenArea({
    showLeft: true, // 显示open-area-left组件
    showRight: true, // 显示open-area-right组件
    leftWidth: 72, // 左侧宽度,超出截断
    leftHeight: 100, // 左侧高度,超出截断
    rightHeight: 100, // 右侧高度,超出截断
    leftsideAreaList: [{ // 显示open-area-left-side组件
        left: 10, // left top width height定义每个元素的位置
        top: 100,
        width: 400,
        height: 172
    }],
    ext: '', // 如果需要额外传一些数据给open-area-left等组件,可通过此参数传入
})

open-area-left-side组件会接收playerId、serialNo、item、index四个参数,组件定义可参考示例:

Component({
  properties: {
    playerId: {
      type: String,
      value: ''
    },
    serialNo: {
      type: Number,
      value: 0
    },
    item: { // 传入的leftsideAreaList数组下的某一项
      type: Object,
      value: {}
    },
    index: { // 传入的leftsideAreaList数组下的某一项
      type: Number,
      value: 0
    },
    ext: {
      type: String,
      value: ''
    },
  },
  observers: {
      serialNo(serialNo) {
          // 当集数发生改变的时候,触发此函数
      }
  }
})

open-area-left、open-area-right组件会接收playerId、serialNo这两个参数可参考示例:

Component({
  properties: {
    playerId: {
      type: String,
      value: ''
    },
    serialNo: {
      type: Number,
      value: 0
    },
    ext: {
      type: String,
      value: ''
    },
  },
  observers: {

  }
})

# 公众号联动

详情可见能力介绍

# 推荐位

播放器插件在不同场景提供推荐位以供开发者使用,推荐位默认关闭,可通过推荐位控制接口打开推荐位。

注意:推荐剧库大于等于 6 部时,才会在相应场景中出现推荐位。

image.png

# 推荐位控制接口

●功能:开发者可通过后台接口控制推荐位的开启与关闭。

●接口url : https://api.weixin.qq.com/wxadrama/setplayerdramarecmdswitch?access_token=

请求方法:POST

入参:json(不允许带注释)

属性 类型 默认值 必填 说明
entry_type number 1-剧结束 2-选集最右侧推荐 3-剧集profile页相关推荐
switch_status bool true-打开 false-关闭,1-剧结束&3-剧集profile页默认打开
{
    "entry_type":1,
    "switch_status": true
}

返回:json

{
    "errcode":0,
    "errmsg":"ok"
}

# 推荐剧目设置

开启推荐位之后,推荐剧目范围默认为播放小程序所有已授权的剧目。

同时支持开发者设置推荐库,在设置推荐库之后,推荐剧目将从开发者设置的推荐剧目中产生。

●接口url : https://api.weixin.qq.com/wxadrama/developersetrecmddrama?access_token=xxxxxx

{

    "entry_type":1, //1-剧结束 2-选集最右侧推荐 3-剧集profile页相关推荐

    "src_appid":"wx94a6522b1d640c3b",

    "drama_id":"666666",

    "list":[

        {"src_appid":"wx4f3ca6d4c2407ccc","drama_id":"266946"},

        {"src_appid":"wx5cefe18a7902141d","drama_id":"236424"}

    ]

}

注1:src_appid 和 drama_id 同时为空,代表小程序维度。展示优先级低于剧粒度的设置。

注2: 每次设置都会覆盖之前的设置,需要把所有要设置的推荐剧一次加上;list不传或者传空数组,则将记录清空。

注3:所有appid需要合法,不然报错。另外存在所传剧目没有授权给该调用账号的,也会失败报错。

注4:list当前的上限是200个。

# 短剧上架

# 短剧上架设置接口

●功能:开发者可通过后台接口设置小程序内短剧的上架时间。在短剧提审成功并授权后默认直接上架,如需设置特定上架时间可以调用该接口。

●接口url : https://api.weixin.qq.com/wxadrama/developerpublishdrama?access_token=

请求方法:POST

入参:json(不允许带注释)

属性 类型 必填 说明
src_appid string 提审方小程序的appid
drama_id string 提审的剧目id
drama_name string 短剧名称
publish_time uint32 上架时间戳(秒级别)
{
   "list": [
           {"src_appid":"example_src_appid", "drama_id":"123456", "drama_name":"example_drama_1", "publish_time":1734624000},
           {"src_appid":"example_src_appid", "drama_id":"123457", "drama_name":"example_drama_2", "publish_time":1734600000},
           {"src_appid":"example_src_appid", "drama_id":"123458", "drama_name":"example_drama_3", "publish_time":1730000030}}
     ]
}

返回:json

{
    "errcode":0,
    "errmsg":"ok"
}

注1:所有src_appid,drama_id,drama_name 都需要合法和已授权。

注2:publish_time为秒级时间戳,表示从"1970-01-01 00:00:00"开始到当前时间的总秒数。publish_time可以被多次设置,且平台取用最新的publish_time。

# 获取已上架短剧

●功能:开发者可以通过该接口查询通过“短剧上架设置接口”设置上架的短剧。

●接口url : https://api.weixin.qq.com/wxadrama/developergetpublisheddrama?access_token=

请求方法:POST

返回:json

{
    "list":[
        {"src_appid":"example_appid","drama_id":"example_drama_id_1","publish_time":1744626100},
        {"src_appid":"example_appid","drama_id":"example_drama_id_2","publish_time":1744626200},
    ]
    "errcode":0,
    "errmsg":"ok"
}

# 短剧变现类型

# 设置短剧变现类型

●功能:在视频号推荐、视频号入口展示、播放器选集等场景,对IAA/IAP/IAAP有不同的精准策略。若不进行配置/配置出错,将影响你的营收和流量分配。

●接口url : https://api.weixin.qq.com/wxadrama/developersetiaadrama?access_token=

请求方法:POST

入参:json(不允许带注释)

属性 类型 必填 说明
src_appid string 提审方小程序的appid
drama_id string 提审的剧目id
iaa_type uint32 短剧变现类型。 1-纯IAA;2-纯IAP;3-IAAP混合变现
vip_flag uint32 是否存在会员功能。 1-有;2-无
{
   "list": [
           {"src_appid":"example_src_appid", "drama_id":"123456", "iaa_type": 1, "vip_flag":1 },
           {"src_appid":"example_src_appid", "drama_id":"123457", "iaa_type": 2, "vip_flag":1 },
           {"src_appid":"example_src_appid", "drama_id":"123458", "iaa_type": 1, "vip_flag":1 }
     ]
}

返回:json

{
    "errcode":0,
    "errmsg":"ok"
}

注1:平台以 src_appid x drama_id 唯一标识一部短剧。 注2:access_token会被平台校验并映射成当前小程序的appid,接口调用后将以appid x src_appid x drama_id 粒度对当前小程序下的一部短剧进行设置。

# 获取短剧变现类型

●功能:获取已设置短剧的变现类型。

●接口url : https://api.weixin.qq.com/wxadrama/developergetiaadrama?access_token=

请求方法:POST

入参:json(不允许带注释)

属性 类型 必填 说明
src_appid string 提审方小程序的appid
drama_id string 提审的剧目id
{
   "list": [
           {"src_appid":"example_src_appid", "drama_id":"123456"},
           {"src_appid":"example_src_appid", "drama_id":"123457"}
     ]
}

返回:json

属性 类型 必填 说明
src_appid string 提审方小程序的appid
drama_id string 提审的剧目id
iaa_type uint32 短剧变现类型。 0-未设置;1-纯IAA;2-纯IAP;3-IAAP混合变现
vip_flag uint32 是否存在会员功能。 0-未设置;1-有;2-无
{
   "list": [
           {"src_appid":"example_src_appid", "drama_id":"123456", "iaa_type": 1, "vip_flag":1 },
           {"src_appid":"example_src_appid", "drama_id":"123457", "iaa_type": 2, "vip_flag":1 }
     ],
    "errcode":0,
    "errmsg":"ok"
}

# 批处理短剧合作推广计划

●功能: 使用接口设置后,可批量将剧目加入/退出短剧推广计划中。 注: 1、剧目加入计划后,会用于生态内的分发,如小程序-发现页、公众号推荐等场景。 2、该接口必须由剧目提审时的小程序调用,即access_token对应的小程序appid必须等于src_appid。 3、每次批量加入短剧最大数目限制为100。

●接口url : https://api.weixin.qq.com/wxadrama/batchprocessdramapromotion?access_token=

请求方法:POST

入参:json(不允许带注释)

属性 类型 必填 说明
action_type uint32 操作类型。1-加入计划;2-查询计划;3-退出计划
list array 短剧数组
list.src_appid string 提审方小程序的appid
list.drama_id string 提审的剧目id

返回:json

属性 类型 必填 说明
list array 短剧数组
list.src_appid string 提审方小程序的appid
list.drama_id string 提审的剧目id
list.status uint32 短剧状态。 0-未加入计划;1-审核中;2-审核通过;3-审核拒绝;4-退出计划中;5-已被下架
errcode uint32 错误码。0-正常
errmsg string 错误信息

加入/退出计划请求示例

此处仅以加入计划为例,如需退出计划可修改action_type为3。

{
   "action_type": 1,
   "list": [
           {"src_appid":"example_src_appid", "drama_id":"123456"},
           {"src_appid":"example_src_appid", "drama_id":"123457"}
     ]
}

加入/退出计划返回示例

{
    "errcode":0,
    "errmsg":"ok"
}

查询计划请求示例

{
   "action_type": 2,
   "list": [
           {"src_appid":"example_src_appid", "drama_id":"123456"},
           {"src_appid":"example_src_appid", "drama_id":"123457"}
     ]
}

查询计划返回示例

{
   "list": [
           {"src_appid":"example_src_appid", "drama_id":"123456", "status": 0 },
           {"src_appid":"example_src_appid", "drama_id":"123457", "status": 1 }
     ],
    "errcode":0,
    "errmsg":"ok"
}

# 常见问题

# 基础库兼容问题

播放器功能支持基础库版本为2.21.4及以上

# 测试注意

●多种进入播放器的场景测试:开发者需要测试不同的场景,例如从首页跳转(navigateTo/redirectTo)、从分享卡片进入,以及从其他小程序通过 navigateToMiniProgram 跳转等情况。确保在各种场景下播放器功能正常运行。

●关于 lazyCodeLoading 的注意事项:如果开启了 lazyCodeLoading 功能,需要注意在开发者工具中进行调试时可能会遇到 bug。在开发者工具中,需要先关闭以下设置:

{
    "lazyCodeLoading":"requiredComponents"
}

# 投放路径设置

# 投放的页面路径

plugin-private://wx94a6522b1d640c3b/pages/playlet/playlet?dramaId={dramaId}&srcAppid={srcAppid}&extParam={extParam}

其中{dramaId}表示剧集id,{srcAppid}提审方appid,请替换成对应的参数,{extParam}是分享参数,具体见分享章节介绍

# 存量投放链接处理

若之前投放的链接是pages/player/index,可使用redirectTo跳转到播放器的页面链接 (即plugin-private://wx94a6522b1d640c3b/pages/playlet/playlet开头的链接),用户在播放器页面点击左上角后,可返回首页。

# 版本更新日志

查看更新日志

# 附录

# 完整接口文档

查看完整接口文档

# 播放器后台返回码

描述
-1 系统错误,请重试
0 成功
1 不存在
2 参数错误
21000 该剧未授权播放,请通过后台api进行授权
21001 用户加密的sessionkey不存在
21002 商家的加密包未进行base64编码
21003 解密商家加密包失败,请确认是否按接入文档中给出的加密方案加密或sessionkey要使用当前用户最新的
21004 商家加密前的明文不是合法的json格式或者字段类型不对,请按接入文档排查
21005 商家加密中的必填参数值(openid、src_appid及drama_id)为空
21006 播放器的入参与商家加密包中的参数值不匹配
21007 加密包中的openid无效
21008 21008 开发者未开启预拉取
21009 21009 商家流量不足

# 接入咨询

短剧贴片申请

问卷填写

播放器接入问题可加群咨询微信团队

image.png