最近遇到的需求就是重新video标签的控制栏的样式,包括进度条、音量、倍速、全屏等样式,在正常状态下,可以将原生样式隐藏掉自定义新的控制栏元素定位上去,但是全屏后样式失效,出现的还是原生的控制栏。
未全屏状态下自定义控制栏的组件样式。(进度条、音量、倍速等组件全部已经重写)
全屏后,发现控制栏已经变成原生的样式
具体是f12 可以看出,自定义的组件其实还在原先的位置,全屏后的video新增的伪类和样式无法修改,
就只能改变策略,将video的父级容器全屏,再将video宽高设置100%,进而达到全屏效果,再次基础上叠加需要的控制栏的元素按钮等,实现自定义控制栏。
1. 页面结构
其中全屏实际作用于id="video-box"这个div,通过按钮控制全屏,将外层的视频容器全屏,再将内部的video元素修改宽高,进而达到全屏效果,再次基础上可以叠加我们想要的操作栏和操作按钮
<div id="video-box">
<button class="btn-full" @click="screen">{{ isFull ? '退出全屏' : '全屏' }}</button>
<button class="btn-shot" @click="screenshot">截图</button>
<video ref="video" :class="{'video': true,'full':isFull}" :src="srcVideo" controls="controls" loop/>
下面是两个变量
data() {
return {
srcVideo: require('@/assets/video/videoDemo.mp4'),
isFull: false, // 是否全屏
2. 全屏方法
// 全屏
screen() {
const element = document.getElementById("video-box");
this.isFull = !this.fullscreen;
if (this.fullscreen) {
console.log('exit');
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else {
console.log('full');
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullscreen) {
// IE11
element.msRequestFullscreen();
this.fullscreen = !this.fullscreen;
3. 截图方法
// 截图
screenshot() {
const video = this.$refs.video;
const canvas = document.createElement("canvas");
const tempLink = document.createElement('a');
const ctx = canvas.getContext("2d");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
tempLink.href = canvas.toDataURL();
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank');
} else {
tempLink.setAttribute('download', '下载.png');//自定义下载的名字,需要加上.png的后缀
document.body.appendChild(tempLink);
tempLink.click();
setTimeout(function () {//移除a标签
document.body.removeChild(tempLink);
}, 100)
4. 样式代码
<style>
/*父级容器*/
#video-box {
position: relative;
background: antiquewhite;
border: 1px solid red;
/*初始化状态video样式*/
.video {
object-fit: cover;
width: 700px;
/*全屏状态下video样式*/
.full {
width: 100%;
height: 100%;
/*隐藏全屏按钮*/
video::-webkit-media-controls-fullscreen-button {
display: none;
.btn-full {
position: absolute;
bottom: 40px;
right: 40%;
z-index: 20;
.btn-shot {
position: absolute;
bottom: 40px;
right: 45%;
z-index: 20;
button {
background: transparent;
color: yellow;
border: none;
font-weight: bold;
box-shadow: 1px 1px 5px inset #fff;
border-radius: 2px;
button:hover {
cursor: pointer;
box-shadow: 1px 1px 5px #fff;
</style>
5. 效果截图
初始化状态下展示效果
点击全屏后的展示效果
点击截图效果
6. 附上完整代码
<template>
<div id="video-box">
<button class="btn-full" @click="screen">{{ isFull ? '退出全屏' : '全屏' }}</button>
<button class="btn-shot" @click="screenshot">截图</button>
<video ref="video" :class="{'video': true,'full':isFull}" :src="srcVideo" controls="controls" loop/>
</template>
<script>
export default {
name: "originVideo",
data() {
return {
srcVideo: require('@/assets/video/videoDemo.mp4'),
isFull: false, // 是否全屏
methods: {
// 全屏
screen() {
const element = document.getElementById("video-box");
this.isFull = !this.fullscreen;
if (this.fullscreen) {
console.log('exit');
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else {
console.log('full');
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullscreen) {
// IE11
element.msRequestFullscreen();
this.fullscreen = !this.fullscreen;
// 截图
screenshot() {
const video = this.$refs.video;
const canvas = document.createElement("canvas");
const tempLink = document.createElement('a');
const ctx = canvas.getContext("2d");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
tempLink.href = canvas.toDataURL();
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank');
} else {
tempLink.setAttribute('download', '下载.png');//自定义下载的名字,需要加上.png的后缀
document.body.appendChild(tempLink);
tempLink.click();
setTimeout(function () {//移除a标签
document.body.removeChild(tempLink);
}, 100)
</script>
<style>
/*父级容器*/
#video-box {
position: relative;
background: antiquewhite;
border: 1px solid red;
/*初始化状态video样式*/
.video {
object-fit: cover;
width: 700px;
/*全屏状态下video样式*/
.full {
width: 100%;
height: 100%;
/*隐藏全屏按钮*/
video::-webkit-media-controls-fullscreen-button {
display: none;
.btn-full {
position: absolute;
bottom: 40px;
right: 40%;
z-index: 20;
.btn-shot {
position: absolute;
bottom: 40px;
right: 45%;
z-index: 20;
button {
background: transparent;
color: yellow;
border: none;
font-weight: bold;
box-shadow: 1px 1px 5px inset #fff;
border-radius: 2px;
button:hover {
cursor: pointer;
box-shadow: 1px 1px 5px #fff;
</style>
一般情况下,video的样式可以满足正常的需求了,但是有时候仍然会要求修改video的样式,下面就是记录一下自定义video样式的代码。
它可以实现进度的拖拽,音量的拖拽和静音,双击全屏功能的实现等
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<meta...
本文介绍了自定义video标签控制栏的必要性和实现方法。原生控制栏存在样式不可定制、功能局限和移动端兼容性差等问题。作者基于React实现了一个功能丰富的自定义控制栏,包含画中画、静音、全屏、进度条等控件,并解决了自动播放限制等技术难点。文章详细展示了代码实现,包括事件处理、状态管理和跨浏览器兼容方案。最后强调浏览器对自动播放的严格限制,建议开发者遵循用户交互原则,避免在无交互情况下强制视频播放。该组件实现了统一风格和功能扩展,为视频播放开发提供了实用参考。
我们自定义实现控制条,所以video不要使用controls属性
从其他网站视频播放,一般都是要自己实现控制条来达到我们想要的效果,使用video提供的控制条相关属性就很难修改,也...
vue3在video.js播放器控制栏增加一个自定义按钮;vue3怎么在video.js播放器控制栏增加一个自定义按钮;video怎么自定义控制按钮
object-fit 一般用于 img 和 video 标签,一般可以对这些元素进行保留原始比例的剪切、缩放或者直接进行拉伸等。video标签默认不是铺满的,即使手动设置宽高100%也不会生效,所以当需要video铺满div时,需要加上一个css样式。object-fit 属性指定元素的内容应该如何去适应指定容器的高度与宽度。关键是这个“object-fit: fill”,这样就可以解决了!fill: 默认,不保证保持原有的比例,内容拉伸填充整个内容容器。
通过设置 playsinline 有的设备会不生效,可以设置 webkit-playsinline。两个可以同时设置,保证包含所有情况。另外,验证时,发现点击视频的时候会出现切换画中画的按钮,实际需求是不需要的。其中介绍了playsinline属性可以设置视频播放的时候不直接全屏播放。但是每次进入页面,视频加载完成播放的时候,会直接进入全屏模式播放。同过mdn查询video标签的参数发现并没有相关介绍。混合开发, 原生使用webview内嵌h5页面。转移思路,查询多媒体相关的设置。