HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>视频播放UI</title>
<link rel="stylesheet" href="main.css">
<script src="main.js"></script>
</head>
<body>
<video src="云樱和元芳.mp4" class="mianVideo"></video>
</body>
</html>
CSS:文章来源:https://www.toymoban.com/news/detail-508062.html
* {
margin: 0;
padding: 0;
}
body {
height: 2000px;
}
/* 去掉全屏时显示的自带控制条 */
.mianVideo::-webkit-media-controls {
display: none !important;
}
.mianVideo {
width: 700px;
width: 1000px;
height: auto;
position: absolute;
top: 100px;
left: 30px;
}
.cloudVideoDiv {
position: absolute;
user-select: none;
overflow: hidden;
}
.controlPanelDiv {
position: absolute;
background-color: rgba(255, 252, 252, 0.5);
border-radius: 5px;
display: none;
height: 30px;
bottom: 0px;
left: 10px;
animation: controlPanelDiv 0.5s forwards;
opacity: 0;
}
@keyframes controlPanelDiv {
0% {}
100% {
bottom: 10px;
opacity: 1;
}
}
.progressBar {
position: absolute;
opacity: 0.8;
cursor: pointer;
}
.progressNum {
position: absolute;
right: 160px;
bottom: 4px;
}
.fullScreen {
position: absolute;
right: 5px;
bottom: 4px;
cursor: pointer;
}
.controlSound {
position: absolute;
right: 38px;
bottom: 0px;
cursor: pointer;
}
.controlSoundProgress {
position: absolute;
right: 35px;
bottom: 35px;
width: 35px;
height: 110px;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 3px;
display: none;
text-align: center;
}
.controlSoundProgress input {
width: 80px;
height: 6px;
transform-origin: 0% 100%;
transform: rotate(-90deg);
position: absolute;
top: 90%;
left: 60%;
}
.playAndPause {
position: absolute;
bottom: -2px;
left: 8px;
cursor: pointer;
}
.videoSpeed {
width: 52px;
position: absolute;
bottom: 4px;
right: 90px;
cursor: pointer;
font-weight: 600;
}
.videoSpeedList {
width: 60px;
position: absolute;
bottom: 35px;
right: 95px;
cursor: pointer;
font-weight: 600;
list-style: none;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 3px;
display: none;
}
.videoSpeedList li {
padding: 5px;
border-bottom: 1px solid black;
text-align: center;
}
.videoSpeedList li:hover {
background-color: rgba(255, 255, 255, 0.4);
}
.videoSpeedList li.select {
background-color: rgba(255, 255, 255, 0.6);
}
.customizePlaybackRate {
padding: 1px !important;
border: none !important;
}
.customizePlaybackRate input {
padding: 3px !important;
width: 95%;
height: 100%;
background-color: transparent;
border: none;
text-align: center;
font-weight: 600;
}
.customizePlaybackRate input::-webkit-input-placeholder {
color: black;
}
.customizePlaybackRate input:focus {
outline: none;
}
.replay {
cursor: pointer;
position: absolute;
top: 50%;
left: 43%;
transform: translate(-50%, -50%);
}
.loop {
cursor: pointer;
position: absolute;
top: 50%;
left: 57%;
transform: translate(-50%, -50%);
}
.setUp {
position: absolute;
bottom: 4px;
right: 73px;
cursor: pointer;
}
JS:(暂时没做优化什么的)文章来源地址https://www.toymoban.com/news/detail-508062.html
window.onload = function () {
const mianVideo = document.querySelector('.mianVideo');
// 视频的元数据加载后触发
mianVideo.addEventListener('loadedmetadata', () => {
const body = document.body;
const mianVideoPlaceAndSize = mianVideo.getBoundingClientRect();
// 获取mianVideo的zIndex
const mianVideoZIndex = getComputedStyle(mianVideo, null).zIndex;
// 创建视频上方的遮盖层
const cloudVideoDiv = document.createElement('div');
cloudVideoDiv.classList.add('cloudVideoDiv');
cloudVideoDiv.style.width = mianVideoPlaceAndSize.width + 'px';
cloudVideoDiv.style.height = mianVideoPlaceAndSize.height + 'px';
cloudVideoDiv.style.top = mianVideo.offsetTop + 'px';
cloudVideoDiv.style.left = mianVideo.offsetLeft + 'px';
// 使遮盖层的zIndex永远比视频大
mianVideoZIndex == 'auto' ? cloudVideoDiv.style.zIndex = '1' : cloudVideoDiv.style.zIndex =
parseInt(mianVideoZIndex) + 1;
body.appendChild(cloudVideoDiv);
// 创建控制面板
const controlPanelDiv = document.createElement('div');
controlPanelDiv.classList.add('controlPanelDiv');
controlPanelDiv.style.width = mianVideoPlaceAndSize.width - 20 + 'px';
cloudVideoDiv.appendChild(controlPanelDiv);
// 控制面板的显示和隐藏
cloudVideoDiv.addEventListener('mouseenter', () => controlPanelDiv.style.display = 'block');
cloudVideoDiv.addEventListener('mouseleave', () => controlPanelDiv.style.display = 'none');
// 创建进度条
const progressBar = document.createElement('input');
progressBar.setAttribute('type', 'range');
progressBar.setAttribute('min', 0);
progressBar.setAttribute('max', mianVideo.duration);
progressBar.value = 0;
progressBar.classList.add('progressBar');
progressBar.style.width = mianVideoPlaceAndSize.width - 340 + 'px';
progressBar.style.bottom = '5px';
progressBar.style.left = '40px';
controlPanelDiv.appendChild(progressBar);
// 为进度条添加事件
progressBar.addEventListener('input', () => {
mianVideo.currentTime = progressBar.value;
mianVideo.play();
cloudVideoDiv.style.backgroundColor = 'rgba(0, 0, 0, 0)';
document.querySelector('.replay').style.display = 'none';
document.querySelector('.loop').style.display = 'none';
});
// 为视频添加事件
mianVideo.addEventListener('timeupdate', () => {
progressBar.value = mianVideo.currentTime;
const currentNum = document.querySelector('.currentNum');
currentNum.innerHTML = formatTime(mianVideo.currentTime);
});
// 创建展示进度的数字
controlPanelDiv.insertAdjacentHTML('beforeend', `
<div class="progressNum">
<span class="currentNum">00:00</span> /
<span>${formatTime(mianVideo.duration)}</span>
</div>
`);
// 创建全屏按钮
controlPanelDiv.insertAdjacentHTML('beforeend', `
<svg class="fullScreen" width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M33 6H42V15" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
<path d="M42 33V42H33" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
<path d="M15 42H6V33" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
<path d="M6 15V6H15" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
</svg>`);
const fullScreen = document.querySelector('.fullScreen');
fullScreen.addEventListener('click', () => {
// 点击全屏
if (mianVideo.requestFullscreen) {
mianVideo.requestFullscreen();
} else if (mianVideo.webkitRequestFullscreen) {
mianVideo.webkitRequestFullscreen();
} else if (mianVideo.mozRequestFullScreen) {
mianVideo.mozRequestFullScreen();
} else if (mianVideo.msRequestFullscreen) {
mianVideo.msRequestFullscreen();
}
})
// 创建声音按钮
controlPanelDiv.insertAdjacentHTML('beforeend', `<div class="controlSound"></div>`);
const controlSound = document.querySelector('.controlSound');
const openSoundSvg = `<svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M24 6V42C17 42 11.7985 32.8391 11.7985 32.8391H6C4.89543 32.8391 4 31.9437 4 30.8391V17.0108C4 15.9062 4.89543 15.0108 6 15.0108H11.7985C11.7985 15.0108 17 6 24 6Z" fill="none" stroke="#000000" stroke-width="4" stroke-linejoin="round"/>
<path d="M32 15L32 15C32.6232 15.5565 33.1881 16.1797 33.6841 16.8588C35.1387 18.8504 36 21.3223 36 24C36 26.6545 35.1535 29.1067 33.7218 31.0893C33.2168 31.7885 32.6391 32.4293 32 33" stroke="#000000" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M34.2358 41.1857C40.0835 37.6953 43.9999 31.305 43.9999 24C43.9999 16.8085 40.2042 10.5035 34.507 6.97906" stroke="#000000" stroke-width="4" stroke-linecap="round"/>
</svg>`;
const closeSoundSvg =
`<svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M40.7344 20.2858L32.2491 28.7711" stroke="#000000" stroke-width="4" stroke-linecap="square" stroke-linejoin="miter"/><path d="M32.25 20.2858L40.7353 28.7711" stroke="#000000" stroke-width="4" stroke-linecap="square" stroke-linejoin="miter"/><path d="M24 6V42C17 42 11.7985 32.8391 11.7985 32.8391H6C4.89543 32.8391 4 31.9437 4 30.8391V17.0108C4 15.9062 4.89543 15.0108 6 15.0108H11.7985C11.7985 15.0108 17 6 24 6Z" fill="none" stroke="#000000" stroke-width="4" stroke-linejoin="miter"/></svg>`;
controlSound.innerHTML = openSoundSvg;
controlSound.addEventListener('click', () => {
const val = controlSoundProgress.querySelector('input').value;
if (val === '0') {
controlSound.innerHTML = openSoundSvg;
controlSoundProgress.querySelector('input').value = '100';
mianVideo.volume = 1;
} else {
controlSound.innerHTML = closeSoundSvg;
controlSoundProgress.querySelector('input').value = '0';
mianVideo.volume = 0;
}
controlSoundProgressValue.innerHTML = controlSoundProgress.querySelector('input').value;
});
// 创建声音控制条
controlPanelDiv.insertAdjacentHTML('beforeend', `
<div class="controlSoundProgress">
<div class="controlSoundProgressValue">100</div>
<input type="range" min="0" max="100" value="100">
</div>`);
// 声音控制条的显示和隐藏
const controlSoundProgress = document.querySelector('.controlSoundProgress');
const controlSoundProgressValue = document.querySelector('.controlSoundProgressValue');
controlSound.addEventListener('mouseenter', () => controlSoundProgress.style.display = 'block');
controlSoundProgress.addEventListener('mouseleave', () => controlSoundProgress.style.display =
'none');
controlSoundProgress.addEventListener('input', () => {
const val = controlSoundProgress.querySelector('input').value;
val <= 0 ? controlSound.innerHTML = closeSoundSvg : controlSound.innerHTML =
openSoundSvg;
mianVideo.volume = val / 100;
controlSoundProgressValue.innerHTML = `${val}`;
});
// 创建播放|暂停按钮
controlPanelDiv.insertAdjacentHTML('beforeend', `<div class="playAndPause"></div>`);
const playAndPause = document.querySelector('.playAndPause');
const playSvg =
`<svg width="25" height="25" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M16 12V36" stroke="#000000" stroke-width="4" stroke-linecap="square" stroke-linejoin="miter"/><path d="M32 12V36" stroke="#000000" stroke-width="4" stroke-linecap="square" stroke-linejoin="miter"/></svg>`;
const pauseSvg =
`<?xml version="1.0" encoding="UTF-8"?><svg width="25" height="25" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M15 24V11.8756L25.5 17.9378L36 24L25.5 30.0622L15 36.1244V24Z" fill="#000000" stroke="#000000" stroke-width="4" stroke-linejoin="miter"/></svg>`;
playAndPause.innerHTML = playSvg;
playAndPause.addEventListener('click', () => {
if (mianVideo.paused) {
mianVideo.play();
playAndPause.innerHTML = playSvg;
} else {
mianVideo.pause();
playAndPause.innerHTML = pauseSvg;
}
});
// 创建倍速按钮
controlPanelDiv.insertAdjacentHTML('beforeend', `<div class="videoSpeed">倍速</div>`);
const videoSpeed = document.querySelector('.videoSpeed');
controlPanelDiv.insertAdjacentHTML('beforeend', `
<ul class="videoSpeedList">
<li data-playbackRate="0.5">0.5×</li>
<li data-playbackRate="0.75">0.75×</li>
<li data-playbackRate="1" class="select">1×</li>
<li data-playbackRate="1.25">1.25×</li>
<li data-playbackRate="1.5">1.5×</li>
<li data-playbackRate="2">2×</li>
<li class="customizePlaybackRate">
<input type="number" min="0" max="15" placeholder="自定义">
</li>
</ul>`);
const videoSpeedList = document.querySelector('.videoSpeedList');
const videoSpeedListLi = document.querySelectorAll('.videoSpeedList li[data-playbackRate]');
const customizePlaybackRate = document.querySelector('.customizePlaybackRate');
const customizePlaybackRateInput = document.querySelector('.customizePlaybackRate input');
videoSpeed.addEventListener('mouseenter', () => videoSpeedList.style.display = 'block')
videoSpeedList.addEventListener('mouseleave', () => videoSpeedList.style.display = 'none');
videoSpeedListLi.forEach(item => {
item.addEventListener('click', () => {
videoSpeedListLi.forEach(item => item.classList.remove('select'));
customizePlaybackRate.classList.remove('select')
item.classList.add('select')
mianVideo.playbackRate = item.getAttribute('data-playbackRate');
});
});
customizePlaybackRateInput.addEventListener('input', () => {
videoSpeedListLi.forEach(item => item.classList.remove('select'));
customizePlaybackRate.classList.add('select')
mianVideo.playbackRate = customizePlaybackRateInput.value;
if (!customizePlaybackRateInput.value) mianVideo.playbackRate = 1;
});
// 创建重新播放按钮
const replaySvg =
'<svg class="replay" width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M21 24V18L26 21L31 24L26 27L21 30V24Z" fill="none" stroke="#ffffff" stroke-width="3" stroke-linejoin="round"/><path d="M11.2721 36.7279C14.5294 39.9853 19.0294 42 24 42C33.9411 42 42 33.9411 42 24C42 14.0589 33.9411 6 24 6C19.0294 6 14.5294 8.01472 11.2721 11.2721C9.6141 12.9301 6 17 6 17" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M6 9V17H14" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>'
// 创建循环播放按钮
const loopSvg =
'<svg class="loop" width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M4 25C4 18.3502 9.39624 13 16 13L44 13" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M38 7L44 13L38 19" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M44 23C44 29.6498 38.6038 35 32 35H4" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 41L4 35L10 29" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>'
mianVideo.addEventListener('ended', () => {
cloudVideoDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';
if (document.querySelector('.replay')) {
document.querySelector('.replay').style.display = 'block';
document.querySelector('.loop').style.display = 'block';
} else {
cloudVideoDiv.insertAdjacentHTML('beforeend', replaySvg);
cloudVideoDiv.insertAdjacentHTML('beforeend', loopSvg);
}
const replay = document.querySelector('.replay');
const loop = document.querySelector('.loop');
function endedClick() {
mianVideo.currentTime = 0;
mianVideo.play();
cloudVideoDiv.style.backgroundColor = 'rgba(0, 0, 0, 0)';
replay.style.display = 'none';
loop.style.display = 'none';
}
replay.addEventListener('click', endedClick);
loop.addEventListener('click', () => {
mianVideo.loop = true;
endedClick();
});
});
// 创建设置按钮
const setUpSvg = '<svg class="setUp" width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M18.2838 43.1712C14.9327 42.1735 11.9498 40.3212 9.58787 37.8669C10.469 36.8226 11 35.4733 11 34C11 30.6863 8.31371 28 5 28C4.79955 28 4.60139 28.0098 4.40599 28.029C4.13979 26.7276 4 25.3801 4 24C4 21.9094 4.32077 19.8937 4.91579 17.9994C4.94381 17.9998 4.97188 18 5 18C8.31371 18 11 15.3137 11 12C11 11.0487 10.7786 10.1491 10.3846 9.34999C12.6975 7.19937 15.5205 5.5899 18.6521 4.72302C19.6444 6.66807 21.6667 8.00001 24 8.00001C26.3333 8.00001 28.3556 6.66807 29.3479 4.72302C32.4795 5.5899 35.3025 7.19937 37.6154 9.34999C37.2214 10.1491 37 11.0487 37 12C37 15.3137 39.6863 18 43 18C43.0281 18 43.0562 17.9998 43.0842 17.9994C43.6792 19.8937 44 21.9094 44 24C44 25.3801 43.8602 26.7276 43.594 28.029C43.3986 28.0098 43.2005 28 43 28C39.6863 28 37 30.6863 37 34C37 35.4733 37.531 36.8226 38.4121 37.8669C36.0502 40.3212 33.0673 42.1735 29.7162 43.1712C28.9428 40.7518 26.676 39 24 39C21.324 39 19.0572 40.7518 18.2838 43.1712Z" fill="none" stroke="#000000" stroke-width="4" stroke-linejoin="round"/><path d="M24 31C27.866 31 31 27.866 31 24C31 20.134 27.866 17 24 17C20.134 17 17 20.134 17 24C17 27.866 20.134 31 24 31Z" fill="none" stroke="#000000" stroke-width="4" stroke-linejoin="round"/></svg>'
controlPanelDiv.insertAdjacentHTML('beforeend', setUpSvg);
});
// 格式化时间
function formatTime(t) {
let m = parseInt(t % 3600 / 60);
m = m < 10 ? '0' + m : m;
let s = parseInt(t % 60);
s = s < 10 ? '0' + s : s;
return m + ':' + s;
}
}
到了这里,关于JS控制视频播放、暂停、倍速、音量等功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!