开发 能力接入指南 短剧插件
# 短剧插件能力
更新时间:2025-04-10 14:19:09
通过插件的形式,我们预先实现了全套短剧功能(视频上下滑、选集、倍速、订阅的功能),小程序开发者只需要直接引入相应插件,并且遵循插件约定的规范,与插件之间实现相互通信,即可完成相应的短剧页面,从而提高开发效率。
# 核心功能介绍
功能模块 | 功能描述 | UI示例图 |
右侧功能区
| 在右侧固定位置,提供了头像+关注、喜欢、追剧、分享、运营位的共 5 个功能,开发者可以选择性的配置相关功能 喜欢:点击按钮,按钮变成红色,反之则取消喜欢 通过接口进行点赞数据统计(需开发者实现) 分享:点击按钮,拉起快手分享能力 关注:点击加号按钮,关注后加号消失 运营位:支持在运营位中自定义图片,进行个性化营销活动的推广 追剧:点击按钮,按钮变成黄色,反之则取消追剧 建议追剧能力与订阅消息提醒联动,点击追剧后拉起订阅消息,获取用户接收订阅追剧消息授权,授权完成后,将在快手侧边栏消息通知里向用户发送追剧消息提醒,引导用户完成复访(需开发者实现) 或者是通过接口保存追剧状态,并展示在小程序其他页面,如首页追剧模块、个人中心追剧模块(需开发者实现) | ![]() ![]() |
播放功能
| 顶部导航栏:平台默认提供透明顶部导航栏效果,用户可更沉浸式观剧 支持在顶部导航栏返回按钮增加回调信息,便于开发者基于该用户行为,进行自定义挽留策略,如付费挽留、好剧推荐等。 播放页面: 点击视频区域可暂停 or 播放 手动下滑下拉切换下集,上滑切换上集 点击下一集按钮切换下集(1.76.0以下低版本基础库使用此方案) 进度调节: 默认1倍速播放,支持的调节按钮为 0.5倍、1倍、1.5倍、2倍 支持用户手动拖动底部进度条,进行进度调节 底部固定播放设置,点击播放设置按钮,可以选择倍速 |
|
选集面板
| 平台提供统一选集面板:点击底部选集面板按钮,展示选集面板弹窗 顶部信息区:默认展示短剧标题、剧情介绍、总集数、完结状态、选集区间按钮、版权方 选集信息区:支持两种风格,开发者可以选择性的配置相关功能 第一种是默认风格,可展示封面、作品描述、时长、播放数量 第二种是mini简约风格,仅展示第几集的按钮 底部固定功能区:展示更新提醒我按钮 剧集播放:点击具体剧集号进入该集播放 免费集用户点击可以直接播放,非免费集需要解锁后观看。 解锁集数需要开发者自行制定,同时需告知解锁形式(付费/广告),用于支持开发者对应不同的后续交互流程,如免费集则默认播放、付费集拉齐支付面板、广告集拉起为广告组件。前端模板提供了一个组件 pay-dialog,该组件是小程序基础库内置组件,可直接使用。具体使用方式,请参见 pay-dialog 交易弹窗。该组件非必接,可基于实际情况接入。 | ![]() ![]() |
# 准备工作
请按照《短剧类小程序接入内容备案审核系统公告》 (opens new window)备案和上传视频。
# 使用教程
# 引入插件代码包
使用插件前,使用者要在 app.json 中声明需要使用的插件,如下所示:
{
"plugins": {
"playletTemplate": {
"provider": "pluginc2e8e7d587"
}
}
}
# 使用插件中的组件
插件的自定义组件和普通的自定义组件使用方法类似。在需要使用插件的小程序页面 .json 文件中,定义需要引用的插件自定义组件时,通过 plugin:// 协议指明需要引用的插件自定义组件,如下所示:
{
"usingComponents": {
"playlet-plugin": "plugin://playletTemplate/playlet-plugin"
}
}
在使用插件的小程序页面 .ksml 文件中,使用上一步声明依赖的插件 Component。注意:插件内部元素不支持嵌套插槽(slot)。
<playlet-plugin
ks:if="{{showPlaylet}}"
playletId="{{playletId}}"
episodeIdList="{{episodeIdList}}"
playId="{{playId}}"
extParams="{{extParams}}"
bindchange="bindchange"
bindnopermissionplay="bindnopermissionplay"
bindpause="bindpause"
bindplay="bindplay"
bindend="bindend"
seriesInfo="{{videoData}}"
bindaction="bindaction"
bindsubscribe="bindsubscribe"
bindback="bindback" />
在使用插件的小程序页面 .js 文件中,如下所示:
import { getSeriesData } from './api';
Page({
data: {
videoData: {},
episodeIdList: [],
extParams: {
payedList: [],
freeList: [],
configList: {},
},
playId: '',
playIndex: 1,
playletId: '',
playEpisodeId: '',
showPlaylet: false,
},
async onReady() {
// 请求视频数据
ks.showLoading();
const data = await getSeriesData('yourappid');
this.mormalizeData(data);
ks.hideLoading();
},
bindaction(e) {
const { type, action } = e.detail;
switch (type) {
case 'collect':
console.log('点击收藏', action);
break;
case 'like':
console.log('点赞', action);
break;
case 'follow':
console.log('点击关注');
break;
case 'operation':
console.log('点击运营位');
break;
};
},
mormalizeData(data) {
// 处理返回的数据
const episodeIds = [];
const freeList = [];
const configList = {};
data.list.forEach(item => {
episodeIds.push(item.episodeId);
if (!item.isLock) {
freeList.push(item.index);
}
configList[item.index] = {
like: item.like,
collect: item.collect,
follow: item.follow,
operation: {
operationUrl: 'https://yourimage.png',
operationDesc: '运营位',
},
}
});
this.setData({
videoData: data,
episodeIdList: episodeIds,
showPlaylet: true,
playletId: data.playletId,
playEpisodeId: data.list[0].episodeId,
playId: data.list[0].episodeId,
extParams: {
freeList,
configList,
payedList: []
}
})
},
bindchange(e) {
console.log('切换视频', e);
this.setData({
playIndex: e.detail.playEpisodeNumber,
playId: e.detail.from === 'swiper' ? this.data.playId : e.detail.episodeId,
playEpisodeId: e.detail.episodeId,
});
},
bindnopermissionplay(e) {
console.log('无播放权限,执行拉起支付组件操作', e);
},
bindpause(e) {
console.log('视频暂停', e);
},
bindend(e) {
console.log('播放结束', e);
},
bindplay(e) {
console.log('播放开始', e);
},
bindsubscribe() {
console.log('点击更新提醒我按钮');
},
bindback() {
console.log('点击导航栏返回按钮');
},
});
# 关于 getSeriesData 数据格式
{
"title": "短剧模版", // 标题
"count": 10, // 总集数
"introduction": "剧情介绍:肖青禾是大名鼎鼎的女影帝,这天她在泡澡时,不满的女主她在泡澡的时候,不满的吐槽经纪人给自己找了部烂剧,说这个剧集男主角长得太丑,本身就不愿意一同去进行剧集的拍摄,但是给的钱很多她也只好同意,导致出现了一系列的故事。",
"filingInfo": "版权方:快手开放平台", // 版权方
"pageSize": 10,
"pageIndex": 1,
"isEnd": true, // 完结状态
"playletId": "kmp5220516518114815260", // 剧目id
"isFollow": true, // 是否已订阅更新提醒
"isMini": false, // 选集风格
"step": 6, // 选集区间范围
"list": [
{
"title": "第1集的标题", // 剧集标题
"playCount": 100, // 播放数量
"duration": "04:03", // 播放时长
"picUrl": "https://yourimage.png", // 选集封面
"videoUrl": "https://yourvideo.mp4", // 视频地址
"coverUrl": "https://yourimage.png", // 视频封面
"index": 1, // 剧集号(对应上传资源库的 episodeNumber)
"episodeId": "kmp5214324068735814356", // 剧集id
"isLock": false, // 是否需要解锁观看
"id": 0,
"like": { "liked": false, "likedCount": 1 }, // 点赞数据
"follow": {
"avatar": "https://yourimage.png",
"followed": false // 头像+关注数据
},
"collect": { "hasCollected": false } // 追剧功能
},
// ...
]
}
# 插件参数说明
属性 | 类型 | 默认值 | 是否必填 | 说明 |
showPlaybackRateBtn | boolean | true | 否 | 是否展示播放设置倍速按钮 |
playletId | string | - | 否 | 剧目id(上传内容库返回的id) |
episodeIdList | string[] | - | 否 | 播放的剧集id |
playId | string / number | - | 否 | 指定播放剧集id或者是剧集数(剧集数只在三方cdn 生效) |
extParams | extParamsType(见下文 extParamsType 配置说明) | - | 否 | 扩展参数+三方cdn播放数据 |
seriesInfo | object (见下文 seriesInfo 配置说明) | - | 是 | 剧集的一些信息 |
showShare | boolean | - | 否 | 是否展示分享按钮 |
bindnopermissionplay | function | - | 否 | 无播放权限时回调 |
binderror | function | - | 否 | 视频播放出错时触发 |
bindaction | function | - | 是 | 用户功能区点击时回调 |
bindchange | function | - | 是 | 播放剧集切换时回调 |
bindend | function | - | 否 | 剧集播放结束 |
bindpause | function | - | 否 | 剧集播放暂停 |
bindplay | function | - | 否 | 剧集播放 |
bindsubscribe | function | - | 否 | 点击更新提醒我按钮 |
bindback | function | - | 否 | 点击导航栏返回按钮 |
# extParamsType 配置说明
属性 | 类型 | 默认值 | 是否必填 | 说明 |
freeList | number[] | - | 否 | 免费剧集list |
payedList | number[] | - | 否 | 已支付list,用户支付完后更新此字段,会完成继续播放 |
configList | Object(见下文 configList 数据格式) | - | 否 | 右侧功能信息(点赞数、关注、运营位数据) |
sourceList | Object | - | 否 | 三方播放数据时必传 |
关于 configList 数据格式
// 集数 -> 对应的用户功能信息
{
1: { // key为 剧集号,对应上传资源库的episodeNumber
"like": {
"liked": true, // 是否已点赞、是否展示
"likedCount": 100, // 数字
},
"collect": {
"hasCollected": true, // 是否已收藏
},
"operation": {
"operationUrl": "https:yourimage.png", // 运营位图片
"operationDesc": "运营位" // 运营位描述
},
"follow": {
"avatar": "https:yourimage.png", // 头像
"followed": true // 是否已关注
}
}
}
# seriesInfo 配置说明
属性 | 类型 | 默认值 | 是否必填 | 说明 |
title | string | - | 是 | 短剧标题 |
count | number | - | 是 | 总集数 |
playletId | string | - | 是 | 剧目id |
introduction | string | - | 是 | 剧情介绍 |
isEnd | boolean | false | 是 | 是否完播 |
filingInfo | string | - | 是 | 备案信息 |
list | array (见下文 list 配置说明) | [ ] | 是 | 剧集的一些信息 |
isFollow | boolean | false | 否 | 是否已经订阅提醒 |
isMini | boolean | false | 否 | 选集风格 |
step | number | 6 | 否 | 选集区间范围 |
list 配置说明
属性 | 类型 | 默认值 | 是否必填 | 说明 |
videoUrl | string | - | 是 | 视频地址(在1.76.0以下低版本中使用) |
episodeId | number | - | 是 | 剧集id |
index | string | - | 是 | 剧集号 |
coverUrl | string | - | 是 | 视频封面(在1.76.0以下低版本中使用) |
duration | string | - | 否 | 播放时长 |
playCount | number | - | 否 | 播放数量 |
picUrl | string | - | 否 | 选集封面 |
title | string | - | 否 | 标题 |
like | { "liked": boolean, "likedCount": number } | - | 否 | 喜欢数据 |
follow | { "avatar": string, "followed": boolean } | - | 否 | 头像+关注数据 |
collect | { "hasCollected": boolean } | - | 否 | 追剧数据 |
isLock | boolean | - | 否 | 是否需要解锁观看 |
# 组件事件
# bindnopermissionplay 说明
无权限播放的回调,开发者需要针对此状态做对应的支付or广告解锁操作,操作完成后需更新 extParams.payedList 数据,从而完成短剧播放的履约部分。
bindnopermissionplay({ detail }) {
// 开发者可以在该方法中处理业务自定义的逻辑,如打开支付面板和广告组件解锁短剧等。
}
事件对象的 detail 为 object 类型,属性如下
属性名 | 类型 | 说明 |
playletId | number | 剧目id |
episodeNumber | number | 当前剧集号 |
开发者自定义支付面板和广告组件,不在插件管控范围内。但是推荐使用官方的 pay-dialog 组件)
# binderror 说明
播放异常信息。事件对象的 detail 为 object 类型,属性如下
属性名 | 类型 | 说明 |
errMsg | string | 组件内部错误信息 |
errCode | number | 错误码,对应某种具体报错原因 |
# 错误码
错误码说明 | 说明 |
10000424 | 短剧不存在 |
10000427 | 短剧已经下线 |
10000426 | 当前小程序无权限播放该短剧 |
10000428 | 短剧分集不存在 |
10000429 | 视频播放链接获取失败 |
10000500 | 未知错误 |
10000501 | 内部未知错误 |
10001001 | 播放器内部错误 |
10001002 | 禁止播放外部视频资源 |
103 | playletId 不合法 |
104 | eposideIdList 不合法 |
# bindaction 说明
用户右侧功能区点击动作的回调,开发者需要在此函数中根据动作类型做出相应的逻辑处理,比如请求接口更新点赞数据。
bindaction({ detail }) {
const playIndex = this.data.playIndex;
switch (detail.type) {
case 'like':
// 调用点赞接口 ks.request({ url: 'https://yourapi' })
// 点赞完成之后需要更新 extParams 数据
const likedCount = this.data.extParams.configList[playIndex].like.likedCount;
const count = detail.action ? likedCount - 1 : likedCount + 1;
this.setData({
[`extParams.configList[${playIndex}.like.likedCount]`]: count;
});
break;
case 'collect':
// 建议追剧能力与订阅消息提醒联动 ks.requestSubscribeMessage({ tmplIds: ['xxx'] })
// 或者调用收藏接口 ks.request({ url: 'https://yourapi' })
this.setData({
[`extParams.configList[${playIndex}].collect.hasCollected`]: detail.action;
});
break;
case 'follow':
// 调用关注接口 ks.request({ url: 'https://yourapi' })
this.setData({
[`extParams.configList[${playIndex}].follow.followed`]: detail.action;
});
break;
case 'operation':
// 开发者可以在该方法中处理业务自定义的逻辑
break;
case 'share':
// 开发者可以在该方法中处理业务自定义的逻辑
break;
}
}
事件对象的 detail 为 object 类型,属性如下
属性名 | 类型 | 说明 |
action | boolean | 动作行为(eg:点赞 true,去掉点赞 false) |
actionType | string | 用户动作数据 'like' 点赞 'collect' 收藏 'follow' 关注 'operation' 运营位点击 'share' 分享 |
episodeNumber | string | 当前剧集号 |
# bindchange 说明
剧集切换事件。开发者需要在此函数中更新 playId 参数,让选集按钮能够在视频切换后也能被选中。
bindchange({ detail }) {
this.setData({
playIndex: detail.playEpisodeNumber,
playId: detail.from === 'swiper' ? this.data.playId : detail.episodeId, // tips:如果在swiper回调中setData改变playId值,则有可能导致setData被不停地调用
playEpisodeId: detail.episodeId,
});
}
事件对象的 detail 为 object 类型,属性如下
属性名 | 类型 | 说明 |
episodeId | string | 当前剧集id |
playEpisodeNumber | number | 当前剧集号 |
from | string | 切换时触发的来源 'list' 点击选集列表按钮 ‘swiper’ 滑动swiper ‘video’ 点击下一集按钮 |
# bindend 说明
剧集播放结束事件。事件对象的 detail 为 object 类型,属性如下
属性名 | 类型 | 说明 |
episodeId | string | 当前剧集id |
playEpisodeNumber | number | 当前剧集号 |
# bindpause 说明
剧集暂停事件。事件对象的 detail 为 object 类型,属性如下
属性名 | 类型 | 说明 |
episodeId | string | 当前剧集id |
playEpisodeNumber | number | 当前剧集号 |
# bindplay说明
剧集播放事件。事件对象的 detail 为 object 类型,属性如下
属性名 | 类型 | 说明 |
episodeId | string | 当前剧集id |
playEpisodeNumber | number | 当前剧集号 |
type | string | 播放类型 'START_PLAY' 开始播放 'PLAY' 继续播放 |
# bindsubscribe 说明
默认会展示订阅更新提醒按钮,当配置 seriesInfo.isFollow 为 true 时不展示,按钮点击后 bindsubscribe 会触发。建议更新提醒我功能与订阅消息提醒联动,点击按钮后拉起订阅消息,获取用户接收订阅追剧消息授权,授权完成后,将在快手侧边栏消息通知里向用户发送追剧消息提醒,引导用户完成复访。该功能非必接,可基于实际情况接入。
bindsubscribe() {
ks.requestSubscribeMessage({
tmplIds: ['YOUR_TEMPLATE_ID'],
success() {
ks.showToast({
title: '订阅成功',
icon: 'success',
duration: 2000,
});
}
});
}
# bindback 说明
返回按钮的回调信息,便于开发者基于该用户行为,进行自定义挽留策略,如付费挽留、好剧推荐等。平台默认提供透明顶部导航栏效果,需要开发者在 page.json 中设置 "navigationStyle": "custom" 配置才会生效。
bindback() {
// 在这里可进行自定义挽留策略,或者直接返回页面
ks.navigateBack();
}
# 接入
快手小程序接入,可通过开发者工具中选择模版选项中的短剧模版快速接入。
第三方框架接入,参考:链接1 (opens new window)、链接2 (opens new window)。
对于现有开发者来说,如果之前使用了 playlet (opens new window) 组件开发页面,由于插件是完全兼容 playlet 组件的参数,那么迁移到插件是相对简单的。