plugin.PlayletExtension
接入说明
使用限制
版本校验
短剧拓展只在抖音、抖音极速版、抖音火山版 30.3 及以上版本支持,使用前可通过 canIUse 校验当前抖音能否使用。若不支持,开发者可使用 video-player 组件或提示用户升级抖音。
// 看播页内部 if (!tt.canIUse('PlayletExtension')) { // 调用构造器前,判断是否可用 // 跳转至开发者自有播放页 或提示用户升级抖音 tt.navigateTo({ url: `xxx`, }); } PlayletExtension({ xxx })
拓展引入
新建小程序组件,在index.json中对插件进行绑定
{ "extends": "ttf57583c86a3aace011://playlet-plugin", "usingComponents": { "player": "../components/player/player", "charge": "../components/charge/charge" }, "isPageExtension": true }
在 js 文件中,通过 PlayletExtension 构造器来注册扩展,并提供扩展的属性定义、内部数据和自定义方法。
const { PlayletExtension, getPlayletManager } = plugin; PlayletExtension({ pm: undefined, data: { xxx: '', }, methods: { onLoad(option) {}, onReady() { // 通过返回的handler pm 对插件页进行操作 const pm = getPlayletManager(this); this.pm = pm; this.pm.setConfig(...); }, // 开发者自定义方法 customFunction() {}, }, });
跳转和query
可直接跳转至绑定短剧的页面。
tt.navigateTo({ url: `/page/xxx/index?tt_album_id=${albumId}&tt_episode_id=${episodeId}`, });
续播
播放器支持自动定位到用户上次观看的集数和播放进度,需要开发者在query中增加is_continue=1,即可开启。当传入1时,播放器会根据当前tt_album_id续播用户上次播放的集数,如果没有观看记录,则播放tt_episode_id指定的集数。
续播需要用户观看时长超过5s,且更新时间有一定延迟。
参数说明
属性名 | 类型 | 必填 | 说明 |
tt_album_id | string | 是 | 拓展要打开的剧ID |
tt_episode_id | string | 是 | 拓展要打开的集数ID |
is_continue | string | 否 | 是否开启自动续播功能,传1为开启 |
沉浸式观看体验
在页面index.json 中,配置 "transparentTitle": "always" 对顶部导航栏透明化。
{ "extends": "ttf57583c86a3aace011://playlet-plugin", "usingComponents": {}, "transparentTitle": "always" }
避免Android拖动进度条触发返回
需在页面 index.json 中配置 "disableSwipeBack": "true" 以禁止当前页面侧滑返回
{ "extends": "ttf57583c86a3aace011://playlet-plugin", "usingComponents": {}, "transparentTitle": "always", "disableSwipeBack": true }
插件生命周期
onLoad
页面初始化时触发。一个页面只会调用一次。
- 1.调用页面路由传递的参数可以在目标页面的 onLoad 中获取;
- 2.在 onLoad 中不支持调用 setConfig、setCatalog 等主动 API
onShow
页面显示/切入前台时触发。该时机不能保证页面渲染完成,且会随页面可见性状态变化多次触发,如有页面/组件元素相关操作建议在 onReady 中处理。
onReady
页面初次渲染完成时触发。 一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
建议在onReady中注册播放器事件的回调;
onUnload
页面卸载时触发。
onHide
页面隐藏/切入后台时触发。
开发者主动调用
setConfig - 开发者设置分享信息和自定义icon
开发者为播放器设置分享、自定义icon等参数
语法
pm.setConfig(options)
参数说明
options 为 object 类型,属性如下:
属性名 | 类型 | 必填 | 说明 |
shareParam | ShareParam | 否 | 小程序分享参数 |
activityInfo | ActivityInfo[] | 否 | 配置右下角自定义button,当前仅展示Array中的第一个icon |
showLockPage | boolean | 否 | 是否展示解锁页,默认为true |
objectFit | 'contain' | 'cover' | 'fill' | 否 | 设置视频展现形式,竖屏场景默认为cover,横屏场景默认为contain |
playbackRate | 0.75 | 1.0 | 1.25 | 1.5 | 2 | 否 | 播放倍速,默认为1 |
catalogLockEnable | boolean | 否 | 开启setCatalog超时默认锁定全部剧集数的兜底,默认true |
catalogLockTimeout | number | 否 | setCatalog超时时间,单位秒,默认5s |
ShareParam
配置分享参数
属性名 | 类型 | 说明 |
title | string | 要转发的小程序标题 |
desc | string | 这是默认的转发文案,用户可以直接发送,也可以在发布器内修改 |
path | string | 示例:'page/xxx/index?tt_album_id=${albumId}&xxx=xxx' 后面的参数会在转发页面打开时传入onLoad方法 |
imageUrl | string | 支持本地或远程图片,默认是小程序 icon |
templateId | string |
ActivityInfo
配置右下角自定义button
属性名 | 类型 | 说明 |
icon | string | 自定义 icon 的图片(暂不支持本地文件) |
title | string | 自定义icon的标题,须填写 1-3 个汉字 |
PlaybackRate
配置播放器默认倍速
- •同一剧集数仅支持设置一次,后续调用无效,需在 onReady 生命周期中设置。
- •建议切换剧集数后可再次设置,应在 onChangeEpisode 时判断剧集数切换并设置。若不设置则保持与上一剧集数相同播放倍速。
// 首次进入时设置 onReady() { pm.setConfig({ playbackRate: 1.25 }) } // 推荐切剧 时再次设置 pm.onChangeEpisode((e) => { if (e.albumId !== this.albumId) { pm.setConfig({ playbackRate: 1.5 }) } })
返回值
无
使用示例
pm.setConfig({ shareParam: { // 分享数据 title: '测试小程序测试短剧 ', // 这是要转发的小程序标题 desc: '这是默认的转发文案,用户可以直接发送,也可以在发布器内修改', path: 'page/xxx/index?tt_episode_id=1&tt_album_id=${albumId}', // ?后面的参数会在转发页面打开时传入attached方法 imageUrl: 'https://e.com/e.png', // 支持本地或远程图片,默认是小程序 icon templateId: '这是开发者后台设置的分享素材模板id' }, activityInfo: [{ icon: 'https://xxx/xxx.png', title: '开辅助', }], playbackRate: 1.25, // 默认以1.25速度播放 catalogLockEnable: false, // 超时不锁定 });
getPlayletInfo - 开发者获取当前剧集数信息
开发者获取当前剧集数信息在 onReady 生命周期时,页面逻辑刚开始执行可能无法获取剧集数信息,建议在切换剧集数时获取。
语法
pm.getPlayletInfo()
参数说明
无
返回值
返回一个promise对象;
属性名 | 类型 | 说明 |
albumId | string | 剧ID |
seq | number | 集数 |
episodeId | string | 集数ID |
使用示例
pm.getPlayletInfo().then(res => { this.setData({ albumId: res.albumId, seq: res.seq, episodeId: res.episodeId }) });
setCatalog - 开发者更新目录设置
开发者主动更新当前目录•pm.setCatalog的调用需要在生命周期 - onReady中或onReady后。
•如果该方法未按要求调用,则默认 5s 后设置剧集数锁定。
语法
pm.setCatalog()
参数说明
options 为 object 类型,属性如下:
属性名 | 类型 | 默认值 | 必填 | 说明 |
lockList | {start_episode_no: number, end_episode_no: number}[] | [] | 否 | 拓展目录中,已锁定的页面范围 |
unlockList | {start_episode_no: number, end_episode_no: number}[] | [] | 否 | 拓展目录中,已解锁的页面范围 |
freeList | {start_episode_no: number, end_episode_no: number}[] | [] | 否 | 拓展目录中,免费的页面范围 |
返回值
无
使用示例
pm.setCatalog({ freeList: [{ start_episode_no: 1, end_episode_no: 5 }], unlockList: [{ start_episode_no: 6, end_episode_no: 10 }, { start_episode_no: 16, end_episode_no: 20 }, ], lockList: [{ start_episode_no: 11, end_episode_no: 15 }, { start_episode_no: 21, end_episode_no: 76 }, ], });
toggleCustomDialog - 开发者(打开 /关闭)自定义模块
充值模块显示规则:仅在短剧未解锁时出现
语法
pm.toggleCustomDialog(type?: 'open' | 'close')
参数说明
无
返回值
无
使用示例
// 观众点击“解锁按钮”时,可弹出自定义模块 pm.onClickUnlock((e) => { console.log("触发点击解锁按钮onClickUnlock回调:" , JSON.stringify(e,null,2)) pm.toggleCustomDialog(); })
setCurrentUnlock - 开发者设置当前集数为解锁
剧集数状态改变可以使用 setCatalog(范围)和 setCurrentUnlock(单集数)两种方式。如果本集数处于解锁状态,则该方法不生效。
语法
pm.setCurrentUnlock()
参数说明
无
返回值
无
使用示例
this.ad.onClose((data) => { if (data.isEnded) { console.log("观看了", data.count, "个视频"); pm.setCurrentUnlock(); } else { console.log("未观看完视频"); }
setPlayStatus - 开发者设置暂停/播放状态
调用后,可控制当前视频的暂停或播放状态。
语法
pm.setPlayStatus(status)
参数说明
status 为 string 类型,属性如下:
属性名 | 类型 | 默认值 | 必填 | 说明 |
status | 'play' 或者 'pause' | 无 | 是 | |
返回值
无
使用示例
pm.setPlayStatus('play') // 播放 pm.setPlayStatus('pause') // 暂停
setRecommendConfig - 设置推荐位
注意事项:目前推荐剧的toast弹窗需开发者自行制作,后续平台推出「基于平台算法推荐剧目」逻辑后,将自行封装 toast 弹窗(无需开发者开发)。
功能说明:新增短剧完播、左上角返回按钮支持推荐剧,开发者可设置推荐其他剧目。
setUnlockPreview - 设置试看
支持为已解锁剧集数设置指定时长的免费观看权限
接入文档详见:
setAdConfig - 配置Draw流广告策略
支持开启Draw流广告组件
接入文档详见:Draw流广告接入文档
观众行为回调
开发者可以使用 handler 处理注册的各种官方回调
pm.onPlay((e) => { console.log("触发开始播放onPlay回调:" , JSON.stringify(e,null,2)) }); pm.onPause((e) => { console.log("触发暂停播放onPause回调:" , JSON.stringify(e,null,2)) }); pm.onEnded((e) => { console.log("触发播放到末尾onEnded回调:" , JSON.stringify(e,null,2)) }); pm.onError((e) => { console.log("触发onError回调:" , JSON.stringify(e,null,2)) });
onPlay 视频开始播放
当视频开始播放时触发 play 事件。
使用示例
pm.onPlay((e) => { console.log("触发开始播放onPlay回调:" , JSON.stringify(e,null,2)) });
onPause 视频暂停
当视频暂停播放时触发 pause 事件。
使用示例
pm.onPause((e) => { console.log("触发暂停播放onPause回调:" , JSON.stringify(e,null,2)) });
onEnded 视频完成播放
当视频播放到末尾时触发 ended 事件。
使用示例
pm.onEnded((e) => { console.log("触发播放到末尾onEnded回调:" , JSON.stringify(e,null,2)) });
onError 视频播放出错
视频播放出错时触发 error 事件。视频播放类错误码可参考:video 视频
使用示例
pm.onError((e) => { console.log("触发onError回调:" , JSON.stringify(e,null,2)) });
onTimeUpdate 播放进度变化时
当播放进度变化时触发该事件,返回当前播放时间点及视频总时长,单位:秒(s)。
返回值
属性名 | 类型 | 说明 |
currentTime | number | 当前时间 |
duration | number | 视频总时长 |
使用示例
pm.onTimeUpdate((e) => { console.log("触发播放进度变化onTimeUpdate回调:" , JSON.stringify(e,null,2)) })
onProgress 视频缓冲进度更新
视频缓冲进度变化时触发该事件。
返回值
属性名 | 类型 | 说明 |
buffered | number | 百分比,取值是 [0, 100] 中的整数,如 buffered 为 50 表示当前视频缓冲了 50%。 |
使用示例
pm.onProgress((e) => { console.log("触发onProgress回调:" , JSON.stringify(e,null,2)) })
onWaiting 视频出现缓冲
视频出现缓冲时触发该事件。
使用示例
pm.onWaiting((e) => { console.log("触发onWaiting回调:" , JSON.stringify(e,null,2)) })
onPlayBackRateChange 视频倍速改变完成
视频倍速改变完成时触发该事件。返回改变后的倍速值。
返回值
属性名 | 类型 | 说明 |
playbackRate | number | 视频倍速 |
使用示例
pm.onPlayBackRateChange((e) => { console.log("触发onPlayBackRateChange回调:" , JSON.stringify(e,null,2)) })
onControlTap - 点击控件
点击控件时触发。返回当前点击的控件类型。取值见表 controlType 的合法值。注意:IDE 上的点赞、点亮是模拟操作,非真实抖音用户行为
controlType
值 | 说明 |
play | 播放控件 |
pause | 暂停控件 |
playbackRate | 在倍速选择面板点击具体速度 |
progress | 进度控件,在刚开始拖动进度条时触发 |
like | 点击喜欢 |
unlike | 点击不喜欢 |
share | 点击分享 |
subscribe | 点击追剧 |
unsubscribe | 点击取消追剧 |
openCatalog | 点击打开目录页 |
closeCatalog | 点击关闭目录页 |
userCloseCharge | 用户点击蒙层关闭充值页 |
openRatePanel | 点击打开播放速度选择面板 |
closeRatePanel | 点击关闭播放速度选择面板 |
使用示例
pm.onControlTap((e) => { console.log("触发onControlTap回调:" , JSON.stringify(e,null,2)) })
onOpenCatalog
当用户点击选集数时,系统触发该事件并通知开发者
使用示例
pm.onOpenCatalog((e) => { console.log("触发onOpenCatalog回调:" , JSON.stringify(e,null,2)) })
onChangeEpisode 观众切换剧集数
当用户点击选集数页中的具体集数,或通过上下滑动切换剧集数时,系统将触发事件并通知开发者
返回值
属性名 | 类型 | 说明 |
albumId | string | 剧ID |
seq | number | 集数 |
status | 'free'|'lock'|'unlock' | 解锁状态 |
scene | 'first_play' | 'swipe_next' | 'swipe_prev' | 'seq_select' | 切换集数归因,分别因为“首次播放” | “滑动向下” | “滑动向上” | “选集数”导致的剧集数变化; |
当 scene === 'first_play'(首次播 放)时,status 字段为 undefined,此时剧集数锁定状态尚未完成初始化(需执行 setCatalog 方法)
使用示例
pm.onChangeEpisode((e) => { this.printLog("触发选集数切换onChangeEpisode回调:", JSON.stringify(e, null, 2)) })
onClickUnlock 观众点击解锁按钮
观众在播放界面点击了“立即解锁”按钮如果setConfig中设置了showLockPage为false,则蒙层与按钮不展示,无法触发该方法;
返回值
属性名 | 类型 | 说明 |
albumId | string | 剧ID |
seq | number | 集数 |
episodeId | string | 集数ID |
使用示例
pm.onClickUnlock((e) => { this.ad.show(); // 监听视频播放完成 this.ad.onClose((data) => { if (data.isEnded) { console.log("观看了", data.count, "个视频"); // 也可以用 pm.setCatalog({}); 范围解锁 pm.setCurrentUnlock(); } else { tt.showToast({ title: '未观看完视频', }); } }); })
onTapShare 用户点击分享按钮,开发者返回实时分享参数
- 1.path 参数必须以'/'开头,缺失该符号将导致分享链接失效
- 2.onTapShare 的优先级高于 shareParam,如果同时设置则优先使用 onTapShare;
返回值
属性名 | 类型 | 说明 |
albumId | string | 剧ID |
seq | number | 集数 |
episodeId | string | 集数ID |
使用示例
pm.onTapShare((e) => { const {} return { // 分享数据 title: '小程序标题', // 这是要转发的小程序标题 desc: '描述', path: 'page/xxx/index?tt_episode_id=1&tt_album_id=${albumId}', // ?后面的参数会在转发页面打开时传入attached方法 imageUrl: 'https://e.com/e.png', // 支持本地或远程图片,默认是小程序 icon templateId: '这是开发者后台设置的分享素材模板id' }, })
onShareSuccess 观众分享成功
使用示例
pm.onShareSuccess((res) => { console.log('shareSuccess-uuuu', res); })
onShareFail 观众分享失败
使用示例
pm.onShareFail((err) => { console.log('shareFail-uuuu', err); })
onTapCustomIcon 点击右下角自定义icon
返回值
属性名 | 类型 | 说明 |
index | number | 点击第几个自定义icon |
使用示例
pm.onTapCustomIcon((e) => { // 调用开发者自定义逻辑 })
onAddShortCut 添加桌面相关能力回调
当用户展示、关闭或点击添加桌面功能时,系统将触发对应事件
请使用tt.canIUse('playlet-plugin.onAddShortCut')判断该 API 是否可用
使用示例
pm.onAddShortCut((e) => { console.log("触发开始播放onAddShortCut回调:" , JSON.stringify(e,null,2)) });
返回值
属性名 | 类型 | 说明 |
type | 'show' | 'click' | 'close' | 播放器展示、点击或关闭添加桌面按钮时 |
position | 'bottom' | 'function_area' | 添加桌面位置:底部、功能区 |
开发者自定义组件
该能力已完成对外,官方文档:插件扩展能力在短剧拓展场景中,需要定制的能力包括以下两种场景
创建插槽节点
自定义组件名必须包含 player 和 charge,否则组件将无法被正确识别和渲染。
在 js 文件中,通过 PlayletExtension 构造器来注册扩展,并提供扩展的属性定义、内部数据和自定义方法。
const { PlayletExtension, getPlayletManager } = plugin; PlayletExtension({ data: { idNo: '', }, methods: { // 开发者自定义方法 customFunction() {}, }, });
在对应的页面json文件中,配置自定义组件的路径;
{ "extends": "ttf57583c86a3aace011://playlet-plugin", "usingComponents": { "player": "../components/player/player", "charge": "../components/charge/charge" }, "disableSwipeBack": true, "isPageExtension": true }
在对应路径正常开发自定义组件;
OpenAPI
新播放插件页外--取消追剧
接口
基本信息
HTTP URL | |
HTTP Method | POST |
HTTP Header |
Content-Type : 传固定值application/json
access-token : 调用/oauth/client_token/生成的 token。示例: clt.xxxxxxxxxxxxxxxxxxxxx |
请求参数
字段名 | 类型 | 是否必填 | 描述 | 示例值 |
open_id | string | ✅ | 关联小程序下具体用户 | "_000PwN_t4yU4LqFa9fvtspS75sn0x3lq_L_" |
action_type | number | ✅ | 固定值,填2 | 2 |
action | number | ✅ | 固定值,填2 | 2 |
album_id | string | ✅ | 剧ID | "7330893816926962228" |
响应参数
字段名 | 类型 | 是否必填 | 描述 | 示例值 |
err_no | number | ✅ | 错误码
| 0 |
err_msg | string | ✅ | 错误信息 | "" |
请求示例
// 请求示例 curl --location 'https://open.douyin.com/api/resource_library/v1/user_action/' \ --header 'Tt-Host-Scheme: https' \ --header 'Content-Type: application/json' \ --header 'X-Tt-Logid: 02172051122807000000000000000000000ffff0a9a641dd13b7d' \ --header 'jaeger-baggage;' \ --header 'access-token: clt.XXXXXXXXXXX_hl' \ --header 'byted-trace-id: 108f945fa829c54506e16058b8b2f73:15247a0ac834c93e:15247a0ac834c926:5' \ --header 'traceparent: 02-0108f945fa829c54506e16058b8b2f73-15247a0ac834c93e-05' \ --header 'tracestate;' \ --header 'Cookie: passport_csrf_token=551e70161bac7ca39949a9edd36a81eb; passport_csrf_token_default=551e70161bac7ca39949a9edd36a81eb' \ --data '{ "open_id": "_000PwN_t4yU4LqFa9fvtspS75sn0x3lq_L_", "action_type": 2, "action": 2, "album_id": "1234" }' // 响应示例 { "err_no": 0, "err_msg": "", "log_id": "02172051122807000000000000000000000ffff0a9a641dd13b7d" }
第三方框架接入
uniapp
在page.json中进行依赖配置"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages { "path": "pages/index/index" }, { "path": "pages/playlet/index", "style": { "extends": "ttf57583c86a3aace011://playlet-plugin", "isPageExtension": true } } ],在对应页面中进行插件声明<template> </template> // template标签中的dom不会被应用在插件页中 <script> import Player from '@/components/player/player.vue'; import Charge from '@/components/charge/charge.vue'; const { PlayletExtension } = plugin; export default { components: { Player, Charge }, methods: { onShow() { console.log('show'); } }, }; </script>(如果需要)使用uniapp语法引入component自定义组件,参考{ Player, Charge }的引用自定义组件与播放页无法进行通信,但可通过pm.getPlayletInfo或pm.onPlay获取参数在 player 或 charge 组件中,通过 const pm = await getPlayletManager({ is: "player | charge" }) 建立通信(需与插槽名称一致)
附:无法播放、卡顿等常见播放问题指引
通用排查思路
关键词:播放器丨播放问题 | 卡顿 | 无法播放 | 卡死 | 播不了 | 不可播 | 不能播 | Video | 诊断工具 | 用户反馈
一、针对常见播放问题,各位开发者可通过诊断工具快速获取原因。
二、查看用户反馈截图上所打印的信息,进一步判断可能的原因。
反馈时所处播放生命周期(status):
- ▪
创建 video 中(onCreate)
- ▪正在准备播放(onPrepare)
- ▪已准备好播放(onPrepared)
- ▪缓冲中(onBufferStart)
- ▪缓冲结束(onBufferEnd)
- ▪遇到报错(onError(code=XXX, msg=XXX))
反馈时所播放视频的码率信息(bitRate)
- ▪截图打印信息中的码率的单位为 bps,建议不大于 1024kbps,建议值为 600kbps
- •如果较多的反馈处于 onPrepare、onBufferStart 状态或 bitRate 显示大于 1024kbps,则可能与视频码率过大有关。
- •如果处于onError状态,可以通过参照错误码列表进行处理。
- •如果仅有“截图已打印调试信息”字样,无其他内容,则尚未走到播放环节,请排查前置流程。
三、如您已明确问题与视频码率有关,可按如下步骤处理:
【推荐】使用抖音云MP4转码,建议选择极致超清 MP4 720P H.265(在同等观感下码率更低);
修改您的转码参数:
- ◦CRF质量等级不大于23
- ◦编码格式为H.265
- ◦分辨率不大于720P
四、若无法通过上述办法获取原因,请开发者在遇到问题时,立即通过小程序右上角进行反馈,并告知反馈内容或反馈 id。(此步骤有助于提升问题跟进和原因定位效率。)
白屏表现排查思路
黑屏表现排查思路
- 1.视频没有声音没有画面,检查抖音云域名证书是否正常、域名是否欠费
- 2.视频有声音没画面,重启抖音 App 并多次操作:关闭抖音 App 后台后重新进入
