更新记录
1.8.2(2025-12-17)
下载此版本
- 1、修复设置initialTime在播放hls流无效的问题
- 2、修复插件在pc端点击无反应的问题
- 3、修复插件发布h5到线上后使用renderjs渲染类型报错getCurrentPage is not defined的问题
- 4、修复ios部分版本的系统向app通信无反应的问题
- 5、插件内js文件ES6+语法转换为ES5语法,兼容低版本webview,但js文件可读性变差了,如果需要修改源码的开发者,请下载示例项目,源代码放在libs中
1.8.1(2025-11-11)
下载此版本
- 修复切换src可能会报错的问题
- 优化自动判断解码器类型函数
- capture方法增加是否展示弹窗配置
- 优化视频内点击事件,取消可能会有的点击延迟
- 优化css样式
1.8.0(2025-10-29)
下载此版本
- 1、增加jsmpeg.js解码器
- 2、renderjs渲染模式下增加组件插槽
- 3、height属性增加inherit配置
查看更多
平台兼容性
uni-app
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
√ |
√ |
√ |
√ |
- |
- |
- |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
快应用-华为 |
快应用-联盟 |
| × |
× |
× |
× |
- |
- |
- |
× |
- |
× |
× |
使用须知
- 1、这个播放器支持APP-VUE、H5、APP-NVUE,兼容VUE3,不支持小程序。
- 2、对于需要兼容小程序的项目来说,不建议你使用本插件,因为该插件有大量静态文件,会导致小程序包增大,并且静态文件是无法按需引入的。
- 3、该插件主要利用h5的video标签播放视频,video原生只支持ogg、mp4、webm格式的视频。
- 4、插件内置hls.js解码器支持播放m3u8,内置flv.js(不支持IOS)支持播放http-flv,内置jsmepg.js支持播放ws://、wss//、MPEG-TS静态文件
- 5、插件不支持播放h.265编码的视频,也不支持播放rtsp://,rtmp://协议,如果你需要播放这些视频流,需要配合后端转码播放
- 6、支持弹幕功能、字幕功能、画质切换,360全景等。
- 7、APP-NVUE可能会有性能问题,如果播放太长的视频,播放一定时间可能会出现闪退的情况,猜想应该是nvue的webview未做视频播放优化的缘故。
- 8、IOS支持性可能不太好,因为我没有ios设备调试,如果有人愿意帮我调试,就看下面,加进来一起交流,关于该插件在IOS得表现需要单独说明,详情见下方,IOS特别说明。
- 9、有什么不懂可以加 1_0_8_7_7_3_5_9_4_2 去掉横杠即可。
ES6+转ES5
- 插件内的js文件已经转换成es5语法,但可读性很差,需要修改源码的话,需要下载示例项目,源代码放在根目录libs文件夹中
- 想要在修改源码后将源代码转换ES5语法,需要先在示例项目中安装依赖,然后使用命令行npm run build即可,如下所示:
- 安装依赖
npm install
- 使用命令行转换
npm run build
- 最后将示例项目内的uni_modules/yingbing-video插件替换到你的项目即可
props属性
| 属性名 |
类型 |
默认值 |
可选值 |
说明 |
| src |
String |
---- |
---- |
播放链接 |
| segments |
Array |
---- |
---- |
切片列表(详情见下方) |
| title |
String |
---- |
---- |
标题 |
| poster |
String |
---- |
---- |
封面 |
| type |
String |
auto |
auto-自动判断 video-使用video标签播放 hls-使用hls.js播放 flv-使用flv.js播放 jsmpeg-使用jsmpeg.js播放 |
解码类型 |
| three |
String |
none |
none-关闭3D 360-360全景 |
3D模式 |
| isLive |
Boolean |
false |
true/false |
是否是直播流 |
| autoplay |
Boolean |
false |
true/false |
自动播放(大部分浏览器都不支持,APP-NVUE下也不支持,想要自动播放最好设置默认静音) |
| preload |
String |
atuo |
auto-加载所有资源 meta-只加载元数据 none-不加载 |
预加载(autoplay设置为true时忽略此属性) |
| loop |
Boolean |
false |
true/false |
循环播放 |
| muted |
Boolean |
false |
true/false |
静音 |
| playbackRate |
Number |
1 |
---- |
播放倍速 |
| duration |
Number |
---- |
---- |
自定义播放时长 (单位是秒) |
| initialTime |
Number |
0 |
---- |
初始播放时长 (单位是秒) |
| height |
String |
auto |
auto-自适应视频高度 百分比(30%)-根据屏幕高度计算 像素(200px或400rpx)-像素高度 inherit-继承父组件高度 |
视频高度 |
| objectFit |
String |
---- |
fill-内容拉伸填充 contain-保持比例内容缩放 cover-保持比例内容可能被剪切 none-内容不重置 scale-down-保持比例从none或contain选一个 |
当视频大小与 video 容器大小不一致时,视频的表现形式。 |
| crossOrigin |
String |
---- |
anonymous-不传递凭据信息的情况下发送CORS请求(重要属性,360全景视频和截图不设置该属性可能会报错) use-credentials-将发送带有凭据、cookie 和证书的 cross-origin 请求 |
跨域属性 |
| header |
Boolean |
false |
true/false |
显示顶部控制栏 |
| controls |
Boolean |
false |
true/false |
显示底部控制栏 |
| openDirection |
String |
auto |
auto-自动计算 landscape-横屏 portrait-竖屏 |
开启全屏时设备方向 (只支持APP)(如果IOS出现屏幕旋转2次的问题,看下方IOS特别说明) |
| exitDirection |
String |
portrait |
landscape-横屏 portrait-竖屏 |
退出全屏时设备方向 (只支持APP) |
| danmu |
Object |
---- |
---- |
弹幕(详情见下方) |
| quality |
Array |
---- |
---- |
画质列表(详情见下方) |
| works |
Array |
---- |
---- |
分P列表(详情见下方) |
| workIndex |
Number |
-1 |
---- |
分P默认索引 |
| subtitles |
Array |
---- |
---- |
字幕列表(详情见下方) |
| subtitleIndex |
Number |
-1 |
---- |
字幕默认索引 |
| custom |
Object |
---- |
---- |
自定义配置(详情见下方) |
| hlsConfig |
Object |
---- |
---- |
hls配置(详情见下方) |
| flvConfig |
Object |
---- |
---- |
flv配置(详情见下方) |
| jsmpegConfig |
Object |
---- |
---- |
jsmpeg配置(详情见下方) |
| renderType |
String |
---- |
renderjs-使用renderjs渲染视频 web-使用网页方式渲染视频 |
渲染模式(ios平台默认renderjs,如果想使用web,必须将webview内核改为UIWebview)(APP-NVUE只能使用web方式渲染) |
event事件
| 事件名 |
参数 |
说明 |
| canplay |
--- |
可以播放状态,但不保证后面可以流畅播放,视频总长度,尺寸信息可以从这里取到 (该事件触发比较频繁,跳转进度也会触发(jsmpeg解码器播放该事件只会触发一次,并且此时获取到的视频尺寸信息可能是错误的),如果想在这个方法做一些操作,建议用loadedmetadata或loadeddata替代) |
| canplaythrough |
--- |
可以正常播放且无需停顿和缓冲时触发。,视频总长度,尺寸信息可以从这里取到 (该事件触发比较频繁,跳转进度也会触发(jsmpeg解码器播放该事件只会在全部视频数据加载完后触发一次),如果想在这个方法做一些操作,建议用loadedmetadata或loadeddata替代) |
| loadeddata |
---- |
加载视频当前帧时触发,视频总长度,尺寸信息可以从这里取到(由于jsmpeg解码器的差异性,视频总时长无法获取,jsmpeg主要是用于播放实时流的) |
| loadedmetadata |
---- |
元素据加载完毕,视频总长度,尺寸信息可以从这里取到(由于解码器的不同,获取视频信息可能也会有差异,比如jsmpeg.js在loadedmetadata触发时获取到的视频尺寸可能是错误的,建议在loadeddata事件中获取视频尺寸) |
| loadstart |
---- |
开始加载视频时触发 |
| play |
--- |
播放事件 |
| pause |
--- |
暂停事件 |
| ended |
--- |
自然播放结束事件 |
| error |
--- |
播放错误事件 |
| abort |
--- |
播放中断事件 |
| timeupdate |
--- |
播放进度更新事件 |
| waiting |
--- |
加载中事件,当视频因为数据不足,需要停下来加载时会触发 |
| playing |
--- |
继续播放事件,当视频因为数据不足停下来成功加载到数据之后继续播放时触发 |
| progress |
--- |
进度加载事件 |
| seeking |
--- |
进行跳转进度操作事件 |
| seeked |
--- |
完成跳转进度操作事件 |
| seizing |
--- |
视频(直播流)播放卡住事件(仅在播放时间卡住时起效) |
| seekvolume |
--- |
音量改变事件 |
| seeklight |
--- |
亮度改变事件 |
| mutedchange |
--- |
静音改变事件 |
| ratechange |
--- |
播放倍速改变事件 |
| durationchange |
--- |
播放进度改变事件 |
| directionchange |
--- |
屏幕方向改变事件 |
| fullscreenchange |
--- |
全屏切换事件(type为api表示为全屏API调用的全屏type为css表示css模拟的全屏) |
| controlschange |
--- |
控制栏显示\消失事件 |
| capturefinish |
--- |
截图完成事件 |
| captureerror |
--- |
截图失败事件(多半是视频链接在h5跨域导致的) |
| capturesaved |
--- |
截图保存事件(一般不用管) |
| workchange |
--- |
视频切换事件 |
| qualitychange |
--- |
画质切换事件 |
| subtitlechange |
--- |
字幕切换事件 |
| threechange |
--- |
3D模式切换事件 |
| panocontrolschange |
--- |
3D模式控制器切换事件 |
| danmuconfigchange |
--- |
弹幕配置更改事件 |
| back |
--- |
非全屏下点击头部控制器返回按钮触发 |
| hlserror |
--- |
hls.js加载错误事件 |
| flverror |
--- |
flv.js加载错误事件 |
| danmusend |
--- |
弹幕发送事件 |
| danmuconfigchange |
--- |
弹幕配置更改事件 |
| destroyed |
--- |
视频销毁完成事件(可以在该事件触发时,退出视频页,避免页面报错) |
内置方法
| 方法名 |
参数 |
说明 |
| play |
--- |
播放 |
| pause |
--- |
暂停 |
| toggle |
--- |
播放/暂停 |
| seek |
--- |
跳转位置(单位是s) |
| loadDanmu |
--- |
加载弹幕模块 |
| unloadDanmu |
--- |
卸载弹幕模块 |
| sendDanmu |
--- |
发送并渲染弹幕 |
| insertDanmu |
--- |
插入弹幕数据 |
| capture |
type-截图类型:video-截图video标签, three-3D渲染模式下截图渲染后的画面, show-截图成功后是否展示截图弹窗 |
截取画面 |
| openFullscreen |
direction-屏幕方向 |
开启全屏 |
| exitFullscreen |
--- |
退出全屏 |
| showToast |
--- |
消息提示(详情见下方) |
| showToolbar |
--- |
展示工具栏(详情见下方) |
| disableGesture |
--- |
禁用手势事件 |
| enableGesture |
--- |
启用手势事件 |
| reloadVideo |
--- |
重加载视频 |
| unload |
--- |
卸载视频(卸载完成后会触发destroyed事件) |
关于H5在history路由模式下使用该组件,组件不渲染并且报错的问题(报错了才看,没报错不用看)
快速开始
<!-- 引入播放器 -->
<yb-video src="video.mp4" height="auto" />
360视频
| 属性名 |
类型 |
默认值 |
说明 |
| controlsType |
String |
orientation |
控制器类型 orbit-手指或鼠标拖动 orientation-陀螺仪控制 |
| disableDragReverse |
Boolean |
false |
关闭反方向拖拽旋转(反向拖拽更符合人的直觉) |
| enableDamping |
Boolean |
true |
添加阻尼效果(滑动更顺畅) |
- VUE2使用
<!-- 引入播放器 -->
<yb-video src="360全景视频.mp4" three="360"
:custom="custom"
@threechange="handleThreeChange"
@panocontrolschange="handlePanoControlsChange"/>
export default {
data() {
return {
custom: {
pano: {
controlsType: 'orbit',//控制器类型 orbit-手指或鼠标拖动 orientation-陀螺仪控制
},
header: {
enableThree: true//开启头部切换3D模式按钮
},
controls: {
disablePanoControlsType: false//关闭控制器类型切换按钮
}
}
}
},
methods: {
//监听3D模式改变事件
handleThreeChange (e) {
console.log(e.value)//3D模式
//可以在这里记录更改后的配置,以便用户下次继续使用
},
//监听动画控制器改变事件
handlePanoControlsChange (e) {
console.log(e.value)//动画控制器类型
//可以在这里记录更改后的配置,以便用户下次继续使用
}
}
}
- VUE3使用
<!-- 引入播放器 -->
<yb-video src="360全景视频.mp4" three="360"
:custom="custom"
@threechange="handleThreeChange"
@panocontrolschange="handlePanoControlsChange"/>
const custom = ref({
pano: {
controlsType: 'orbit',//控制器类型 orbit-手指或鼠标拖动 orientation-陀螺仪控制
},
header: {
enableThree: true//开启头部切换3D模式按钮
},
controls: {
disablePanoControlsType: false//关闭控制器类型切换按钮
}
})
//监听3D模式改变事件
const handleThreeChange = (e) => {
console.log(e.value)//3D模式
//可以在这里记录更改后的配置,以便用户下次继续使用
}
//监听动画控制器改变事件
const handlePanoControlsChange = (e) => {
console.log(e.value)//动画控制器类型
//可以在这里记录更改后的配置,以便用户下次继续使用
}
画质模块(quality)
| 属性名 |
类型 |
说明 |
| title |
String |
标题 |
| src |
String |
播放链接(画质列表的索引是根据播放链接来的,也就是说当前播放链接是什么,播放的画质就是哪一个) |
| type |
String |
解码器类型 auto-自动判断 video-使用video标签播放 hls-使用hls.js播放 flv-使用flv.js播放 |
| 属性名 |
类型 |
默认值 |
说明 |
| name |
String |
画质 |
自定义名称 |
- VUE2使用
<!-- 引入播放器 -->
<yb-video src="video-480.mp4" :quality="quality" :custom="custom" @qualitychange="handleQualityChange" />
export default {
data() {
return {
quality: [{
title: '480P',
src: 'video-480.mp4',
type: 'video'
},{
title: '720P',
src: 'video-720.mp4',
type: 'video'
}],
custom: {
quality: {
name: '播放源'//自定义名称
}
}
}
},
methods: {
//监听画质改变事件
handleQualityChange (e) {
console.log(e.index)//画质索引
console.log(e.detail)//画质详情
//可以在这里记录更改后的配置,以便用户下次继续使用
}
}
}
- VUE3使用
<!-- 引入播放器 -->
<yb-video :quality="quality" src="video-480.mp4" :custom="custom" @qualitychange="handleQualityChange" />
const quality = ref([{
title: '480P',
src: 'video-480.mp4',
type: 'video'
},{
title: '720P',
src: 'video-720.mp4',
type: 'video'
}])
const custom = ref({
quality: {
name: '播放源'//自定义名称
}
})
//监听画质改变事件
const handleQualityChange = (e) => {
console.log(e.index)//画质索引
console.log(e.detail)//画质详情
//可以在这里记录更改后的配置,以便用户下次继续使用
}
字幕模块(subtitles)
| 属性名 |
类型 |
说明 |
| title |
String |
标题 |
| src |
String |
字幕文件链接(支持vtt,srt,ass)注意不管什么格式字幕都只有最基本显示,不支持高级动画(APP-NVUE不支持本地链接) |
| 属性名 |
类型 |
默认值 |
说明 |
| fontSize |
Number |
18 |
文字大小 |
| color |
String |
#ffffff |
文字颜色 |
| bottom |
String |
10% |
底部边距 |
| shadowColor |
String |
rgba(0,0,0,.5) |
字体阴影颜色 |
- VUE2使用
<!-- 引入播放器 -->
<yb-video
src="video.mp4"
:subtitles="subtitles"
:subtitleIndex="subtitleIndex"
:custom="custom"
@subtitlechange="handleSubtitleChange" />
export default {
data() {
return {
subtitleIndex: 0,//默认加载第一个字幕
subtitles: [{
title: '中文字幕',
src: 'subtitle-ch.srt'
},{
title: '英文字幕',
src: 'subtitle-en.vtt'
},{
title: '中英字幕',
src: 'subtitle-ch-en.ass'
}],
custom: {
subtitle: {//字幕配置
bottom: '5%',
fontSize: 15
}
}
}
},
methods: {
//监听字幕改变事件
handleSubtitleChange (e) {
console.log(e.index)//字幕索引
console.log(e.detail)//字幕详情
//可以在这里记录更改后的配置,以便用户下次继续使用
}
}
}
- VUE3使用
<!-- 引入播放器 -->
<yb-video
src="video.mp4"
:subtitles="subtitles"
:subtitleIndex="subtitleIndex"
:custom="custom"
@subtitlechange="handleSubtitleChange" />
const subtitleIndex = ref(0)//默认加载第一个字幕
const subtitles = ref([{
title: '中文字幕',
src: 'subtitle-ch.srt'
},{
title: '英文字幕',
src: 'subtitle-en.vtt'
},{
title: '中英字幕',
src: 'subtitle-ch-en.ass'
}])
const custom = ref({
subtitle: {//字幕配置
bottom: 30,
fontSize: 15
}
})
//监听字幕改变事件
const handleSubtitleChange = (e) => {
console.log(e.index)//字幕索引
console.log(e.detail)//字幕详情
//可以在这里记录更改后的配置,以便用户下次继续使用
}
分P列表(works)
| 属性名 |
类型 |
说明 |
| title |
String |
标题 |
| 属性名 |
类型 |
默认值 |
说明 |
| name |
String |
分P |
自定义名称 |
- VUE2使用
<!-- 引入播放器 -->
<yb-video
:src="src"
:works="works"
:workIndex="workIndex"
:custom="custom"
@workchange="handleWorkChange" />
export default {
data() {
return {
src: 'video1.mp4',//默认第一集
workIndex: 0,//默认第一集
works: [{
title: '第一集',
src: 'video1.mp4'
},{
title: '第二集',
src: 'video2.mp4'
},{
title: '第三集',
src: 'video3.mp4'
}],
custom: {
work: {
name: '选集'//自定义名称
}
}
}
},
methods: {
//监听视频切换事件
handleWorkChange (e) {
console.log(e.index)//分P索引
console.log(e.detail)//分P详情
//可以在这里执行切换视频操作 比如
this.src = e.detail.src
}
}
}
- VUE3使用
<!-- 引入播放器 -->
<yb-video
:src="src"
:works="works"
:workIndex="workIndex"
:custom="custom"
@workchange="handleWorkChange" />
const src = ref('video1.mp4')
const workIndex = ref(0)//默认第一集
const works = ref([{
title: '第一集',
src: 'video1.mp4'
},{
title: '第二集',
src: 'video2.mp4'
},{
title: '第三集',
src: 'video3.mp4'
}])
const custom = ref({
work: {
name: '选集'//自定义名称
}
})
//监听字幕改变事件
const handleWorkChange = (e) => {
console.log(e.index)//分P索引
console.log(e.detail)//分P详情
//可以在这里执行切换视频操作 比如
src.value = e.detail.src
}
弹幕模块(danmu)
| 属性名 |
类型 |
说明 |
| mode |
Number |
弹幕模式(1-滚动 5-顶端 4-底端) |
| time |
Number |
弹幕出现的时间(单位:秒) |
| text |
String |
弹幕文本内容 |
| fontSize |
Number |
弹幕大小(单位:像素) |
| color |
String |
弹幕颜色 |
| 属性名 |
类型 |
默认值 |
说明 |
| accuracy |
Number/String |
1 |
绘制精度 auto-自动使用屏幕DPI 任意整数-自定义精度 高精度会导致性能问题,谨慎使用 |
| speed |
Number |
1 |
弹幕速度 |
| playbackRate |
Number |
1 |
弹幕倍速 |
| fontSize |
Number |
18 |
文字大小 |
| fontScale |
Number |
1 |
文字规格(几倍大小) |
| color |
String |
#ffffff |
默认颜色 |
| fontFamily |
String |
'Microsoft Yahei' |
默认字体 |
| opacity |
Number |
1 |
透明度,有效值 0-1 |
| top |
Number |
0 |
画布上边距 |
| bottom |
Number |
0 |
画布下边距 |
| lineGap |
Number |
5 |
弹幕行间距 |
| overlap |
Boolean |
false |
防重叠(开启可能会丢失弹幕) |
| timeDiffrence |
Number |
0 |
弹幕时间校准(一般用不到) |
| disableScroll |
Boolean |
false |
关闭滚动弹幕 |
| disableTop |
Boolean |
false |
关闭顶端弹幕 |
| disableBottom |
Boolean |
false |
关闭底端弹幕 |
| disableFilter |
Boolean |
false |
关闭弹幕过滤 |
| filter |
Array |
---- |
弹幕过滤列表 |
| 属性名 |
类型 |
说明 |
| pattern |
String |
过滤规则 |
| type |
String |
规则类型(string-文本 regex-正则) |
- VUE2使用
<!-- 引入播放器 -->
<yb-video ref="video" :danmu="danmu" :custom="custom" src="video.mp4"
@loadedmetadata="handleLoadedmetadata"
@danmusend="handleDanmuSend"
@danmuconfigchange="handleDanmuConfigChange" />
<input v-model="text" type="text" placeholder="输入弹幕" />
<button @tap="sendDanmu">发送弹幕</button>
export default {
data() {
return {
danmu: [{
mode: 1,
time: 1,
text: '这是滚动弹幕',
fontSize: 24,
color: '#ffffff',
},{
mode: 5,
text: '这是顶端弹幕',
fontSize: 24,
color: '#0ff0ff',
},{
mode: 4,
text: '这是底端弹幕',
fontSize: 24,
color: '#0ff0ff',
}],
custom: {
//自定义弹幕配置
danmu: {
fontSize: 24,//弹幕默认大小
fontScale: 0.7,//弹幕规格(多少倍大小)
//弹幕过滤列表
filter: [{
pattern: '求不卡',//将包含 求不卡 的弹幕过滤掉
type: 'string'//普通文本过滤
},{
pattern: '\\d+',//将包含数字的弹幕过滤掉(由于是js中写入字符串所以要用双斜杠,不然会被转义)
type: 'regex'//正则过滤
}]
}
},
text: ''
}
},
methods: {
//监听视频加载成功
handleLoadedmetadata (e) {
//判断是初始化视频,因为内部画质切换,或者错误重加载也会触发load
if ( e.type == 'init' ) {
this.$refs.video.loadDanmu()//加载弹幕模块
}
},
//监听弹幕发送事件
handleDanmuSend (danmu) {
//在这里处理弹幕,比如上传发送的弹幕到数据库
},
//监听弹幕配置改变事件
handleDanmuConfigChange (config) {
console.log(config)//config为更改后的配置
//可以在这里记录更改后的配置,以便用户下次继续使用
},
sendDanmu () {
if ( !this.text ) return
this.$refs.video.sendDanmu({
mode: 1,
text: this.text,
color: '#ffffff'
}, true)//true表示使用边框
}
}
}
- VUE3使用
<!-- 引入播放器 -->
<yb-video ref="videoRef" :danmu="danmu" :custom="custom" src="video.mp4"
@loadedmetadata="handleLoadedmetadata"
@danmusend="handleDanmuSend"
@danmuconfigchange="handleDanmuConfigChange" />
<input v-model="text" type="text" placeholder="输入弹幕" />
<button @tap="sendDanmu">发送弹幕</button>
const danmu = ref([{
mode: 1,
time: 1,
text: '这是滚动弹幕',
fontSize: 24,
color: '#ffffff',
},{
mode: 5,
text: '这是顶端弹幕',
fontSize: 24,
color: '#0ff0ff',
},{
mode: 4,
text: '这是底端弹幕',
fontSize: 24,
color: '#0ff0ff',
}])
const custom = ref({
danmu: {
fontSize: 24,//弹幕默认大小
fontScale: 0.7,//弹幕规格(多少倍大小)
//弹幕过滤列表
filter: [{
pattern: '求不卡',//将包含 求不卡 的弹幕过滤掉
type: 'string'//普通文本过滤
},{
pattern: '\\d+',//将包含数字的弹幕过滤掉(由于是js中写入字符串所以要用双斜杠,不然会被转义)
type: 'regex'//正则过滤
}]
}
})
const text = ref('')
const videoRef = ref(null)
//监听视频加载成功
const handleLoadedmetadata = (e) => {
//判断是初始化视频,因为内部画质切换,或者错误重加载也会触发load
if ( e.type == 'init' ) {
videoRef.value.loadDanmu()//加载弹幕模块
}
}
//发送弹幕
const sendDanmu = () => {
if ( !text.value ) return
videoRef.value.sendDanmu({
mode: 1,
text: text.value,
color: '#ffffff'
})
}
//监听弹幕发送事件
const handleDanmuSend = (danmu) => {
//在这里处理弹幕,比如上传发送的弹幕到数据库
}
//监听弹幕配置改变事件
const handleDanmuConfigChange = (config) => {
console.log(config)//config为更改后的配置
//可以在这里记录更改后的配置,以便用户下次继续使用
}
hls.js (部分浏览器比如safri浏览器不支持hls.js,因为这些浏览器支持直接播放hls)
- 配置(hlsConfig)
| 属性名 |
类型 |
默认值 |
说明 |
| debug |
Boolean |
---- |
流中是否有视频轨道 |
| enableWorker |
Boolean |
false |
是否使用Web Worker进行异步处理 |
| autoStartLoad |
Boolean |
true |
是否自动开始加载视频 |
| startPosition |
Number |
-1 |
指定开始播放的位置(单位:秒) |
| capLevelToPlayerSize |
Boolean |
false |
是否根据播放器尺寸限制最高质量等级 |
| capLevelOnFPSDrop |
Boolean |
---- |
流中是否有视频轨道 |
| maxBufferLength |
Number |
30 |
目标缓冲长度 |
| maxBufferSize |
Number |
60000000 |
音频和视频轨道的最大缓冲大小,以字节为单位 |
| maxBufferHole |
Number |
0.5 |
最大允许的缓冲间隙 |
| maxStarvationDelay |
Number |
---- |
最大缓冲匮乏延迟,用于处理缓冲停滞问题 |
| manifestLoadingTimeOut |
Number |
10000 |
主播放列表(m3u8)加载超时时间(ms) |
| levelLoadingTimeOut |
Number |
10000 |
质量等级列表加载超时时间(ms) |
| fragLoadingTimeOut |
Number |
20000 |
分片(ts文件)加载超时时间(ms) |
| startLevel |
Number |
-2 |
指定初始加载的视频质量等级 |
| abrBandWidthFactor |
Number |
0.95 |
带宽估算保守因子 |
| abrEwmaFastLive |
Number |
5.0 |
直播快速EWMA因子 |
| abrEwmaSlowLive |
Number |
9.0 |
直播慢速EWMA因子 |
| abrEwmaDefaultEstimate |
Number |
---- |
设置初始带宽预估,帮助播放器更准确判断 |
| liveSyncDurationCount |
Number |
3 |
直播同步段数 |
| liveMaxLatencyDurationCount |
Number |
10 |
最大延迟段数 |
| defaultAudioCodec |
String |
---- |
设置默认音频编解码器 |
| xhrSetup |
Function |
---- |
设置所有TS分片和M3U8播放列表请求头 |
| pLoader |
Function |
---- |
自定义播放列表(m3u8)加载器,可用于拦截和修改请求 |
| fLoader |
Function |
---- |
自定义分片(ts文件)加载器,可用于拦截和修改请求 |
- 由于webview和app通信的限制,函数是无法序列化传输的,所以如果要配置函数,需要使用字符串,如下所示:
<!-- 引入播放器 -->
<yb-video ref="video" src="video.mp4" :hlsConfig="hlsConfig" />
export default {
data () {
return {
hlsConfig: {
//本身应该传入函数,但因为通信限制,只能传入字符串,传入webview后,才会转换为函数
xhrSetup: `function (xhr, url) {
// 设置自定义请求头
xhr.setRequestHeader('Authorization', 'Bearer your-token-here');
xhr.setRequestHeader('Custom-Header', 'CustomValue');
// 如果需要,你也可以根据 URL 判断并设置不同的头部
if (url.includes('.ts')) {
xhr.setRequestHeader('X-Segment-Header', 'SegmentValue');
}
}`,
//本身应该传入class类,但因为通信限制,只能传入字符串,传入webview后,才会转换为class
pLoader: `
class CustomPlaylistLoader {
constructor(config) {
// 初始化,如果需要可以使用配置
}
load(context, responseType, onSuccess, onError, onTimeout, timeout, retry, retryDelay) {
// 在加载前修改URL:添加上动态参数
const url = new URL(context.url);
url.searchParams.set('token', 'dynamic-token-value');
url.searchParams.set('t', Date.now()); // 例如加时间戳防止缓存
const modifiedUrl = url.toString();
// 使用修改后的URL进行Fetch
fetch(modifiedUrl, {
method: 'GET',
headers: new Headers({
'Authorization': 'Bearer your-token', // 同时可以设置自定义头
'Custom-Header': 'CustomValue'
})
}).then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response[responseType](); // 根据responseType处理响应体
}).then(data => {
onSuccess(response, data, modifiedUrl, context); // 成功回调
}).catch(error => {
onError(error); // 失败回调
});
}
abort() {
// 实现中止请求的逻辑,例如使用AbortController
}
destroy() {
// 执行清理工作
}
}
`
}
}
}
}
flv.js (不支持ios)
| 属性名 |
类型 |
说明 |
| duration |
Number |
必填字段,表示段持续时间(以毫秒为单位 |
| filesize |
Number |
可选字段,以字节为单位指示段文件大小 |
| url |
String |
必填字段,指示段文件URL |
| 属性名 |
类型 |
默认值 |
说明 |
| cors |
Boolean |
---- |
是否启用CORS进行http提取 |
| withCredentials |
Boolean |
---- |
是否对Cookie进行http提取 |
| hasAudio |
Boolean |
---- |
流是否有音频轨道 |
| hasVideo |
Boolean |
---- |
流中是否有视频轨道 |
| duration |
Number |
---- |
总媒体持续时间(以毫秒为单位) |
| filesize |
Number |
---- |
媒体文件的总文件大小,以字节为单位 |
| enableWorker |
Boolean |
false |
启用分离的线程进行转换(暂时不稳定) |
| enableStashBuffer |
Boolean |
true |
启用IO隐藏缓冲区。如果您需要实时(最小延迟)进行实时流播放,则设置为false,但是如果网络抖动,则可能会停顿 |
| stashInitialSize |
Number |
384KB |
表示IO暂存缓冲区的初始大小。默认值为384KB。指出合适的尺寸可以改善视频负载/搜索时间 |
| isLive |
Boolean |
false |
同样要isLive在MediaDataSource,如果忽略已经在MediaDataSource结构集合 |
| lazyLoad |
Boolean |
true |
如果有足够的数据可播放,则中止http连接 |
| lazyLoadMaxDuration |
Number |
3 * 60 |
指示要保留多少秒的数据lazyLoad |
| lazyLoadRecoverDuration |
Number |
30 |
指示lazyLoad恢复时间边界,以秒为单位 |
| deferLoadAfterSourceOpen |
Boolean |
true |
在MediaSourcesourceopen事件触发后加载。在Chrome上,在后台打开的标签页可能不会触发sourceopen事件,除非切换到该标签页 |
| autoCleanupSourceBuffer |
Boolean |
false |
对SourceBuffer进行自动清理 |
| autoCleanupMaxBackwardDuration |
Number |
3 * 60 |
当向后缓冲区持续时间超过此值(以秒为单位)时,请对SourceBuffer进行自动清理 |
| autoCleanupMinBackwardDuration |
Number |
2 * 60 |
指示进行自动清除时为反向缓冲区保留的持续时间(以秒为单位) |
| fixAudioTimestampGap |
Boolean |
true |
当检测到较大的音频时间戳间隙时,请填充无声音频帧,以避免A / V不同步 |
| accurateSeek |
Boolean |
false |
精确查找任何帧,不限于视频IDR帧,但可能会慢一些。可用的Chrome > 50,FireFox和Safari |
| seekType |
String |
'range' |
'range'使用范围请求进行查找,或'param'在url中添加参数以指示请求范围 |
| seekParamStart |
String |
'bstart' |
指示的搜索起始参数名称 seekType = 'param' |
| seekParamEnd |
String |
'bend' |
指示的搜索结束参数名称 seekType = 'param' |
| rangeLoadZeroStart |
Boolean |
false |
Range: bytes=0-如果使用范围查找,则发送首次负载 |
| customSeekHandler |
Object |
---- |
指示自定义搜索处理程序 |
| reuseRedirectedURL |
Boolean |
false |
重复使用301/302重定向的url进行子序列请求,例如搜索,重新连接等 |
| referrerPolicy |
String |
'no-referrer-when-downgrade' |
指示使用FetchStreamLoader时的推荐人策略 |
| headers |
Object |
---- |
指示将添加到请求的其他标头 |
jsmpeg.js
| 属性名 |
类型 |
默认值 |
说明 |
| loop |
Boolean |
true |
是否循环播放视频(仅静态文件),默认=true |
| autoplay |
Boolean |
false |
是否立即开始播放(仅限静态文件),默认=false |
| audio |
Boolean |
true |
是否解码音频,默认=true |
| video |
Boolean |
true |
是否解码视频,默认=true |
| poster |
String |
---- |
预览图像的URL,用来在视频播放之前作为海报显示。 |
| pauseWhenHidden |
Boolean |
true |
当页面处于非活动状态时是否暂停播放,默认=true(请注意,浏览器通常会在非活动选项卡中限制 JS) |
| disableGl |
Boolean |
false |
是否禁用WebGL,始终使用Canvas2D渲染器,默认=false |
| disableWebAssembly |
Boolean |
false |
是否禁用WebAssembly并始终使用JavaScript解码器,默认=false(不建议设置为true) |
| preserveDrawingBuffer |
Boolean |
---- |
WebGL上下文是否创建必要的“截图”(如果需要截图,要设置该属性为true,不然截图会黑屏) |
| progressive |
Boolean |
---- |
是否以块的形式加载数据(仅静态文件)。当启用时,回放可以在完整加载源之前开始 |
| throttled |
Boolean |
---- |
当不需要回放时是否推迟加载块。默认=progressive |
| chunkSize |
Number |
---- |
指使用时,以字节为单位加载的块大小。默认(1 mb)1024*1024 |
| decodeFirstFrame |
Boolean |
true |
是否解码并显示视频的第一帧,一般用于设置画布大小以及使用初始帧作为"poster"图像。当使用自动播放或流媒体资源时,此参数不受影响。默认true |
| maxAudioLag |
Number |
---- |
流媒体时,以秒为单位的最大排队音频长度。(可以理解为能接受的最大音画不同步时间) |
| maxAudioLag |
Number |
---- |
流媒体时,以秒为单位的最大排队音频长度。(可以理解为能接受的最大音画不同步时间) |
| videoBufferSize |
Number |
---- |
流媒体时,视频解码缓冲区的字节大小。默认的512 * 1024 (512 kb)。对于非常高的比特率,您可能需要增加此值。 |
| audioBufferSize |
Number |
---- |
流媒体时,音频解码缓冲区的字节大小。默认的128 * 1024 (128 kb)。对于非常高的比特率,您可能需要增加此值。 |
消息提示(showToast)
- VUE2使用
<!-- 引入播放器 -->
<yb-video ref="video" src="video.mp4" @loadedmetadata="handleLoadedmetadata" />
export default {
methods: {
handleLoadedmetadata (e) {
this.$refs.video.showToast({
message: '视频加载成功',//消息内容
duration: 3000//显示周期
})
}
}
}
- VUE3使用
<!-- 引入播放器 -->
<yb-video ref="videoRef" src="video.mp4" @loadedmetadata="handleLoadedmetadata" />
const videoRef = ref(null)
//监听截图保存事件
const handleLoadedmetadata = (e) => {
videoRef.value.showToast({
message: '视频加载成功',//消息内容
duration: 3000//显示周期
})
}
自定义工具栏(showToolbar)
- VUE2使用
<!-- 引入播放器 -->
<yb-video ref="video" src="video.mp4" :custom="custom" />
export default {
data () {
return {
custom: {
controls: {
rightSlots: [{
innerHTML: '<div class="my-custom-btn yb-player-icon">自定义</div>',
click: () => {
this.$refs.video.showToolbar({
selector: '.my-custom-btn',
list: [{
text: '自定义工具1',
click: () => {
this.$refs.video.showToast('自定义工具1')
}
},{
text: '自定义工具2',
click: () => {
this.$refs.video.showToast('自定义工具2')
}
},{
text: '自定义工具3',
click: () => {
this.$refs.video.showToast('自定义工具3')
}
}]
})
}
}]
}
}
}
}
}
- VUE3使用
<!-- 引入播放器 -->
<yb-video ref="videoRef" src="video.mp4" :custom="custom" />
const videoRef = ref(null)
const custom = ref({
controls: {
rightSlots: [{
innerHTML: '<div class="my-custom-btn yb-player-icon">自定义</div>',
click: () => {
videoRef.value.showToolbar({
selector: '.my-custom-btn',
list: [{
text: '自定义工具1',
click: () => {
videoRef.value.showToast('自定义工具1')
}
},{
text: '自定义工具2',
click: () => {
videoRef.value.showToast('自定义工具2')
}
},{
text: '自定义工具3',
click: () => {
videoRef.value.showToast('自定义工具3')
}
}]
})
}
}]
}
})
自定义配置(custom)(因为内容太多只展示VUE2示例,VUE3示例参考上面的示例更改)
<!-- 引入播放器 -->
<yb-video src="video.mp4" :custom="custom" />
export default {
data () {
return {
custom: {
disableLoading: false,//关闭loading
disableCenterPlay: false,//关闭中间播放按钮
disableError: false,//关闭加载错误提示
disableBottomProgress: false,//关闭底部进度条
//自定义插槽
slots: [{
innerHTML: '<div class="yb-player-icon" style="position:absolute;top:50px;left:50px;">跟随控制栏的按钮</div>',
followControls: true,//跟随控制栏
click: function () {
console.log('点击了跟随控制栏的按钮')
}
},{
innerHTML: '<div class="yb-player-icon" style="position:absolute;top:50px;right:50px;">永远显示的按钮</div>',
followControls: false,//不跟随控制栏
click: function () {
console.log('点击了永远显示的按钮')
}
}],
//头部控制器配置
header: {
disableBack: false,//关闭返回按钮
disableTitle: false,//关闭标题显示
disableWorks: false,//关闭分P按钮
disableRate: false,//关闭倍速选择
enableThree: false,//开启3D模式切换按钮
disableMore: false,//关闭展示更多按钮
disableLock: false,//关闭锁屏
disableThreeCapture: false,//关闭3D截图
disableCapture: false,//关闭视频截图
disableDanmuFilter: false,//关闭弹幕过滤配置
disableDanmuSetting: false,//关闭弹幕配置
//更多选项自定义配置
more: [{
text: '测试按钮1',
click: function () {
console.log('点击了测试按钮1')
}
},{
text: '测试按钮2',
click: function () {
console.log('点击了测试按钮2')
}
}],
//左边插槽
leftSlots: [{
innerHTML: '<div class="yb-player-icon">左边按钮</div>',
click: function () {
console.log('点击了头部左边按钮')
}
}],
//右边插槽
rightSlots: [{
innerHTML: '<div class="yb-player-icon">右边按钮</div>',
click: function () {
console.log('点击了头部右边按钮')
}
}]
},
//底部控制栏自定义配置
controls: {
disablePrev: false,//关闭播放上一个按钮
disableNext: false,//关闭播放下一个按钮
disableToggle: false,//关闭播放\暂停按钮
disableDanmuSend: false,//关闭发送弹幕按钮
disableFullscreen: false,//关闭全屏按钮
disableMuted: false,//关闭静音按钮
disableDanmuVisible: false,//关闭弹幕显示和隐藏按钮
disableSubtitle: false,//关闭字幕切换按钮
disableQuality: false,//关闭画质切换按钮
disablePanoControlsType: false,//关闭3D模式控制器切换按钮
//左边插槽
leftSlots: [{
innerHTML: `
<svg viewBox="0 0 24 24">
<path d="M8 5v14l11-7z"/>
</svg>
`,//如果要插入图标,只能使用svg
click: function () {
console.log('点击了控制栏左边插槽按钮')
}
}],
//右边插槽
rightSlots: [{
innerHTML: `
<svg viewBox="0 0 24 24">
<path d="M8 5v14l11-7z"/>
</svg>
`,//如果要插入图标,只能使用svg
click: function () {
console.log('点击了控制栏右边插槽按钮')
}
}]
},
//进度条自定义配置
progress: {
disablePrev: false,//关闭播放上一个按钮
disableNext: false,//关闭播放下一个按钮
disableToggle: false,//关闭播放\暂停按钮
disableFullscreen: false,//关闭全屏按钮
disableRange: false,//关闭进度条拖动
//左边插槽
leftSlots: [{
innerHTML: '<div class="yb-player-icon">左边按钮</div>',
click: function () {
console.log('点击了进度条左边按钮')
}
}],
//右边插槽
rightSlots: [{
innerHTML: '<div class="yb-player-icon">右边按钮</div>',
click: function () {
console.log('点击了进度条右边按钮')
}
}]
},
//手势配置
gesture: {
initialVolume: 0,//初始化设备音量
initialLight: 0,//初始化屏幕亮度
disableUnFullscreenEvent: false,//关闭非全屏手势事件
disableLongPress: false,//关闭长按事件
disableLight: false,//关闭手势控制屏幕亮度
disableVolume: false,//关闭手势控制设备音量
disableProgress: false,//关闭手势跳转进度
disableSingleClick: false,//关闭单击事件
disableDoubleClick: false,//关闭双击事件
disableLongPress: false,//关闭长按事件
setLight: function (light) {//自定义改变亮度方法
console.log('亮度', light)
},
setVolume: function (volume) {//自定义改变音量方法
console.log('音量', volume)
},
getLight: function () {//自定义获取亮度方法
return 1//返回亮度 0-1
},
getVolume: function () {//自定义获取音量方法
return 1//返回音量 0-1
}
},
//分P配置
work: {
name: '分P'//自定义名称
},
//画质配置
quality: {
name: '画质'//自定义名称
},
//字幕配置
subtitle: {
color: '#ffffff',//文字颜色
fontSize: 18,//字体大小
bottom: '10%',//底部边距
shadowColor: 'rgba(0,0,0,.5)'//阴影颜色
},
//3D模式配置
pano: {
controlsType: 'orientation',//控制器类型 orbit-手指或鼠标拖动 orientation-陀螺仪控制
disableDragReverse: false,//关闭反方向拖拽旋转(反向拖拽更符合人的直觉)
enableDamping: true//添加阻尼效果(滑动更顺畅)
},
//弹幕配置
danmu: {
accuracy: 1,//绘制精度 auto-自动使用屏幕DPI 任意整数-自定义精度 高精度会导致性能问题,谨慎使用
speed: 1,//弹幕运行速度
playbackRate: 1,//弹幕倍速
color: '#FFFFFF',//弹幕默认颜色
fontSize: 18,//弹幕默认大小
fontScale: 1,//弹幕规格(多少倍大小)
fontFamily: 'Microsoft Yahei',//弹幕默认字体
opacity: 1,//弹幕透明度
top: 0,//舞台顶部间距
bottom: 0,//舞台底部间距
lineGap: 5,//弹幕行间距
overlap: false,//开启防重叠
timeDiffrence: 0,//时间差(用于校准弹幕和视频进度的时间差,一般不需要)
disableScroll: false,//关闭滚动弹幕
disableTop: false,//关闭顶端弹幕
disableBottom: false,//关闭底端弹幕
disableFilter: false,//关闭弹幕过滤
filter: []//过滤列表
}
}
}
}
}
全屏元素和非全屏元素标记
<!-- 引入播放器 -->
<yb-video src="video.mp4" :custom="custom" />
- vue2使用
export default {
data () {
return {
custom: {
//头部控制器配置
header: {
//右边插槽
rightSlots: [{
innerHTML: '<div class="yb-player-icon yb-plyer-full">头部按钮1</div>',//yb-plyer-full表示该插槽元素只在全屏时显示
click: function () {
console.log('点击了只在全屏时显示的头部按钮')
}
},{
innerHTML: '<div class="yb-player-icon yb-plyer-unfull">头部按钮2</div>',//yb-plyer-unfull表示该插槽元素只在非全屏时显示
click: function () {
console.log('点击了只在非全屏时显示的头部按钮')
}
}]
}
}
}
}
}
- VUE3使用
<!-- 引入播放器 -->
<yb-video ref="videoRef" src="video.mp4" :custom="custom" />
const custom = ref({
//头部控制器配置
header: {
//插槽
rightSlots: [{
innerHTML: '<div class="yb-player-icon yb-plyer-full">头部按钮1</div>',//yb-plyer-full表示该插槽元素只在全屏时显示
click: function () {
console.log('点击了只在全屏时显示的头部按钮')
}
},{
innerHTML: '<div class="yb-player-icon yb-plyer-unfull">头部按钮2</div>',//yb-plyer-unfull表示该插槽元素只在非全屏时显示
click: function () {
console.log('点击了只在非全屏时显示的头部按钮')
}
}]
}
})
组件插槽(仅在renderjs渲染模式下有效)
- VUE2使用
<!-- 引入播放器 -->
<yb-video ref="video" render-type="renderjs" src="video.mp4" >
<view class="custom-slot" @tap="handleSlotClick">这是组件插槽仅在renderjs渲染模式下有效</view>
<!-- yb-player-gesture是手势事件标记,如果不添加yb-player-gesture类,点击到该组件会阻止手势事件(比如点击弹出控制栏),自行根据需求添加 -->
<view class="custom-slot yb-player-gesture" @tap="handleSlotClick">这是组件插槽仅在renderjs渲染模式下有效</view>
</yb-video>
export default {
method: {
handleSlotClick () {
this.$refs.video.showToast('点击了组件插槽')
}
}
}
.custom-slot{
position:absolute;
top:50px;
left:50px;
color:#fff;
}
- VUE3使用
<!-- 引入播放器 -->
<yb-video ref="videoRef" render-type="renderjs" src="video.mp4" >
<view class="custom-slot" @tap="handleSlotClick">这是组件插槽仅在renderjs渲染模式下有效</view>
<!-- yb-player-gesture是手势事件标记,如果不添加yb-player-gesture类,点击到该组件会阻止手势事件(比如点击弹出控制栏),自行根据需求添加 -->
<view class="custom-slot yb-player-gesture" @tap="handleSlotClick">这是组件插槽仅在renderjs渲染模式下有效</view>
</yb-video>
const videoRef = ref(null)
const handleSlotClick = () => {
videoRef.value.showToast('点击了组件插槽')
}
.custom-slot{
position:absolute;
top:50px;
left:50px;
color:#fff;
}
IOS特别说明
- IOS播放hls视频流,在新版本的ios系统中,需要指定type为video才能播放,这是因为新版本的ios系统中Hls.isSupported()方法返回的是true,但ios又不支持使用hls.js播放hls视频流
- IOS可能不支持在APP-NVUE环境使用本插件,因为WKWbview内核对于访问本地的html文件,也认为是跨域行为
- IOS即将废弃UIWebview内核,所以ios项目默认使用WKWebview,而WKWebview严格执行cors策略,很多行为都会被认为是跨域行为,导致很多操作无法执行,特别是使用iframe加载本地网页,所以ios只能使用renderjs方式渲染视频(或许H5可以)
- IOS想使用web方式渲染或者在APP-NVUE中使用,需要去manifest.json里面配置webview内核为UIWebview,如下:
// 在manifest.json配置
"app-plus": {
"kernel": {
"ios": "UIWebview" //或者 "WKWebview"
},
// ...
}
- 如果你修改了webview内核在APP-NVUE-IOS环境使用本插件,会有全屏问题,因为IOS不支持全屏API,只能使用css模拟,但APP-NVUE不支持z-index控制层级,默认后渲染得元素层级更高,所以APP-NVUE-IOS全屏时可能会出现无法遮盖后渲染元素得问题
-
正如上面所说IOS不支持全屏API,所以IOS在APP-VUE和H5得全屏也和安卓有区别,在IOS上使用css模拟全屏无法遮盖原生元素,需要自行遮盖和隐藏,如下:
// 在pages.json配置引入播放器的页面为沉浸模式
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom"//隐藏原生导航栏
}
},
<!-- 在pages/index/index页面引入播放器 -->
<yb-video src="video.mp4" @fullscreenchange="handleFullscreenChange" />
export default {
methods: {
handleFullscreenChange (e) {
//css模拟的全屏
if ( e.type == 'css' ) {
//当前状态是开启全屏
if ( e.fullscreen ) {
//可以在这里做无法遮盖原生元素的隐藏
//插件内部已经调用plus.screen.setFullscreen(true)和plus.hideSystemNavigation() 一般不用调用
}
//当前状态是退出全屏
else {
//可以在这里做无法遮盖原生元素的显示
//插件内部已经调用plus.screen.setFullscreen(false)和plus.showSystemNavigation() 一般不用调用
}
}
}
}
}
- 真机调试IOS发现横竖屏设置无效,需要去manifest.json配置屏幕方向(配置完成后需重新打包自定义基座或者apk才会生效)
// 在manifest.json配置screenOrientation的屏幕方向
"app-plus" : {
"screenOrientation": [
"portrait-primary",
"portrait-secondary",
"landscape-primary",
"landscape-secondary"
]//ios不配置屏幕方向,无法旋转屏幕
}
- 如果真机调试IOS横屏会旋转2次,需要固定屏幕方向,如下:
<!-- 引入播放器 -->
<!-- landscape-primary是固定横屏后的方向,这样就不会发生旋转2次的问题,但这样无法实现视频自动跟随屏幕方向 -->
<yb-video src="video.mp4" open-direction="landscape-primary" @fullscreenchange="handleFullscreenChange" />