移动端video标签的坑

544 阅读4分钟

video标签简介

html5中的video的标签,使得页面中使用视频变得简单了很多,与引入图片的方式类似,我们使用video标签指定src属性即可引入视频。

video用法

<video src="test.mp4"></video>

video常见属性

video标签有一些常见的属性。

常见属性属性值属性描述
src绝对值或者相对值视频地址
poster绝对值或者相对值视频播放前的默认封面
autoplay‘’或者autoplay自动播放
controls‘’或者controls显示组件
preload‘’或none或metadata或auto规定加载视频的方式
looploop播放完成后是否循环播放
height百分比,像素等播放器的高度
width百分比,像素等播放器的宽度

属性的兼容性和值的选择

poster属性

按照html5的标准,支持video标签的浏览器,如果poster没有设定任何值,那么会默认将视频的第一帧作为poster封面,但是大多数浏览器并没有取第一帧作为poster封面(ios下可以)。最好给poster设置一个默认值或者可以通过后端截取第一帧的形式传递给前端作为poster。使用poster属性设置封面可能会造成封面图片按照播放器的大小拉伸等情况,这时候我们需要指定对应的css属性。

video {
  object-fit: cover;
}

使用这种方式,也可以保证视频不至于按照播放器的尺寸进行拉伸等。

设置视频的默认封面,除了指定poster值以外,也可以通过css的background属性来设置,使用css设置的好处在于不会出现封面图片的比例失调等情况。

video {
  background-image: url('test.jpg');
  background-color: transparent;
  background-repeat: no-repeat;
  background-size: 100% auto;
  -webkit-background-size:cover;
  -moz-background-size:cover;
  -o-background-size:cover;
  background-size:cover;
}

如果确实想使用视频的第一帧作为视频的封面,还有一种不太完美的方案。视频默认没有进入到第一帧画面,我们可以考虑手动播放再停止,这样对于很多android端的浏览器可以看到效果,这里有一个重要的前提,浏览器只有在用户至少有一次交互后,play()、pause()等方法才可以生效。因此还是需要给document绑定事件。

let video = document.getElementById('xxx');
document.addEventlistener('touchstart', function() {
  video.play();
  video.pause();
});

autoplay属性

autoplay属性用来告知浏览器自动播放视频,但是各手机端的浏览器出于安全等的考虑,并不会在页面加载完成后开始自动播放。同时,我们试图通过js来控制播放play()也是失效的。浏览器必须确定用户已经和页面发生交互以后,play()方法才可以生效。

let video = document.getElementById('xxx');
document.addEventlistener('touchstart', function() {
  video.play();
});

preload属性

preload有这么几个值,空值、none、metadata、auto,对于控制,会默认赋值auto,会尽可能的加载整个视频,none则不会加载任何数据,metadata会加载必备的视频数据,例如视频的实际宽高,时长等。我们可以根据需要选择合适的值。

属性值值描述
空值默认相当于auto,加载整个视频
none不加载任何数据
metadata加载视频相关的一些元数据
auto加载整个视频

视频的宽高值

我们在css中或者直接指定的height和width实际为video标签也就是视频播放器的高宽,而视频的实际宽高是通过video的videoHeight和videoWidth获取。

var video = document.getElementById('xxx');
var videoHeight = video.videoHeight;
var videoWidth = video.videoWidth;

看起来是不是挺简单,但是实际上却有很多浏览器获取不到这个值,测试了下,在UC、IOS下是可以访问到的,而在好多android浏览器下无法获取,读取到的值为undefined。假如我们像让视频100%宽度,高度自适应,我们直接设置css属性即可。

video {
  width: 100%;
  height: auto;
}

如果我们不想通过css来控制,通过js来让视频100%显示,那么我们就需要获取videoWidth和videoHeight来获取,理论上,我们在loadedmetadata事件执行回调中可以拿到这个值,等比缩放就可以了,如果获取不到,我们使用css控制视频居中显示。

var video = document.getElementById('xxx');
video.addEventlistener('loadedmetadata', function(event){
	var videoHeight = event.target.videoHeight;
	if (videoHeight) {
		// 调整播放器的宽高,以保证和视频实际宽高一致。
	} else {
		// 设置object-fit属性值为cover
	}
});

使用video标签的时候,videoWidth和videoHeight获取有兼容问题,我们可以通过css来兼容处理,保证最好的视觉显示,可以通过100%来自动比例缩放,而如果播放器固定大小时,我们通过object-fit控制视频居中显示。

android端video播放后层级提高

移动端使用video引入视频后,当播放时,video会默认将层级调整至最高,从而覆盖别的高层级。
这个问题暂时还没有很好的解决方案。