最近更新时间:2024.03.27 16:56:32
首次发布时间:2023.06.06 17:56:58
视频点播为抖音小程序播放场景提供播放器、日志上报、滑动切换等一系列 SDK 和组件,助您实现需要的业务功能。
播放器 SDK:提供完善的播放控制与良好的交互体验。
日志上报 SDK:支持上报播放日志,覆盖播放量、播放失败率、首帧时间、卡顿率等播放指标,与质量平台配合使用,可实现精细化的指标统计、实时的数据监控和深度的指标分析。
滑动切换组件:在视频竖屏上下滑动的播放场景中,实现流畅顺滑的切换效果。
具体效果如下:
您需要在小程序后台 > 开发 > 开发设置 > 服务器域名中添加日志上报域名 https://mcs.zijieapi.com
。
操作截图示例如下。
说明
视频资源的 CDN 域名不需要添加到域名配置中。
# npm npm i veplayer-mp-douyin // 播放器 SDK npm i veplayer-mp-logger // 日志上报 SDK npm i veplayer-mp-swiper-douyin // 滑动切换组件 # yarn yarn add veplayer-mp-douyin // 播放器 SDK yarn add veplayer-mp-logger // 日志上报 SDK yarn add veplayer-mp-swiper-douyin // 滑动切换组件
说明
构建前,请先了解抖音开放平台官网对于 npm 功能的介绍。
在抖音开发者工具编辑器左侧功能栏 NPM功能:依赖管理中点击 npm 构建。
在页面的 JSON 文件中引入 SDK 和组件。详情请参考抖音小程序自定义组件的使用方式。
{ "usingComponents": { "veplayer": "ext://veplayer-mp-douyin/veplayer" // 播放器 SDK "veplayer-swiper": "ext://veplayer-mp-swiper-douyin/veplayer-swiper", // 滑动切换组件容器 "veplayer-swiper-item": "ext://veplayer-mp-swiper-douyin/veplayer-swiper-item" // 滑动切换组件播放器容器 } }
注意
如果您使用的是抖音开发者工具 4.1.0 之前的版本,请注意其 npm 功能存在缺陷。您需要手动将 node_modules
下的 veplayer-mp-douyin
复制到 components
内,并删掉 package.json
中的 veplayer-mp-douyin
依赖。之后,您需要更新组件引用路径为 /components/veplayer-mp-douyin/dist/index
。
在火山引擎视频点播控制台,新建应用并获取应用 ID(App ID)。
引入日志上报 SDK,并在页面加载前设置日志上报 SDK 的构造器。代码示例如下所示:
import { initCollector } from 'veplayer-mp-logger' initCollector({ appId: xxxx, // 火您可在火山引擎视频点播控制台上获取应用 AppID userId: '7231102**007992', // 用户 ID,强烈建议您使用与业务相关的用户 ID。如不传入,SDK 将随机生成一个值 })
说明
setCollector
方法第二项参数中的 userId
。这是用于识别单一用户的 ID。强烈建议您使用与业务密切相关的用户 ID,以便在播放过程中出现错误时,可以进行单点故障排查,精确定位问题。如果您没有设定用户 ID,组件将随机生成一个。按照如下示例代码在项目中引用播放器 SDK。
<view> <!-- 以下是对小程序播放器 SDK 的引用 --> <veplayer id="videoContainer" src="{{src}}" muted loop logInfo="{{logInfo}}" /> </view>
在对应业务组件中添加日志上报需要的视频配置信息,代码示例如下:
// index.js Component({ data: { src: 'https://xxxx.mp4', logInfo: { vtype: 'MP4', // [可选]播放类型,默认为 'MP4'。'HLS' || 'MP4' codecType: 'h264', // [可选]视频编码类型,默认 h264。'h264' || 'h265' sourceType: 'url', // [可选]播放资源类型,可选 'url' bitrate: 1334556, // [可选]视频码率,默认为 0 tag: 'myTag', // [可选]播放场景 subtag: 'subtag', // [可选]二级播放场景 logger: true, // [可选]是否开启 log 打印,默认 false,开发环境可设置为 true } } })
视频信息配置完成后,如需查看日志上报数据,可以按以下操作步骤进行:
登录视频点播控制台。
选择左侧导航栏下的质量平台 > 播放看板,跳转至播放看板页面,并点击大盘速览标签。
在查询条件中选择抖音小程序。具体操作步骤可参考查看大盘速览。
说明
我们只收集 Android 和 iOS 真机上运行的小程序播放数据。通常数据存在 5-10 分钟的延时。如果长时间看不到数据,可能是因为您通过开发者工具模拟器或桌面端微信播放的小程序数据被过滤掉了。
滑动切换组件包含以下两个部分:
veplayer-swiper
: 基于抖音小程序开放平台的 swiper 开发,可作为轮播视图的容器。veplayer-swiper-item
: 基于抖音小程序开放平台的 swiper-item 开发,可作为播放器的容器。在 player/index.ttml
文件引用 veplayer-swiper
和 veplayer-swiper-item
组件。请注意以下参数的设置:
index
:播放列表的序号。current
:swiper
激活项,需要与 veplayer-swiper
的 current
保持一致。videoId
:为播放器内原生 video
组件的 ID,也对应小程序播放器 SDK 的 componentId
属性。videoId
作用是在切换视频时实现自动播放的效果,因此请确保在播放列表中,每一项的 videoId
是唯一的。此外,为了实现用户第一次进入播放页面时以及选集后自动播放视频,推荐将播放器的 autoplay
属性设置为 autoplay="{{index === current}}"
。
示例代码如下:
<veplayer-swiper current="{{current}}" class="swiper" bindchange="onChange" bindanimationfinish="onAnimationfinish" bindtransition="onTransition" > <block tt:for="{{list}}" tt:for-item="item" tt:for-index="index" > <veplayer-swiper-item videoId="{{item.vid}}" poster="{{item.poster}}" index="{{index}}" current="{{current}}" preloadSrc="{{item.src}}" > <view slot="video" style="width: 100%; height:100%; position: relative"> <veplayer src="{{item.src}}" poster="{{item.poster}}" autoplay="{{index === current}}" componentId="{{item.vid}}" playBtnPosition="bottom" enableProgressGesture="{{true}}" enablePlayGesture="{{true}}" bindended="onEnded" bindplay="onPlay" bindpause="onPause" ></veplayer> <!-- 业务功能点赞 --> <view style="right: 20px; top:50%; position: absolute; color: #fff">❤️</view> </view> </veplayer-swiper-item> </block> </veplayer-swiper>
在 player/index.js
文件中,您需要监听 veplayer-swiper
的 change
事件,更新 current
的值。示例代码如下:
const videoList = [ { vid: 'v0ddfag10001c*****k63casl9ed0', poster: 'https://demo.video.com/poster.jpg', src: 'https://demo.video.com/video.mp4', des: '', }, // ... ]; Component({ data: { current: 0, list: VideoList }, onChange(e) { // 监听 veplayer-swiper 的 change 事件,更新 current 的值 this.setData({ current: e.detail.detail.current }); }, })
您可以监听 onEnded
事件。在该事件的回调函数中,设置 veplayer-swiper
和veplayer-swiper-item
这两个组件的 current
属性。这样一来,播放完当前集之后,小程序就会自动播放下一集。
示例代码如下:
<veplayer slot="video" src="{{item.src}}" poster="{{item.poster}}" autoplay="{{index === current}}" componentId="{{item.vid + item.src}}" playBtnPosition="bottom" enableProgressGesture="{{true}}" enablePlayGesture="{{true}}" bindended="onEnded" ></veplayer>
onEnded() { const { current, list } = this.data; if (current + 1 < list.length) { // 设置 swiper 的 current 属性 this.setData({ current: current + 1 }); } else { tt.showToast({ title: '看完了!', duration: 2000, }); } }
如果您希望实现在剧集列表中通过点击剧集按钮来使播放器跳转至特定剧集,可设置veplayer-swiper
的 current
属性。
示例代码如下:
onSelectChange(e) { this.setData({ // 设置指定剧集的序号跳转到指定剧集 current: target }); }
播放器 SDK 封装了抖音原生 video
视频组件,支持配置大部分的 video
属性。原生 video
视频组件支持的属性详见抖音官方文档。
下表展示播放器 SDK 的新增属性及差异化属性。
说明
show-
开头的开关,既影响原生 video
视频组件,又影响自定义 UI。video
视频组件。video
视频组件的属性,如 show-play-btn
这类中划线分割的属性名,需要改写成驼峰式命名 showPlayBtn
。属性 | 类型 | 默认值 | 是否必选 | 说明 |
---|---|---|---|---|
mode | 'portrait' | 'landscape' |
| 否 | UI 模式。支持 2 种播放 UI 模式。取值如下:
|
disableLogVerify | Boolean |
| 否 | 关闭日志配置验证。取值如下:
|
componentId | String | - | 否 | video 组件 ID。
|
logInfo | Object | - | 否 | 日志上报时用到的视频信息 |
src | String | - | 否 | 播放视频的资源地址。支持网络路径、本地临时路径、云文件 ID等。 |
controls | 'custom' | 'native' |'false'| 'focus' | 'hidden' | 'blur' | 'focus' | 'immerse' |
| 否 | 播控 UI 的模式。取值如下:
说明
|
playBtnPosition | 'center' | 'bottom' | 'center-bottom' | bottom | 否 | 播放按钮的位置。取值如下:
|
duration | Number | - | 否 | 指定视频时长。 说明 不会控制实际播放的时长。因此该属性不设置给原生 |
showFullscreenBtn | Boolean |
| 否 | 是否展示全屏播放按钮。取值如下:
|
needLoading | Boolean |
| 否 | 是否显示 loading 加载标识。 说明
|
isShowDataLoading | Boolean |
| 否 | 是否展示数据加载标识,即获取地址时展示 loading。取值如下:
|
loadingText | String | - | 否 | 设置数据加载标识的文字描述。 |
veDebugger | Boolean |
| 否 | 用于开启内置日志打印。取值如下:
|
allowNullSource | Boolean |
| 否 | 是否允许空资源起播。取值如下:
说明
|
timeUpdateInterval | Number | 400 | 否 | 进度条更新的频率,单位为 ms。用于减少频繁的渲染造成内存升高的问题。 |
autoBlurTime | Number | 15000 | 否 | 自动失焦,即播放器在处于激活态,用户无操作多长时间隐藏播控。 |
interactiveConfig |
|
| 否 | 响应式配置。取值如下:
|
enableTapActive | Boolean | true | 否 | 是否启用点击触发激活(进入 focus 态) 说明 当自定义 |
bindplay | eventhandle | - | 否 | 当开始/继续播放时触发 play 事件。 |
bindpause | eventhandle | - | 否 | 当暂停播放时触发 pause 事件。 |
bindended | eventhandle | - | 否 | 当播放到末尾时触发 ended 事件。 |
bindtimeupdate | eventhandle | - | 否 | 播放进度变化时触发
|
bindfullscreenchange | eventhandle | - | 否 | 视频进入和退出全屏时触发
|
bindwaiting | eventhandle | - | 否 | 视频出现缓冲时触发 waiting 事件。 |
binderror | eventhandle | - | 否 | 视频播放出错时触发 error 事件。 |
bindprogress | eventhandle | - | 否 | 加载进度变化时触发
|
bindloadedmetadata | eventhandle | - | 否 | 视频元数据加载完成时触发
|
bindplaybackratechange | eventhandle | - | 否 | 视频倍速改变完成时触发。返回改变后的倍速值。
|
bindenterbackground | eventhandle | - | 否 | 进入小窗播放时触发。 |
bindclosebackground | eventhandle | - | 否 | 关闭小窗播放时触发。 |
bindleavebackground | eventhandle | - | 否 | 离开小窗进入 app 事件时触发 |
bindseekcomplete | eventhandle | - | 否 | seek 完成时触发 说明
|
binduseraction | eventhandle | - | 否 | 用户行为触发。例如,用户点击暂停、滑动进度条。 |
播放器 SDK 封装了 VideoContext,提供同原生接口一致的 API。代码示例如下所示。
let player = null // 异步获取组件内 video 的 VideoContext const component = this.selectComponent("#videoContainer", (component) => { player = component.getContext() // 原生接口 player.play() player.pause() player.stop() player.seek(10) player.requestFullScreen() player.exitFullScreen() player.setWaterMark({ color: "#FFFF11" }) player.setMediaVolume({ value: 1}) player.getMediaVolume(options) player.playbackRate(1) player.requestFullScreen({ direction: 90 }) player.exitFullScreen() }); // 同步获取组件内 video 的 VideoContext,需要保证是在 page 或者 component 的 ready 事件之后才能正常调用 // player = this.selectComponent("#videoContainer").getContext(); // player.play() // ...
播放器 SDK 提供两种方式进行事件监听:
bind
属性对组件进行事件监听。我们建议您在使用时,选择其中一种方式进行事件订阅,而不是同时使用两种方式。这两种方式都已在组件实例中实现了组件从页面节点树移除(lifetimes->detached)时的事件解绑,因此,您无需单独处理事件泄漏的问题。
bind
属性对组件进行事件监听请参见组件属性中 bind
开头的事件属性。
播放器 SDK 提供接口用于获取 player context。您可为 player
添加事件订阅,从而实现任意时刻对各种播放事件添加和移除监听。代码示例如下:
let player = null const component = this.selectComponent("#videoContainer", (component) => { player = component.getContext() // 事件订阅 player.on('error', (e) => { console.log('event error:', e) }) player.on('timeupdate', (e) => { const { currentTime, duration } = e.detail; console.log('event error:', currentTime, duration) }) ... });
详细的事件列表如下所示。
事件名称 | 是否可自定义事件 | 说明 |
---|---|---|
play | 否 | 当开始/继续播放时触发 play 事件。 |
pause | 否 | 当暂停播放时触发 pause 事件。 |
ended | 否 | 当播放到末尾时触发 ended 事件。 |
timeupdate | 否 | 播放进度变化时触发timeupdate 事件。 |
fullscreenchange | 否 | 视频进入和退出全屏时触发 fullscreenchange 事件。 |
waiting | 否 | 视频出现缓冲时触发 waiting 事件。 |
error | 否 | 视频播放出错时触发 error 事件。 |
progress | 否 | 加载进度变化时触发 progress 事件,只支持一段加载。 |
loadedmetadata | 否 | 视频元数据加载完成时触发 loadedmetadata 事件。 |
playbackratechange | 否 | 视频倍速改变完成时触发。返回改变后的倍速值。 |
enterbackground | 否 | 进入小窗播放时触发。 |
closebackground | 否 | 关闭小窗播放时触发。 |
leavebackground | 否 | 离开小窗进入 app 事件时触发。 |
seekcomplete | 否 | Seek 完成时触发 seekcomplete 事件。 |
controlstoggle | 否 | 切换 controls 显示隐藏时触发 controlstoggle 事件。 |
useraction | 是 | 用户行为触发,如用户点击暂停、滑动进度条。 |
veplayer-swiper
组件属性属性名 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
current | Number | 0 | 是 | 当前选中视频所在滑块的索引。 |
duration | Number | 500 | 否 | 滑动动画时长,单位为 ms。 |
easingFunction | String |
| 否 | Swiper 切换缓动动画类型,有效值:
|
vertical | Boolean |
| 否 | 竖直方向。取值如下:
|
showLoadingWhenChange | Boolean |
| 否 | 切换选集时是否展示 Loading。取值如下:
|
loadingText | String | "" | 否 | 切换选集的 Loading 文案。 |
indicatorDots | Boolean |
| 否 | 是否显示面板指示点。取值如下:
说明 播放场景中建议不传入此参数。 |
indicatorColor | Color | rgba(0, 0, 0, .3) | 否 | 指示点颜色。 说明 播放场景中建议不传入此参数。 |
indicatorActiveColor | Color | rgba(0, 0, 0, 0) | 否 | 当前选中的指示点颜色。 说明 播放场景中建议不传入此参数。 |
autoplay | Boolean |
| 否 | 是否自动切换。取值如下:
说明 播放场景中建议不传入此参数。 |
currentItemId | String | "" | 否 | 当前选中滑块的组件 ID。 说明
|
interval | Number |
| 否 | 自动切换时间间隔,单位为 ms。 说明 播放场景中建议不传入此参数。 |
previousMargin | String | "" | 否 | 前边距,可以用露出前一项的一小部分,支持 px 和 rpx,默认单位为 px。 说明 播放场景中建议不传入此参数。 |
nextMargin | String | "" | 否 | 后边距,可用于露出后一项的一小部分,支持 px 和 rpx,默认单位为 px。 说明 播放场景中建议不传入此参数。 |
displayMultipleItems | Number |
| 否 | 同时显示的滑块数量。 说明 播放场景中建议不传入此参数。 |
circular | Boolean |
| 否 | 是否循环播放(首尾衔接) 说明 播放场景中建议不传入此参数。 |
bindchange | EventHandle | - | 否 | current 改变时触发。 |
bindanimationfinish | EventHandle | - | 否 | 动画结束时会触发 animationfinish 事件。 |
bindtransition | EventHandle | - | 否 | wiper-item 产生位移时触发 transition 事件。 |
说明
在播放场景(例如微短剧场景)中,建议不要传入 indicatorDots
、indicatorColor
、indicatorActiveColor
、autoplay
、currentItemId
、interval
、previousMargin
、nextMargin
、displayMultipleItems
和 circular
属性,使用滑动切换组件的默认值即可。
veplayer-swiper-item
组件属性属性名 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
videoId | String | - | 是 | 视频 ID,对应播放器 SDK 的 |
index | Number | 0 | 是 | 当前 veplayer-swiper-item 所在列表的序号。 |
current | Number | 0 | 是 | 当前 veplayer-swiper 显示项的序号。 |
itemId | String | - | 否 | 该 veplayer-swiper-item 的标识符。 |
poster | String | - | 否 | 用于不渲染播放器时兜底的封面图。 |
preloadSrc | String | - | 否 | 视频预加载路径。值同该 说明
|
preloadNum | Number |
| 否 | 多实例预加载的数目,即最多同时加载的播放器数目。 说明 (推荐)保持默认值不做修改。 |
veplayer-swiper-item
组件插槽veplayer-swiper-item
组件提供了两个具名插槽 slot:
video
插槽:此插槽用于放置播放器。对于播放器类型没有限制,但请确保播放器的原生 video
属性必须绑定一个唯一 ID。这个 ID 需要传递给 veplayer-swiper-item
的 videoId
属性,用于控制视频的播放与暂停。
placeholder
插槽:此插槽用于播放器未渲染时的占位。如果你没有设置此插槽,那么默认会使用封面图片地址 poster
作为占位图。