项目中的视频标记实践、属性和事件详情
最编程
2024-04-09 18:17:32
...
前言
- 新年开工第一天,祝大家新年快乐、虎年大吉、技术和工资蹭蹭涨、代码
bug
蹭蹭没,万事如意!???????????? -
video
标签大家应该都很熟悉了,那有没有遇到些什么问题呢?年前在做一个活动页面的时候,需要放一个视频在上面,本以为是一个很简单的功能,结果最后却是其他功能都实现了,这个视频播放还有各种问题。
遇到的问题
-
iOS
视频无法自动播放; -
iOS
视频点击播放会自动全屏; - 外部链接(微信中),
iOS
无法监听事件; - 点击播放时,视频区域会出现白屏;
- 原生的
UI
样式太丑,需要弃掉并按UI
设计重新写。
了解 video 属性及事件
- 在解决上面的问题之前,我们需要先了解
video
标签有哪些属性以及事件,我们要用到哪些来解决上面的问题。
HTML
属性
- 全局属性(所有 HTML 元素一起使用的属性)。
- 其他属性
-
src
: 要播放的视频的URL
。 -
controls
: 如果出现该属性,则向用户显示控件,比如播放按钮。 -
poster
: 规定视频下载时显示的图像,或者在用户点击播放按钮前显示的图像。 -
autoplay
: 如果出现该属性,则视频在就绪后马上播放。 -
preload
: 如果出现该属性,则视频在页面加载时进行加载,并预备播放。如果使用"autoplay"
,则忽略该属性。 -
loop
: 如果出现该属性,则当媒介文件完成播放后再次开始播放。 -
muted
: 规定视频的音频输出应该被静音。 -
poster
: 规定视频下载时显示的图像,或者在用户点击播放按钮前显示的图像。 -
playsinline、webkit-playsinline
: 小窗播放。
-
实例属性
属性名 | 属性含义 |
---|---|
currentSrc | 当前视频地址 |
currentTime | 视频已播放时间 |
videoWidth | 视频本身的宽度 |
videoHeight | 视频本身的高度 |
duration | 视频长度,流返回无限 |
ended | 是否播放结束 |
error | 媒体错误(null:正常) |
paused | 是否停止 |
muted | 是否静音 |
seeking | 是否在seeking |
volume | 音量 |
height | 播放框的高度 |
width | 播放框的宽度 |
startTime | 开始时间,默认为0 |
defaultPlaybackRate | 默认回放速度 |
playbackRate | 当前播放速度 |
video
事件
事件名 | 事件含义 |
---|---|
loadstart | 客户端开始请求数据 |
progress | 客户端正在请求数据 |
suspend | 延迟下载 |
abort | 客户端主动终止下载(不是因为错误引起) |
error | 请求数据时遇到错误 |
stalled | 网速失速 |
play | play()和autoplay开始播放时触发 |
pause | pause()触发 |
loadedmetadata | 成功获取资源长度 |
loadeddata | 媒介数据已加载时运行的脚本 |
waiting | 等待数据,并非错误 |
playing | 开始回放 |
canplay | 可以播放,但中途可能因为加载而暂停 |
canplaythrough | 可以播放,视频全部加载完毕 |
seeking | 寻找中 |
seeked | 寻找完毕 |
timeupdate | 播放时间改变 |
ended | 播放结束 |
ratechange | 播放速率改变 |
durationchange | 资源长度改变 |
volumechange | 音量改变 |
问题解决
- 通告前面的介绍,相信就算没用过
video
标签的小伙伴也有一定的了解了,针对遇到的问题,我们要用到哪些呢?下面是基本的一些属性:
<video
ref="videoRef"
class="video"
controls
autoplay
poster="https://xxx.png"
/>
iOS 视频无法自动播放
- 去掉
video
标签上的autoplay
属性。 - 在
mounted
中设置video
的视频src
并执行load
方法,通过添加事件,监听视屏的加载,触发事例的播放事件。 - 当在初始化时给视频上方盖一个遮罩层,当视频可以播放时,隐藏遮罩层。
mounted() {
const videoDom = this.$refs.videoRef;
videoDom.src = 'https://xxx.mp4';
videoDom.load();
videoDom.addEventListener('canplay', this.canPlayVideo);
},
methods: {
canPlayVideo() {
const videoDom = this.$refs?.videoRef;
if (!videoDom) return;
if (videoDom.currentTime > 0) {
videoDom.currentTime = 0;
}
videoDom.play();
this.videoLoading = false;
this.isPaused = videoDom.paused; // 后续 UI 样式
videoDom.removeEventListener('canplay', this.canPlayVideo);
},
},
iOS
视频点击播放会自动全屏
- 给 video 标签添加
playsinline、webkit-playsinline
属性。
<video
ref="videoRef"
class="video"
preload="auto"
controls
playsinline
webkit-playsinline
poster="https://xxx.png"
/>
外部链接(微信中),iOS
无法监听事件
方法一
- 由于无法监听事件,那就不用自动播放,在第一个问题中直接去掉 autoplay(多端一致),或者保留,能自动播放就自动播放。
方法二
- 引入微信
jssdk
,<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
const video = document.querySelectorAll("video")[0]
document.addEventListener("WeixinJSBridgeReady", function () {
video.play()
}, false)
点击播放时,视频区域会出现白屏
- 给
video
添加一个背景图片,最好和视频的封面图(video
的poster
属性)一致。
.video {
...;
background-image: url('https://xxx.png');
}
原生的 UI
样式太丑,需要弃掉并按 UI
设计重新写
- 去掉
video
标签的controls
属性,通过一个遮罩将操作的按钮盖在视频UI
设计的对应区域是,并给对应的元素绑定对应操作的事件即可。以播放暂停为例:
----- vue html -----
<div v-if="isPaused && !videoLoading" class="video-wrapper" @click="videoPlayer">
<img class="play-img" src="https://xxx.png" alt="" />
</div>
----- vue js -----
mounted() {
videoDom.addEventListener('canplay', this.canPlayVideo);
+ videoDom.addEventListener('play', this.videoEvent);
+ videoDom.addEventListener('pause', this.videoEvent);
},
methods: {
videoEvent() {
if (this.$refs?.videoRef?.paused) {
this.isPaused = true;
} else {
this.videoLoading = false;
this.isPaused = false;
}
},
// 点击遮罩的播放按钮
videoPlayer() {
if (this.videoLoading) return;
if (this.$refs?.videoRef?.paused) {
this.isPaused = false;
this.$refs.videoRef.play();
} else {
this.isPaused = true;
this.$refs.videoRef.pause();
}
},
}
- 当然,除了上面这些,如果涉及到切换
tab
、后台运行等情况也是需要考虑的。
感悟
- 大多数遇到的问题,我们都可以通过曲线救国的方式去解决,不要一开始就去死磕一个方向走进误区;
- 通过查阅官方文档、标准等去了解,有时候比直接找一些随便搬运的博客有效;
- 有兴趣的小伙伴可以自己完全自定义实现一个
video
的播放器。
参考链接
- w3c 事件 Media 事件
- h5 video方法,事件,属性详解
往期精彩
- 磕磕绊绊的 4 年前端er,一次含泪总结
- 前端还不会 Nginx 吗?快来学起来
- VS Code 提升开发效率、质量以及编码体验指南
- 金九前端面试总结!
- 从0搭建Vite + Vue3 + Element-Plus + Vue-Router + ESLint + husky + lint-staged
- 「前端进阶」JavaScript手写方法/使用技巧自查
- 公众号打开小程序最佳解决方案(Vue)
- Axios你可能不知道使用方式
「点赞、收藏和评论」
❤️关注+点赞收藏+评论+分享❤️,手留余香,谢谢????大家。
推荐阅读