veplayer-mp-wechat
v1.2.10
Published
> 小程序播放器微信原生版本
Downloads
22
Keywords
Readme
Veplayer小程序播放器
小程序播放器微信原生版本
前提条件
在小程序后台 > 开发 > 开发设置 > 服务器域名中添加以下域名配置:
- 日志上报域名:https://mcs.zijieapi.com
- 播放请求域名(Vid 方式播放时需要):https://vod.volcengineapi.com
操作截图如下所示。
视频资源的 CDN 域名不需要添加到域名配置中。
安装
# npm
npm i veplayer-mp-wechat
npm i veplayer-mp-logger
# yarn
yarn add veplayer-mp-wechat
yarn add veplayer-mp-logger
构建 npm 包
请优先了解微信小程序官网对于 npm 支持 的介绍。 您需要点击微信开发者工具中的菜单栏,工具 > 构建 npm。
引入组件
详情请参考微信官方文档小程序自定义组件的引入方式。引入微信小程序点播 SDK 的代码示例如下:
{
"usingComponents": {
"veplayer": "veplayer-mp-wechat"
}
}
使用组件
使用播放器组件
按照播放方式的不同,分为 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 本地方法生成,具体生成参考火山引擎视频点播文档。
对应业务组件中添加日志上报需要的视频信息配置,代码示例如下:
// index.js
Component({
data: {
src: 'https://xxxx.mp4',
...,
logInfo: {
vtype: 'MP4', // [可选]播放类型, 默认为 'MP4','HLS' || 'MP4'
codecType: 'h264', // [可选]视频编码类型,默认 h264,'h264' || 'h265'
sourceType: 'url', // [可选]播放资源类型,默认 'vid','vid' || 'url'
bitrate: 1334556, // [可选]视频码率,默认为 0
vid: '1', // [可选]sourceType 为 vid 的时候视频 vid
tag: 'myTag', // [可选]播放场景
subtag: 'subtag', // [可选]二级播放场景
logger: true, // [可选] 是否开启 log 打印,默认 false, 开发环境可设置为 true
}
}
})
配置日志采集上报
在组件的属性中传入logInfo,logInfo中需要传入appId,即可开启播放日志的采集上报,除了appId,可以根据业务的需要填入以下所列配置。
| 属性名 | 类型 | 是否必选 | 默认值 | 说明 | |---------------|-----------|------|--------------------------|-------------------------------------------------------------------------------------------------------------------------| | appId | number | 是 | - | 应用ID, 可在火山引擎视频点播控制台上获取应用 AppID | | userId | string | 否 | - | 用户 ID,强烈建议您使用与业务相关的用户 ID。如不传入,SDK 将随机生成一个值。强烈建议您使用与业务密切相关的用户 ID,以便在播放过程中出现错误时,可以进行单点故障排查,精确定位问题。如果您没有设定用户 ID,组件将随机生成一个。 | | tag | string | 否 | - | 业务标签或业务类型,用于标记不同的播放场景,如推荐页、详情页 | | subtag | string | 否 | - | 子业务标签或业务类型,用于细分播放场景 | | vtype | HLS 或 MP4 | 否 | MP4 | 视频格式 | | codecType | string | 否 | h264 | 视频编码格式 | | bitrate | number | 否 | 0 | 视频码率 | | logger | boolean | 否 | false | 是否开启日志打印 | | appName | string | 否 | 视频云小程序 | 应用名称 | | appVersion | string | 否 | 1.0.0 | 应用版本 | | channelDomain | string | 否 | https://mcs.zijieapi.com | 日志上报域名 |
示例代码如下:
<view>
<!-- 以下是对小程序播放器 SDK 的引用 -->
<veplayer
id="videoContainer"
src="{{src}}"
loop
logInfo="{{logInfo}}"
/>
</view>
// index.js
Component({
data: {
src: 'https://xxxx.mp4',
logInfo: {
appId: xxx,
tag: 'recommend',
subtag: 'hot',
}
}
})
查看日志上报数据
视频信息配置完成后,可登录视频点播控制台,选择左侧导航栏质量平台 > 播放看板,进入播放看板页面,选择大盘速览页签,在查询条件中选择在小程序点播 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'| 'focus' | 'hidden' | 'blur' | 'focus' | immerse | 'custom' | 否 | custom: 自定义UI; native: 原生组件UI;false: 完全关闭播放UI控件(包括自定义UI及原生组件UI); focus: 高亮状态; hidden: 隐藏状态(禁交互); blur: 失去焦点状态; immerse:半沉浸状态(即半透明状态), 播放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之后的版本生效 |
| timeUpdateInterval | number | 400 | 否 | 进度条更新的频率, 用于减少频繁的渲染造成内存升高的问题,单位ms |
| autoBlurTime | number | 15000 | 否 | 自动失焦,即播放器在处于激活态用户无操作多长时间隐藏播控 |
| interactiveConfig | object | { immersive: false, delay: 10000, focusDelay: 0 } | 否 | 响应式配置: immersive: 是否启用半沉浸式 delay:进入半沉浸状态/隐藏状态的延迟时间,单位ms focusDelay: 隐藏态进入focus态是否自动切换,单位ms |
| activeState | string | default | 否 | 当前实例是否是激活状态: active:激活状态 standby:备用状态 default:默认状态,即不区分是否激活 |
| enableTapActive | boolean | true | 否 | 自定义controls时,即controls不是native时,是否启用点击触发激活(进入focus态) |
| binduseraction | eventhandle | | 否 | 用户行为触发,如用户点击暂停、滑动进度条 |
| 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
npm i veplayer-mp-wechat
npm i veplayer-mp-logger
# yarn
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. 配置组件引入
在 pages.json
对应页面的 style -> usingComponents 引入组件: 可通过uni-app提供的条件编译的方式在不同平台上编译使用不同的SDK,抖音小程序播放器SDK对应veplayer-mp-douyin
如果是在 vue 组件中使用小程序组件时,注意需要在
pages.json
的globalStyle
中配置usingComponents
,而不是页面级配置。
{
"pages": [
{
"path": "pages/index/index",
"style": {
// #ifdef MP-WEIXIN
"usingComponents": {
"veplayer": "/wxcomponents/veplayer-mp-wechat/dist/index"
},
// #endif
// #ifdef MP-TOUTIAO
"usingComponents": {
"veplayer": "/ttcomponents/veplayer-mp-douyin/dist/index"
},
// #endif
"navigationBarTitleText": "uni-app"
}
}
]
}
4. 组件使用
以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>
5. 配置日志采集上报
在组件的属性中传入logInfo,logInfo中需要传入appId,即可开启播放日志的采集上报,除了appId,可以根据业务的需要填入以下所列配置。
| 属性名 | 类型 | 是否必选 | 默认值 | 说明 | |---------------|-----------|------|--------------------------|-------------------------------------------------------------------------------------------------------------------------| | appId | number | 是 | - | 应用ID, 可在火山引擎视频点播控制台上获取应用 AppID | | userId | string | 否 | - | 用户 ID,强烈建议您使用与业务相关的用户 ID。如不传入,SDK 将随机生成一个值。强烈建议您使用与业务密切相关的用户 ID,以便在播放过程中出现错误时,可以进行单点故障排查,精确定位问题。如果您没有设定用户 ID,组件将随机生成一个。 | | tag | string | 否 | - | 业务标签或业务类型,用于标记不同的播放场景,如推荐页、详情页 | | subtag | string | 否 | - | 子业务标签或业务类型,用于细分播放场景 | | vtype | HLS 或 MP4 | 否 | MP4 | 视频格式 | | codecType | string | 否 | h264 | 视频编码格式 | | bitrate | number | 否 | 0 | 视频码率 | | logger | boolean | 否 | false | 是否开启日志打印 | | appName | string | 否 | 视频云小程序 | 应用名称 | | appVersion | string | 否 | 1.0.0 | 应用版本 | | channelDomain | string | 否 | https://mcs.zijieapi.com | 日志上报域名 |
示例代码如下:
<!-- 页面模板 (index.vue) -->
<template>
<view>
<veplayer
id="videoContainer"
:src="src"
loop
:logInfo="logInfo"
/>
</view>
</template>
<script>
export default {
data() {
return {
src: 'https://xx.cdn.com/demo.mp4',
logInfo: {
appId: xxx,
tag: 'recommend',
subtag: 'hot',
}
}
},
}
</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
npm i veplayer-mp-wechat
npm i veplayer-mp-logger
# yarn
yarn add veplayer-mp-wechat
yarn add veplayer-mp-logger
2. 拷贝组件到项目目录
拷贝node_modules/veplayer-mp-wechat
到项目小程序组件存放目录wxcomponents
(0.1.14之后的版本会自动拷贝)。
3. 配置组件引入
在使用到播放器组件所在页面的index.config.ts
配置中引入组件:
export default definePageConfig({
navigationBarTitleText: '',
navigationBarTextStyle: 'black',
navigationStyle: 'custom',
disableScroll: true,
usingComponents: {
veplayer: '../../wxcomponents/veplayer-mp-wechat/dist/index',
},
});
注意保证组件路径配置正确
4. 组件使用
以react语法示例在自定义组件中使用播放器组件:
const VideoPlayer = ({
videoComponentId,
className,
videoPlayUrl,
coverUrl,
controlShow,
onTimeUpdate,
onError,
}) => {
const handleTimeupdate = (e) => {
// 注意原生组件事件的event在taro项目中被劫持包装到了e.mpEvent.detail.e中
const originEvent = e.mpEvent.detail.e;
const { currentTime, duration } = originEvent.detail;
// TODO something
// ...
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}
/>
);
};
5. 配置日志采集上报
在组件的属性中传入logInfo,logInfo中需要传入appId,即可开启播放日志的采集上报,除了appId,可以根据业务的需要填入以下所列配置。
| 属性名 | 类型 | 是否必选 | 默认值 | 说明 | |---------------|-----------|------|--------------------------|-------------------------------------------------------------------------------------------------------------------------| | appId | number | 是 | - | 应用ID, 可在火山引擎视频点播控制台上获取应用 AppID | | userId | string | 否 | - | 用户 ID,强烈建议您使用与业务相关的用户 ID。如不传入,SDK 将随机生成一个值。强烈建议您使用与业务密切相关的用户 ID,以便在播放过程中出现错误时,可以进行单点故障排查,精确定位问题。如果您没有设定用户 ID,组件将随机生成一个。 | | tag | string | 否 | - | 业务标签或业务类型,用于标记不同的播放场景,如推荐页、详情页 | | subtag | string | 否 | - | 子业务标签或业务类型,用于细分播放场景 | | vtype | HLS 或 MP4 | 否 | MP4 | 视频格式 | | codecType | string | 否 | h264 | 视频编码格式 | | bitrate | number | 否 | 0 | 视频码率 | | logger | boolean | 否 | false | 是否开启日志打印 | | appName | string | 否 | 视频云小程序 | 应用名称 | | appVersion | string | 否 | 1.0.0 | 应用版本 | | channelDomain | string | 否 | https://mcs.zijieapi.com | 日志上报域名 |
示例代码如下:
const VideoPlayer = ({
videoComponentId,
className,
videoPlayUrl,
coverUrl,
controlShow,
onTimeUpdate,
onError,
}) => {
const handleTimeupdate = (e) => {
// 注意原生组件事件的event在taro项目中被劫持包装到了e.mpEvent.detail.e中
const originEvent = e.mpEvent.detail.e;
const { currentTime, duration } = originEvent.detail;
// TODO something
// ...
onTimeUpdate(currentTime);
};
const handleVideoTap = () => {
// 点击视频
};
const logInfo = {
appId: xxx,
tag: 'recommend',
subtag: 'hot',
}
return (
<veplayer
id={videoComponentId}
// 引用原生组件需要使用 class 传参
class={className}
src={videoPlayUrl}
logInfo={logInfo}
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) => {
// 注意原生组件事件的event在taro项目中被劫持包装到了e.mpEvent.detail.e中
const originEvent = e.mpEvent.detail.e;
const { currentTime, duration } = originEvent.detail;
// TODO something
// ...
};