# 介绍

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

具体介绍

短剧播放器介绍

接入示例

代码示例

# 接入流程

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

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 可选,传入的扩展信息

# 更换剧目

// 请将{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,likeAndFav:{}}。type为1表示Unload,为2表示hide,likeAndFav是object对象,表示用户在播放器内点赞、取消点赞、追剧、取消追剧的行为
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点赞
SHARE 分享 例如{shareType: 1, shareId: ''}。shareType为1表示分享好友,2表示分享海报。shareId表示每次分享唯一的字符串,会在分享的path上带出去
CLICK_ACTIVITY 点击活动位
FAV 在追
UNFAV 取消在追
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 关注公众号
WATCH_TIME 观看时长 {type: 1, playTime: 10, duration: 65}。type表示触发的时机,目前取值1表示unload,2表示hide,3表示某一集结束,4表示用户手动拖动进度条,5表示切换了剧集,playTime是此次观看时长
TAP_UNLOCK 点击解锁按钮

每个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集是免费剧集
})

# 设置用广告解锁剧集

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

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

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

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

# 退出横屏

从插件版本1.1.5开始支持退出横屏的接口,在用户进入横屏之后,如果碰到需要充值的剧集,需要退出横屏的,可调用此接口。接口调用如下:

pm.setPageOrientationPortrait()

# 预加载

开发者可通过后台接口控制是否开启预加载,开启后在当前集播放结束前10s将开始预加载下个视频,以及保留前一集的视频观看进度,优化用户体验。开发者可以通过API控制、按需选择是否开启,默认状态为关闭。

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

请求方法:POST

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

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

# 播放原始视频

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

接口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",
    "fav-list": "plugin://playlet-plugin/fav-list"
  }
}

其中fav-list组件是在追列表组件,recent-list是最近观看组件,在页面wxml中添加组件

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

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

click事件表示点击了对应的剧,unfav表示取消了追剧。

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

# 运营能力

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

# 分享

# 分享开关

分享开关默认打开,您可以通过调用 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是分享的自定义参数,会带在小程序的页面路径上。

# 侧边运营位

image.png

侧边固定操作栏提供“活动”运营位,icon及文案均可自定义。 可通过PlayletManager的setActivityInfo(info)来进行设置,具体的示例代码可参考

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

# 自定义开放区域

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

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个。

# 常见问题

# 基础库兼容问题

播放器功能支持基础库版本为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开头的链接),用户在播放器页面点击左上角后,可返回首页。

# 部分场景进入播放页面无法解锁的问题

plugin-private://wx94a6522b1d640c3b/pages/playlet/playlet?dramaId=xxx&srcAppid=xxx

问题:很多场景不会带开发者的内部id,会导致用户从这些场景进入播放页无法解锁的问题

解决方案:需要通过path上的dramaId与srcAppid 映射到开发者内部剧id

# 版本更新记录

1.2.22

  1. 非移动端隐藏后台小窗播放按钮
  2. 修复部分场景 profile 页报错问题

1.2.19

  1. 调整活动运营位位置,不再显示运营文字
  2. 调整播放器下边栏 ui 和设置面板交互
  3. 支持小程序 profile 页

1.2.18

  1. 修复分享菜单会被自定义区域遮挡问题
  2. 修复长按恢复时没有触发 CHANGE_SPEED 的问题

1.2.17

  1. 修复自动拉起选集弹窗时,剧集状态无法更新的问题

1.2.14

  1. 修复演员详情弹窗可能无法滚动到底的问题
  2. 支持后台小窗播放按钮
  3. 优化部分异常抛出日志
  4. 修复 video 异常可能没有抛出的问题

1.2.13

  1. 修复异常公众号仍然会展示关注按钮的问题
  2. 修复 UNLOAD_OR_HIDE 事件中 playTime 没有值的问题

1.2.12

  1. 激励广告弹窗兼容横屏样式

1.2.11

  1. 回退“自定义区域在开发版、体验版进行溢出截断”改动

1.2.10

  1. 刷剧组件 nextSerialNoClick 事件过滤
  2. 自定义区域在开发版、体验版进行溢出截断

1.2.9

  1. onDataReport 补充 playerId 通用字段

1.2.8

  1. 修复进入自动拉起选集时没有显示剧集列表的问题

1.2.7

  1. 修复播放器 debug 日志无法输出问题
  2. 修复备案号被全局样式影响问题

1.2.6

  1. 支持 setLoggerConfig 接口用于控制播放器日志输出

1.2.5

  1. 调整播放器页面背景色和页面容器背景色为黑色
  2. 新增 VIDEO_REMOVED 事件表示该剧已下架
  3. isCanPlay 方法支持 useLastStatus 参数,表示沿用之前的解锁状态且无需传入加密数据

2024.4.28

缺陷修复

修复横屏下充值弹窗&推荐弹窗

2024.4.26

能力更新

1.支持横屏剧模式

2.分享组件开放,支持开发者调用分享接口

体验优化

1.切集loading首帧图片

2024.4.24

体验优化

1.演员&简介信息外露

2.公众号显示策略调整

2024.4.19

能力更新

1.支持配置单集循环播放

2.支持推荐位剧目批量设置

3.拼团体验优化

缺陷修复

iOS演员页显示

2024.4.16

能力更新

1.剧集详情页、演员页(安卓)

2024.4.12

能力更新

1.通用插屏广告、信息流广告组件(内测)

2.解锁按钮适配广告解锁场景

3.开放onShow事件,监听充值返回播放页面事件

体验优化

1.当前集、总集数显示优化

2.最近观看&在追组件标题支持隐藏

3.接口超时提示优化

缺陷修复

修复一些 bug

2024.4.8

体验优化

海报授权逻辑优化

2024.4.2

能力更新

保留观看进度

2024.3.25

能力更新

1.最近观看&追剧列表组件

2.接口新增setFreeList设置免费剧列表

3.支持原视频画质播放

缺陷修复

修复一些 bug

2024.3.19

能力更新

1.支持拼团

2024.3.15

能力更新

1.弹幕屏蔽策略

体验优化

预加载启用时间更新为视频最后10秒

缺陷修复

修复视频播放卡屏问题

2024.3.5

能力更新

1.支持弹幕互动

2.主界面布局优化

3.推荐位支持定义推荐剧目

缺陷修复

修复快速滑动剧集出现卡住问题等缺陷

2024.2.26

能力更新

1.支持预加载

2.支持api编程式跳转方式,支持:wx.switchTab wx.navigateTo

体验优化

1.保留上一集的观看进度

2.追剧提示文案时长调整

缺陷修复

修复分享海报相关缺陷

2024.2.2

体验优化

1.分享体验优化 2.剧目名称后缀过滤

缺陷修复

1.修复剧集过多时的Tab样式错乱等问题

2024.1.29

体验优化

1.视频加载速度优化

2.视频滑动切换优化

缺陷修复

1.修复视频转码问题

2024.1.22

能力更新

1.支持开发者自定义返回行为

体验优化

1.半屏优化:拉起选集页后视频缩小播放

2.视频加载速度优化

3.解锁页面添加蒙层,增加点击感

缺陷修复

1.修复播放方、授权方相同时,推荐库为空的问题

2024.1.12

能力更新

1.新增分享海报能力

2.前端接入Demo

3.投放兼容:若播放器是第一个页面,左上角的返回表现为返回首页

4.播放器内支持切换剧目/自动连播设置

5.分享的时候新增shareId上报给开发者

6.play和pause支持

体验优化

1.充值弹窗支持透明底色,高度限制调整

缺陷修复

1.单Tab时推荐Tab的样式问题

2024.1.8

能力更新

1.新增推荐位:选集页、剧集结束页

2.公众号关联优化

3.新增剧集授权接口

4.播放界面左侧新增列表自定义区域

体验优化

1.支持下拉收起选集页

2.备案号水印调整:左下角出现2秒

缺陷修复

1.插件样式隔离

2023.12.26

能力更新

1.新增题材、热度数据展示

2.支持跳转公众号profile页

3.防录屏/截屏

体验优化

1.基础体验优化

2.选集页交互优化

2023-12-20

支持一键关注公众号

2023-12-14

基础版本发布

# 附录

# 播放器后台返回码

描述
-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