更新记录
2.0.0(2024-08-03) 下载此版本
将原有的ls-dom-video迁移至此。
平台兼容性
Vue2 | Vue3 |
---|---|
√ | √ |
App | 快应用 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 |
---|---|---|---|---|---|---|
× | × | × | × | × | × | × |
钉钉小程序 | 快手小程序 | 飞书小程序 | 京东小程序 |
---|---|---|---|
× | × | × | × |
H5-Safari | Android Browser | 微信浏览器(Android) | QQ浏览器(Android) | Chrome | IE | Edge | Firefox | PC-Safari |
---|---|---|---|---|---|---|---|---|
× | × | × | × | × | × | × | × | × |
dom-video-player
- 使用 html5 的原生 video 标签,实现的APP
中的视频播放器组件
介绍
缘由(uniapp 提供的 video 原生组件不香吗???)
- 香!uniapp 中的 video 是原生组件,提供了丰富的参数配置和事件回调,能不香吗?但局限性也是有的,无法满足我司的产品需求 和 设计同学的 UI 需求(打也打不过):
- uniapp 的视频播放器是原生组件,
层级
比较高于普通前端组件,难以被业务组件和定制化需求所遮挡
、覆盖
。 - 使用
cover-view
遮挡的话又有一些 css 样式限制 & 显隐的兼容性问题,plus.nativeObj.view
的开发难度高。 - uniapp 的视频播放器就难以自定义样式了,播放按钮、进度条、遮挡层级等无法实现 UI 的设计需求。
- video 在
scroll-view
和swiper
中的使用问题,原生组件使用限制 - uniapp 的视频播放器在 iOS 端与
uni.getBackgroundAudioManager
背景音频的事件冲突,事件调用存在互相干扰。
- uniapp 的视频播放器是原生组件,
实现
- 代码实现其实很简单的,思路:
通过 renderjs 将 HTML5 中的 video 标签渲染到 APP 上来
! - 但是从一开始想到这个
思路
真的好难,起初在插件市场没找到一个解决视频层级的相关插件,于是只能自己写了~
迭代更新
上线
DCloud 插件市场
一年以来,大家反馈都很不错,基本都是五星好评,还有许多大佬们的打赏
,也收到了许多的技术咨询和私信,根据大家的需求和建议更新迭代了下:
- 对编码本身做了优化,清晰的定义了
原生事件
和自定义事件
,方便大家根据自身业务去进行二次开发、修改。 - 优化了属性更新逻辑,支持播放过程中
controls
、muted
、loop
等属性变更,不会造成视频的重新渲染。 - 优化了 Android 在加载视频时出现
黑色播放按钮
的情况,增加了 loading 效果,优化了视频封面的第一帧展示。 - 新增了
播放进度(timeupdate)
、播放总长(durationchange)
的自定义事件,用户可通过事件监听来实现自定义进度条。 - 新增了
ratechange
、fullscreenchange
、canplay
等 video 的原生事件监听。 - 新增了
全屏播放
的fullScreen()
函数调用,支持多机型、多端的兼容适配,支持安卓、ios、h5端。 - 新增了
进度跳转
的toSeek(time, isDelay)
函数调用,支持延迟生效,保证视频加载完成后生效。 - 新增了
swiper
的 banner 的左右滑案例、全屏上下滑动类似抖音视频
播放案例。 - 提供了更加完善的 vue2
项目示例
,顺便支持了下vue3
的使用和项目示例。
使用说明
video 组件的 props 传值:
src: '' // 视频地址
autoplay: false // 是否自动播放
loop: false // 是否循环播放
controls: false // 是否显示控制栏
muted: false // 是否静音
isLoading: false // Android系统加载时显示loading(为了遮挡安卓的黑色按钮)
objectFit: 'contain' // 视频尺寸与video区域的适应模式
poster: '' // 视频封面
video 向父组件传递的事件:
play: () => {} // 播放事件
pause: () => {} // 暂停事件
ended: () => {} // 播放结束事件
timeupdate: (e) => {} // 视频播放进度事件
durationchange: (e) => {} // 视频总时长改变事件
video 组件
methods
方法:
play() // 播放
pause() // 暂停
remove() // 移除视频
fullScreen() // 进入全屏
toSeek(time) // 跳转到指定时间点(s)
// example: 父组件对 video 的 methods 调用案例
methods: {
// 播放视频
play() {
const videoPlayer = this.$refs.domVideoPlayer
videoPlayer.play()
},
// 删除视频
remove() {
const videoPlayer = this.$refs.domVideoPlayer
videoPlayer.remove()
}
}
子组件的
data
数据:
currentTime: 0 // 当前播放时间
duration: 0 // 视频总时长
playing: false // 是否播放中
// example: 父组件对 video 的 data 数据获取案例
methods: {
// 播放/暂停视频
playOrPause() {
const videoPlayer = this.$refs.domVideoPlayer
// 获取 video 当前是否处于播放中
if (videoPlayer.playing) {
videoPlayer.pause()
} else {
videoPlayer.play()
}
}
}
组件书写案例:
<DomVideoPlayer
ref="domVideoPlayer"
src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-video-courses.mp4"
autoplay
loop
controls
muted
/>
父组件调用子组件方法:
/* vue2 */
let videoPlayer = this.$refs.domVideoPlayer
videoPlayer.play()
/* vue3 */
const videoPlayer = ref(null)
videoPlayer.play()
使用异常 Q&A
-
视频黑屏,播放不出来?
- 视频地址必须是网络地址,不可以是本地地址。
- 播放器仅支持常用视频格式,视频格式支持情况
- 视频带有签名已过期、视频过大导致加载时间长等。
-
我的视频是
hls
、flv
格式(视频流),该如何播放?- flv 格式的视频就没办法了,
flv.js
重点是调用MediaSource
的创建,在 iOS 的浏览器内核中暂时不支持该 API。 - hls 格式的视频还算有办法,使用 hls.js 去播放就好了,具体使用可以看我另一个插件项目:hls-video-player
- flv 格式的视频就没办法了,
-
Android 端的视频,为什么播放前有个
黑色播放图标
?- 因为使用的是 html5 中的 video 标签进行播放,而在 Android 系统的浏览器内核中,视频器自带了这个播放图标样式,无法自定义。
- 解决方案:使用 loading 去遮挡播放图标这个期间的视频加载过程,该组件已实现该能力,提供了
isLoading
属性,默认是 false,设置为 true 即可。
-
为什么拖拽 video 原生进度条的时候,视频会出现文字
“在左侧或右侧点按两次即可跳过 10 秒”
?- 因为是使用 html5 中的 video 标签进行播放,而在 Android 系统的浏览器内核中,视频器自带了这个文字提示,无法自定义。
-
iOS 端为什么不能两个视频
同时播放
?- 因为在 iOS 系统中不允许两个音频媒体同时播放,所以两个有声视频是不能同时播放的。
- 想同时播放两个视频最简单的方案是,将视频的
muted
静音属性设置为 true,这样两个视频就不会播放声音,即可以同时播放视频了。
-
我要在视频上做一个 click 点击事件,该怎么做?
- 可以在
DomVideoPlayer
组件外包一层 div,然后给 div 标签绑定上点击事件,就可以了。
- 可以在
-
我的项目是
vue3
的,组件是 vue2 的,可以使用吗?- 可以使用的,demo 案例中有 vue3 的基本案例、swiper案例等。
-
控制台显示
xxxx https://goo.gl/LdLk22 xxxx
这样之类的报错是什么?- 点开链接有相关说明,一种是警告我们不要在非静音状态下直接播放视频,这是谷歌的用户体验规范,可以忽略。
- 另一种是告诉我们 play() 被 pause() 行为打断了,因为 play() 是异步,不影响视频播放,可以忽略。
-
vue3 可以使用吗?
- 当然可以,本身编译后是兼容的,在示例项目中有 vue3 的案例。
- 如果希望组件也是 vue3 版本的,因为是 renderjs 写的,其实没必要。
-
有更多的函数和组件调用的业务需求,该
如何扩展
?- 更多拓展函数和事件,可以通过组件中的提供的
renderFunc
进行实现,video 原生的事件调用可借助组件中的eventCommand
进行实现,详细可阅读源码。 - 有难题需要技术咨询、需要更多的定制化组件、定制化能力、其它技术问题等可以联系作者,提供
免费
/付费帮助。
- 更多拓展函数和事件,可以通过组件中的提供的
作者联系方式?
// 因官方不允许作者透露个人信息,需要大佬们理解一下了...
const numbers = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
const secrets = [9, -1, -5, 1, 3, 2]
let weChat = ''
numbers.forEach((v, i) => {
weChat += (secrets[i] || 0) + v
})
console.log(weChat)