# 短剧插件能力

更新时间: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 } // 追剧功能
        },
        // ...
    ]
}

# 插件参数说明

属性类型默认值是否必填说明
showPlaybackRateBtnbooleantrue是否展示播放设置倍速按钮
playletIdstring-剧目id(上传内容库返回的id)
episodeIdListstring[]-播放的剧集id
playIdstring /  number-指定播放剧集id或者是剧集数(剧集数只在三方cdn 生效)
extParamsextParamsType(见下文 extParamsType 配置说明)-扩展参数+三方cdn播放数据
seriesInfoobject (见下文 seriesInfo 配置说明)-剧集的一些信息
showShareboolean-是否展示分享按钮
bindnopermissionplayfunction-无播放权限时回调
binderrorfunction-视频播放出错时触发
bindactionfunction-用户功能区点击时回调
bindchangefunction-播放剧集切换时回调
bindendfunction-剧集播放结束
bindpausefunction-剧集播放暂停
bindplayfunction-剧集播放
bindsubscribefunction-点击更新提醒我按钮
bindbackfunction-点击导航栏返回按钮

# extParamsType 配置说明

属性类型默认值是否必填说明
freeListnumber[]-免费剧集list
payedListnumber[]-已支付list,用户支付完后更新此字段,会完成继续播放
configListObject(见下文 configList 数据格式)-右侧功能信息(点赞数、关注、运营位数据)
sourceListObject-三方播放数据时必传
关于 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 配置说明

属性类型默认值是否必填说明
titlestring-短剧标题
countnumber-总集数
playletIdstring-剧目id
introductionstring-剧情介绍
isEndbooleanfalse是否完播
filingInfostring-备案信息
listarray (见下文 list 配置说明)[ ]剧集的一些信息
isFollowbooleanfalse是否已经订阅提醒
isMinibooleanfalse选集风格
stepnumber6选集区间范围
list 配置说明
属性类型默认值是否必填说明
videoUrlstring-视频地址(在1.76.0以下低版本中使用)
episodeIdnumber-剧集id
indexstring-剧集号
coverUrlstring-视频封面(在1.76.0以下低版本中使用)
durationstring-播放时长
playCountnumber-播放数量
picUrlstring-选集封面
titlestring-标题
like{ "liked": boolean, "likedCount": number }-喜欢数据
follow{ "avatar": string, "followed": boolean }-头像+关注数据
collect{ "hasCollected": boolean }-追剧数据
isLockboolean-是否需要解锁观看

# 组件事件

# bindnopermissionplay 说明

无权限播放的回调,开发者需要针对此状态做对应的支付or广告解锁操作,操作完成后需更新 extParams.payedList 数据,从而完成短剧播放的履约部分。

bindnopermissionplay({ detail }) {
    // 开发者可以在该方法中处理业务自定义的逻辑,如打开支付面板和广告组件解锁短剧等。
}

事件对象的 detail 为 object 类型,属性如下

属性名类型说明
playletIdnumber剧目id
episodeNumbernumber当前剧集号

开发者自定义支付面板和广告组件,不在插件管控范围内。但是推荐使用官方的 pay-dialog ​组件)

# binderror 说明

播放异常信息。事件对象的 detail 为 object 类型,属性如下

属性名类型说明
errMsgstring组件内部错误信息
errCodenumber错误码,对应某种具体报错原因

# 错误码

错误码说明说明
10000424短剧不存在
10000427短剧已经下线
10000426当前小程序无权限播放该短剧
10000428短剧分集不存在
10000429视频播放链接获取失败
10000500未知错误
10000501内部未知错误
10001001播放器内部错误
10001002禁止播放外部视频资源
103playletId 不合法
104eposideIdList  不合法

# 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 类型,属性如下

属性名类型说明
actionboolean动作行为(eg:点赞 true,去掉点赞 false)
actionTypestring

用户动作数据

'like' 点赞

'collect' 收藏

'follow' 关注

'operation' 运营位点击

'share' 分享

episodeNumberstring当前剧集号

# 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 类型,属性如下

属性名类型说明
episodeIdstring当前剧集id
playEpisodeNumbernumber当前剧集号
fromstring

切换时触发的来源

'list' 点击选集列表按钮

‘swiper’ 滑动swiper

‘video’ 点击下一集按钮

# bindend 说明

剧集播放结束事件。事件对象的 detail 为 object 类型,属性如下

属性名类型说明
episodeIdstring当前剧集id
playEpisodeNumbernumber当前剧集号

# bindpause 说明

剧集暂停事件。事件对象的 detail 为 object 类型,属性如下

属性名类型说明
episodeIdstring当前剧集id
playEpisodeNumbernumber当前剧集号

# bindplay说明

剧集播放事件。事件对象的 detail 为 object 类型,属性如下

属性名类型说明
episodeIdstring当前剧集id
playEpisodeNumbernumber当前剧集号
typestring

播放类型

'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 组件的参数,那么迁移到插件是相对简单的。

Copyright ©2025, All Rights Reserved