Veplayer小程序播放器
小程序播放器微信原生版本
前提条件
在小程序后台 > 开发 > 开发设置 > 服务器域名中添加以下域名配置:
操作截图如下所示。
视频资源的 CDN 域名不需要添加到域名配置中。
安装
npm i veplayer-mp-wechat
npm i veplayer-mp-logger
yarn add veplayer-mp-wechat
yarn add veplayer-mp-logger
构建 npm 包
请优先了解微信小程序官网对于 npm 支持 的介绍。
您需要点击微信开发者工具中的菜单栏,工具 > 构建 npm。
引入组件
详情请参考微信官方文档小程序自定义组件的引入方式。引入微信小程序点播 SDK 的代码示例如下:
{
"usingComponents": {
"veplayer": "veplayer-mp-wechat"
}
}
使用组件
配置播放器日志
- 您需要在火山引擎视频点播控制台,新建应用,获取应用的唯一 AppID。
- 引入日志组件,在页面加载前设置数据采集 SDK 的构造器。setCollector 方法的第二项参数中的 userId 是用来统计用户相关的播放数据。推荐使用应用关联的用户 ID,方便后续发生错误时进行单点排查。代码示例如下所示:
import { CollectorManager } from 'veplayer-mp-wechat/tool/index';
import Collector from 'veplayer-mp-logger';
CollectorManager.setCollector(Collector, {
appId: 11***1,
userId: '7231102***76007992'
});
如果在不使用播放器 SDK 的情况下,也能够进行播放日志上报,具体操作请参考 veplayer-mp-logger。
使用播放器组件
按照播放方式的不同,分为 DirectUrl 方式播放和 Vid 方式播放。
DirectUrl 方式播放
<view>
<!-- 以下是对小程序播放器组件的引用 -->
<veplayer
id="videoContainer"
showPlayBtn
autoplay
src="http://xxxx.mp4"
logInfo="logInfo"
bindplay="onPlay"
/>
</view>
Vid 方式播放
<view>
<!-- 以下是对一个播放器组件的引用 -->
<veplayer
id="videoContainer"
showPlayBtn
autoplay
playDomain='https://vod.volcengineapi.com'
playAuthToken='*****************'
logInfo="logInfo"
bindplay="onPlay"
/>
</view>
- playDomain 是调用火山引擎视频点播 OpenAPI 的播放域名,您如果做了该接口的代理,可以替换成您自己的播放域名。使用正式 AppID 调试时需要将该地址配置在小程序服务器域名配置白名单中。
- playAuthToken 是获取视频播放信息的临时凭证,由业务方服务端通过调用火山服务端 SDK 基于视频 Vid 本地方法生成,具体生成参考火山引擎视频点播文档。
对应业务组件中添加日志上报需要的视频信息配置,代码示例如下:
Component({
data: {
src: 'https://xxxx.mp4',
...,
logInfo: {
vtype: 'MP4',
codecType: 'h264',
sourceType: 'url',
bitrate: 1334556,
vid: '1',
tag: 'myTag',
subtag: 'subtag',
logger: true,
}
}
})
查看日志上报数据
视频信息配置完成后,可登录视频点播控制台,选择左侧导航栏质量平台 > 播放看板,进入播放看板页面,选择大盘速览页签,在查询条件中选择在小程序点播 SDK 中配置的各项指标。详细操作说明请见查看大盘速览。
组件属性
小程序播放器封装了 video 原生组件,支持配置大部分的 video 属性。原生组件支持的属性配置详情请参考微信官方文档。以下列表展示了新增属性及差异化属性。
- 列表中的部分属性以 show- 开头的开关,既影响原生组件,又影响自定义 UI。
- 不在列表中的只影响原生组件。
原生微信 video 组件的属性,如:show-play-btn 这类中划线分割的属性名,需要改写成驼峰式命名showPlayBtn。
属性 | 类型 | 默认值 | 是否必选 | 说明 |
---|
mode | 'portrait' | 'landscape' | landscape | 否 | UI 模式。支持 2 种播放 UI 模式。取值如下:landscape:(默认值)横屏。展示类似抖音等短视频播放 UI 模式。 portrait:竖屏。展示偏向于普通的 PC 视频播放器 UI 模式。 |
componentId | String | | 否 | video 组件 ID。通过createVideoContext获取视频 VideoContext。如果不传,随机生成一个 ID,需要通过组件上下文的getContext()方法才能获取视频 VideoContext。 |
src | String | | 是 | 播放视频的资源地址。支持网络路径、本地临时路径、云文件 ID等。 |
controls | 'custom' | 'native'|'false' | custom | 否 | custom: 自定义 UI。native: 原生组件 UI。false: 完全关闭播放 UI 控件(包括自定义 UI 及原生组件UI)。播放 UI 控件指 loading 状态、播控按钮、进度条、时间显示等。 |
playAuthToken | string | | vid方式播放必传 | 获取视频播放信息的临时凭证,由业务方服务端通过调用火山服务端SDK基于视频vid本地服务生成,具体生成参考火山引擎视频点播文档 |
playDomain | string | https://vod.volcengineapi.com | 否 | 调用火山引擎视频点播 OpenAPI 的播放域名,您如果做了该接口的代理,可以替换成您自己的播放域名。使用正式 AppID 调试时需要将该地址配置在小程序服务器域名配置白名单中| |
duration | number | | 否 | 指定视频时长。不会控制实际播放的时长。因此该属性不设置给原始 video 组件,只提供给自定义 UI 使用。 |
showCenterPlayBtn | boolean | true | 否 | 是否显示视频正中心的播放按钮。 |
showBottomProgress | boolean | true | 否 | 是否展示底部进度条。 |
needLoading | boolean | true | 否 | 是否显示loading,扩展属性,controls=custom的时候生效,v0.1.12之后的版本生效 |
bindplay | eventhandle | | 否 | 当开始/继续播放时触发 play 事件。 |
bindpause | eventhandle | | 否 | 当暂停播放时触发 pause 事件。 |
bindended | eventhandle | | 否 | 当播放到末尾时触发 ended 事件。 |
bindtimeupdate | eventhandle | | 否 | 播放进度变化时触发 timeupdate 事件。event.detail = {currentTime, duration} 触发频率 250ms 一次。 |
bindfullscreenchange | eventhandle | | 否 | 视频进入和退出全屏时触发 fullscreenchange 事件。event.detail = {fullScreen, direction} direction 有效值为 vertical 或 horizontal |
bindwaiting | eventhandle | | 否 | 视频出现缓冲时触发 waiting 事件。 |
binderror | eventhandle | | 否 | 视频播放出错时触发 error事件。 |
bindprogress | eventhandle | | 否 | 加载进度变化时触发 progress 事件,只支持一段加载。event.detail = { buffered } ,单位百分比 |
bindloadedmetadata | eventhandle | | 否 | 视频元数据加载完成时触发 loadedmetadata 事件。event.detail = {width, height, duration} |
bindcontrolstoggle | eventhandle | | 否 | 切换 controls 显示隐藏时触发 controlstoggle 事件。event.detail = {show} |
bindenterpictureinpicture | eventhandle | | 否 | 播放器进入小窗 enterpictureinpicture 事件。 |
bindleavepictureinpicture | eventhandle | | 否 | 播放器退出小窗 leavepictureinpicture 事件。 |
bindseekcomplete | eventhandle | | 否 | seek 完成时触发 seekcomplete 事件。position 的单位在不同系统上有所区别: iOS单位为 s,Android,单位为 ms。 |
组件接口
小程序播放器封装了 VideoContext,提供同原生接口一致的 API。代码示例如下所示。
const component = this.selectComponent("#videoContainer");
const player = component.getContext()
player.play()
player.pause()
player.stop()
player.seek(10)
player.sendDanmu(Object data)
player.playbackRate(1)
player.requestFullScreen({ direction: 90 })
player.exitFullScreen()
player.exitPictureInPicture()
player.requestBackgroundPlayback()
player.exitBackgroundPlayback()
组件事件
微信小程序播放器对外支持 2 种方式的事件监听形式:
- 组件属性 bind 方式事件监听
- 组件对象提供事件订阅的机制进行事件监听
请选择其中一种进行订阅,尽量不要两者混用。这两种方式在组件实例中,被从页面节点树移除(lifetimes -> detached)时,进行事件解绑,您无需单独关注事件泄漏的问题。
组件属性 bind 方式事件监听
请参见组件属性中 bind 开头的事件属性。
组件对象提供事件订阅的机制进行事件监听
小程序播放器提供了接口可以获取 player context,并可以对 player 添加事件订阅,从而实现任意时刻对各种播放事件添加/移除监听的功能。代码示例如下所示。
const component = this.selectComponent("#videoContainer");
const player = component.getContext();
player.on('error', (e) => {
console.log('event error:', e)
});
player.on('timeupdate', (e) => {
const { currentTime, duration } = e.detail;
console.log('event timeupdate:', currentTime, duration)
});
详细的事件列表如下所示。
事件名称 | 是否可自定义事件 | 说明 |
---|
play | 否 | 当开始/继续播放时触发 play 事件。 |
pause | 否 | 当暂停播放时触发 pause 事件。 |
ended | 否 | 当播放到末尾时触发 ended 事件。 |
timeupdate | 否 | 播放进度变化时触发。 |
fullscreenchange | 否 | 视频进入和退出全屏时触发 fullscreenchange 事件。 |
waiting | 否 | 视频出现缓冲时触发 waiting 事件。 |
error | 否 | 视频播放出错时触发 error 事件。 |
progress | 否 | 加载进度变化时触发 progress 事件,只支持一段加载。 |
loadedmetadata | 否 | 视频元数据加载完成时触发 loadedmetadata 事件。 |
controlstoggle | 否 | 切换 controls 显示隐藏时触发 controlstoggle 事件。 |
enterpictureinpicture | 否 | 播放器进入小窗 enterpictureinpicture 事件。 |
leavepictureinpicture | 否 | 播放器退出小窗 leavepictureinpicture 事件。 |
seekcomplete | 否 | seek 完成时触发 seekcomplete 事件。 |
uni-app 项目使用
此播放器组件提供的是原生小程序版本,uni-app项目支持使用小程序自定义组件,可以按照以下步骤在uni-app项目中使用此播放器组件:
1. 在项目中安装依赖
npm i veplayer-mp-wechat
npm i veplayer-mp-logger
yarn add veplayer-mp-wechat
yarn add veplayer-mp-logger
HBuilderX创建的项目默认没有package.json
文件,需要通过初始化命令来创建。
npm init -y
2. 拷贝组件到项目目录
拷贝node_modules/veplayer-mp-wechat
到项目小程序组件存放目录wxcomponents
(0.1.14之后的版本会自动拷贝)。HBuilderX 建立的工程 ttcomponents
文件夹在 项目根目录下。vue-cli 建立的工程 ttcomponents
文件夹在 src
目录下。
3. 配置播放器日志
在页面/组件实例化之前,配置播放器日志的相关配置。
import { CollectorManager } from '@/wxcomponents/veplayer-mp-wechat/dist/tool';
import Collector from 'veplayer-mp-logger';
CollectorManager.setCollector(Collector, {
appId: 11***1,
userId: '7231102***76007992'
});
4. 配置组件引入
在 pages.json
对应页面的 style -> usingComponents 引入组件: 可通过uni-app提供的条件编译的方式在不同平台上编译使用不同的SDK,抖音小程序播放器SDK对应veplayer-mp-douyin
如果是在 vue 组件中使用小程序组件时,注意需要在 pages.json
的 globalStyle
中配置 usingComponents
,而不是页面级配置。
{
"pages": [
{
"path": "pages/index/index",
"style": {
"usingComponents": {
"veplayer": "/wxcomponents/veplayer-mp-wechat/dist/index"
},
"usingComponents": {
"veplayer": "/ttcomponents/veplayer-mp-douyin/dist/index"
},
"navigationBarTitleText": "uni-app"
}
}
]
}
5. 组件使用
以vue模板语法示例:
<!-- 页面模板 (index.vue) -->
<template>
<view>
<!-- 在页面中对自定义组件进行引用 -->
<veplayer
id="video"
:src="src"
controls="custom"
@play="onPlay"
@timeupdate="onTimeupdate"
/>
</view>
</template>
<script>
export default {
data() {
return {
src: 'https://xx.cdn.com/demo.mp4'
}
},
methods: {
onPlay(e) {
// TODO something
console.log('play event: ', e);
},
onTimeupdate(e) {
// TODO something
console.log('timeupdate event', e);
},
},
}
</script>
API使用,以暂停为例:
const component = this.selectComponent('#video');
const player = component.getContext();
if (player) {
player.pause();
}
订阅事件:
除了通过@事件名
方式进行监听外,还可以通过组件的videoContext
以事件订阅的方式动态监听。
const component = this.selectComponent('#video');
const player = component.getContext();
if (player) {
player.on('timeupdate', (data) => {
const { currentTime, duration } = data.e.detail;
console.log('event timeupdate:', currentTime, duration)
});
}
- 如果是从uni-app的video组件迁移到本组件,不作API使用的更改,则组件属性里通过
componentId
传入uni.createVideoContext
需要的组件id,API调用同uni-app组件说明。 - 需要注意的是通过
createVideoContext
获取的播放器上下文无法使用事件订阅。
注意数据和事件绑定的差异,组件使用时应按照 vue 的方式进行数据和事件绑定:
- 属性绑定从 attr="",改为 :attr="a";从 src="http://xx.demo.com/1.mp4" 改为 :src="'http://xx.demo.com/' + vid + '.mp4"
- 事件绑定从 bind:play="onPlay" 改为 @play="onPlay"
- 阻止事件冒泡 从 catch:tap="xx" 改为 @tap.native.stop="xx"
- wx:if 改为 v-if
- wx:for="" wx:key="" 改为v-for="(item,index) in list"
详细的小程序转uni-app语法差异可参考文档https://ask.dcloud.net.cn/article/35786。
Taro 项目使用
Taro 项目支持使用原生小程序组件,可以按照以下步骤在Taro项目中使用此播放器组件。
1. 在项目中安装依赖
npm i veplayer-mp-wechat
npm i veplayer-mp-logger
yarn add veplayer-mp-wechat
yarn add veplayer-mp-logger
2. 拷贝组件到项目目录
拷贝node_modules/veplayer-mp-wechat
到项目小程序组件存放目录wxcomponents
(0.1.14之后的版本会自动拷贝)。
3. 配置播放器日志
在页面/组件实例化之前,配置播放器日志的相关配置。
import { CollectorManager } from '@/wxcomponents/veplayer-mp-wechat/dist/tool';
import Collector from 'veplayer-mp-logger';
CollectorManager.setCollector(Collector, {
appId: 11***1,
userId: '7231102***76007992'
});
4. 配置组件引入
在使用到播放器组件所在页面的index.config.ts
配置中引入组件:
export default definePageConfig({
navigationBarTitleText: '',
navigationBarTextStyle: 'black',
navigationStyle: 'custom',
disableScroll: true,
usingComponents: {
veplayer: '../../wxcomponents/veplayer-mp-wechat/dist/index',
},
});
注意保证组件路径配置正确
5. 组件使用
以react语法示例在自定义组件中使用播放器组件:
const VideoPlayer = ({
videoComponentId,
className,
videoPlayUrl,
coverUrl,
controlShow,
onTimeUpdate,
onError,
}) => {
const handleTimeupdate = (e) => {
const originEvent = e.mpEvent.detail.e;
const { currentTime, duration } = originEvent.detail;
onTimeUpdate(currentTime);
};
const handleVideoTap = () => {
};
return (
<veplayer
id={videoComponentId}
// 引用原生组件需要使用 class 传参
class={className}
src={videoPlayUrl}
showPlayBtn
showBottomProgress={false}
controls={controlShow}
// 原生组件需要使用小写 autoplay
autoplay
onPlay={onPlay}
onTimeupdate={handleTimeupdate}
poster={coverUrl}
onError={onError}
onTap={handleVideoTap}
/>
);
};
API使用,以暂停为例:
import Taro, { nextTick } from '@tarojs/taro';
const { page } = Taro.getCurrentInstance();
const videoContext = page?.selectComponent(`#${id}`)?.getContext();
videoContext.play();
订阅事件:
除了通过在jsx语法上添加on+首字母大写事件名
方式进行监听外,还可以通过组件的videoContext
以事件订阅的方式动态监听,以监听timeupdate
事件为例
import Taro from '@tarojs/taro';
const { page } = Taro.getCurrentInstance();
const videoContext = page?.selectComponent(`#${id}`)?.getContext();
if (player) {
player.on('timeupdate', (data) => {
const { currentTime, duration } = data.e.detail;
console.log('event timeupdate:', currentTime, duration)
});
}
需要注意的是通过jsx语法监听的原生事件event在taro项目中被劫持包装到了e.mpEvent.detail.e中,以监听timeupdate
事件为例,取数据时参考以下代码:
const handleTimeupdate = (e) => {
const originEvent = e.mpEvent.detail.e;
const { currentTime, duration } = originEvent.detail;
};