第一篇文章 记app webview内嵌h5开发视频播放器踩坑
- 视频自动播放
- ios默认全屏播放
- 在微信,飞书等内置浏览器打开h5,调用requestFullscreen方法,自动旋转导致视频进度条拖动错误
查阅MDN发现
网页加载完成后立即播放音频(或带有音频轨道的视频)可能会意外地打扰到用户。尽管自动播放媒体文件是一个很实用的功能,但是我们也应该谨慎地使用它,保证只有在它被需要的时候才使用。为了让用户拥有控制权,通常浏览器会提供各种方式禁用自动播放音频功能。
由于浏览器带有自动播放策略,需要在视频不能自动播放时,进行处理,总结找到的几种方法。
1.将视频进行静音处理,视频在静音的情况下是可以进行自动播放的,但是就导致视频没有声音。
<video muted></video>
2.调用video标签的play方法返回一个Promise,可以根据该Promise状态检测能否自动播放进行相应的处理。
// 检测h5能否自动播放
export function isAutoPlay() {
return new Promise((resolve, reject) => {
const video = document.createElement('video')
document.body.appendChild(video)
const startPlayPromise = video.play()
if (startPlayPromise !== undefined) {
startPlayPromise
.then(() => {
resolve()
})
.catch((error) => {
if (error.name === 'NotAllowedError') {
reject(new Error("can't autoPlay"))
} else {
reject(error.message)
}
})
.finally(() => {
document.body.removeChild(video)
})
}
})
}
3.引导用户在播放视频之前和网页产生交互行为。
在ios webview中,播放视频时会默认全屏播放,此时需要在video标签上进行设置
//视频播放时局域播放
playsinline="true"
webkit-playsinline="true"
注:但是这个属性比较特别, 需要嵌入网页的APP比如WeChat中UIwebview 的allowsInlineMediaPlayback = YES
如果还需要ios能够自动播放,还需要ios进行设置。
为了在app上播放器和设计图一致,手写了一个简易播放器,在该播放器上,需要实现全屏功能。
直接使用浏览器自带的requestFullscreen方法,查阅兼容性发现,ios设备对该属性支持不咋滴
最后决定在app内部打开的h5使用css来模拟全屏的效果,暂时没有更好方案。 直接将父元素直接铺满,video标签在其中居中,高度根据width:100%自适应。
在app外部,使用原生方法来对元素进行全屏操作
full() {
//通过jsBridge来判断是否app环境
if (this.jsBridge.check()) {
this.isFull = !this.isFull
} else if (!document.fullscreenEnabled) {
this.isFull = !this.isFull
} else if (this.isFull) {
//推出全屏判断各浏览器兼容性
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else {
document.webkitExitFullscreen()
}
this.isFull = false
} else {
//进入全屏判断各浏览器兼容性
const video = document.querySelector('.video')
if (video.requestFullscreen) {
video.requestFullscreen()
} else if (video.mozRequestFullScreen) {
video.mozRequestFullScreen()
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen()
} else if (video.msRequestFullScreen) {
video.msRequestFullScreen()
}
this.isFull = true
}
// const video = this.$refs.video
},
当我们使用微信内置浏览器打开h5进行播放视频时,调用微信浏览器的requestFullscreen方法,浏览器自动将我们的视频进行了横屏操作,导致进度条拖拽功能出现了错误。
进度条拖拽功能实现步骤:
- 获取进度条元素相对于page的left和right以及本身的宽
getOffsetInfo() {
this.left = document.getElementsByClassName('progress-box')[0].getBoundingClientRect().left
this.right = document.getElementsByClassName('progress-box')[0].getBoundingClientRect().right
this.domWidth = document.getElementsByClassName('progress-box')[0].clientWidth
},
- 当进度条的touch事件触发之后获取触摸点的坐标 当前进度 = ((触摸点的x坐标 - 进度条的left) / 进度条的width)* 100
computedNowPosition() {
const pageX = this.startTouchPoint.pageX
const ratio = (pageX - this.left) / this.domWidth
//duration为当前视频总时长
this.currentTime = ratio * this.duration
this.$refs.video.currentTime = ratio * this.duration
this.width = ratio * 100
},
在微信内打开h5使用全屏方法,浏览器自动旋转了播放器,导致计算当前播放进度方法出错,经过反复查找问题,我们的left是一开始播放器没有旋转时的left,当播放器被旋转之后left被改变了,并且触发了window的resize事件,所以当resize事件被触发的时候,我们需要重新获取进度条的各种距离
// 在微信或者飞书打开使用自带全屏方法,全屏时重新获取进度条相对屏幕的距离
window.addEventListener('resize',()=>{
this.getOffsetInfo()
})
以此记录掘金第一篇文章!!!