在 HTML5 视频中突出显示播放器搜索栏
Posted
技术标签:
【中文标题】在 HTML5 视频中突出显示播放器搜索栏【英文标题】:Highlight player seekbar in HTML5 video 【发布时间】:2020-06-29 02:43:27 【问题描述】:我为我的 html5 视频播放器定制了一个搜索栏。但我需要突出显示搜索栏的一些预定义部分,例如秒 2-5 和 7-8。我该怎么做?
基本上,我需要它是这样的:
到目前为止,这是我的简单代码:
<!DOCTYPE html>
<html>
<head>
<style>
.body
background-color:black;
.video-player
position: relative;
width: 66%;
height: 66%;
.video-player img
width: 100%;
height: 100%;
.video-player video
position: fixed;
top: 0;
left: 0;
min-width: 66%;
min-height: 66%;
width: auto;
height: auto;
z-index: -100;
background-repeat: no-repeat;
.video-player .controls
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
.video-player .controls .progress-bar
position: absolute;
margin-left: 28%;
bottom: 10%;
color: orange;
font-size: 12px;
width: 40%;
height: 8%;
border: none;
background: #434343;
border-radius: 9px;
vertical-align: middle;
cursor: pointer;
.video-player .controls progress::-moz-progress-bar
color: orange;
background: #434343;
.video-player .controls progress[value]::-webkit-progress-bar
background-color: #434343;
border-radius: 2px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
.video-player .controls progress[value]::-webkit-progress-value
background-color: orange;
video#backgroundvid
position: absolute;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -100;
background-repeat: no-repeat;
</style>
</head>
<body>
<div class="video-player">
<video preload="auto" autoplay loop id="backgroundvid">
<source src="mov_bbb.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
<img src="top2.png" style="object-fit:cover" id="backgroundvid">
<div class="controls">
<progress class="progress-bar" style="object-fit:cover; z-index=10000" min="0" max="100" value="0">0% played</progress>
</div>
</div>
<script>
const player = document.querySelector('.video-player');
const video = player.querySelector('video');
const progressBar = player.querySelector('.progress-bar');
video.addEventListener('timeupdate', updateProgressBar, false);
progressBar.addEventListener('click', seek);
function updateProgressBar()
var percentage = Math.floor((100 / video.duration) * video.currentTime);
progressBar.value = percentage;
progressBar.innerHTML = percentage + '% played';
function seek(e)
let percent = e.offsetX / this.offsetWidth;
video.currentTime = percent * video.duration;
e.target.value = Math.floor(percent / 100);
e.target.innerHTML = progressBar.value + '% played';
</script>
</body>
</html>
【问题讨论】:
【参考方案1】:您可以使用将叠加在进度条顶部的画布,
然后您只需在此画布中绘制标记。
只需对 html 做些微改动(在进度条上添加一个 id id="progress-bar"
):
<progress id="progress-bar" class="progress-bar" style="object-fit:cover; z-index=10000" min="0" max="100" value="0">0% played</progress>
添加 CSS 以设置画布的样式(与进度条相同的 CSS 属性)
#markers
position: absolute;
bottom: 10%;
margin-left: 28%;
border-radius: 9px;
pointer-events: none;
注意pointer-events: none;
,如果不放,就无法控制进度条。
因此,创建和插入画布的 javascript,然后在其上放置标记。
// We need the metadata 'duration', so we wrap the code in an event listener to be sure we execute our code when the metadata is loaded
video.addEventListener('loadedmetadata', function ()
// Get the dimension of the progress-bar
const progressbar = document.getElementById('progress-bar');
const widthProgressBar = window.getComputedStyle(progressbar, null).getPropertyValue("width");
const heightProgressBar = window.getComputedStyle(progressbar, null).getPropertyValue("height");
// Create the canvas
const canvas = document.createElement('canvas');
const w = canvas.width = parseFloat(widthProgressBar);
const h = canvas.height = parseFloat(heightProgressBar);
canvas.id = 'markers';
const progressBar = document.getElementById("progress-bar");
// Insert the canvas in the DOM
progressBar.parentNode.insertBefore(canvas, progressBar.nextSibling)
// Define the context
const ctx = canvas.getContext('2d');
// Calcul how many px will represent 1s
const videoDuration = video.duration;
const ratioPxBySeconds = parseFloat(w) / videoDuration;
// Define the markers
const markers =
'marker1': [2, 5],
'marker2': [7, 8]
;
// Function to draw the markers
function setMarkers(markers, ratioPxSec, height)
for (marker in markers)
let x = markers[marker][0] * ratioPxSec; // Start x position of the marker
let y = 0; // Start y position of the marker
let w = (markers[marker][1] - markers[marker][0]) * ratioPxSec; // Width of the marker
let h = parseFloat(height); // Height of the marker
ctx.fillStyle = "#7f3302"; // Set the color of the marker
ctx.fillRect(x, y, w, h); // Draw a rectangle
setMarkers(markers, ratioPxBySeconds, h); // Call the function
);
const player = document.querySelector('.video-player');
const video = player.querySelector('video');
const progressBar = player.querySelector('.progress-bar');
video.addEventListener('timeupdate', updateProgressBar, false);
progressBar.addEventListener('click', seek);
function updateProgressBar()
var percentage = Math.floor((100 / video.duration) * video.currentTime);
progressBar.value = percentage;
progressBar.innerHTML = percentage + '% played';
function seek(e)
let percent = e.offsetX / this.offsetWidth;
video.currentTime = percent * video.duration;
e.target.value = Math.floor(percent / 100);
e.target.innerHTML = progressBar.value + '% played';
// We need the metadata 'duration', so we wrap the code in an event listener to be sure we execute our code when the metadata is loaded
video.addEventListener('loadedmetadata', function()
// Get the dimension of the progress-bar
const progressbar = document.getElementById('progress-bar');
const widthProgressBar = window.getComputedStyle(progressbar, null).getPropertyValue("width");
const heightProgressBar = window.getComputedStyle(progressbar, null).getPropertyValue("height");
// Create the canvas
const canvas = document.createElement('canvas');
const w = canvas.width = parseFloat(widthProgressBar);
const h = canvas.height = parseFloat(heightProgressBar);
canvas.id = 'markers';
const progressBar = document.getElementById("progress-bar");
// Insert the canvas in the DOM
progressBar.parentNode.insertBefore(canvas, progressBar.nextSibling)
// Define the context
const ctx = canvas.getContext('2d');
// Calcul how many px will represent 1s
const videoDuration = video.duration;
const ratioPxBySeconds = parseFloat(w) / videoDuration;
// Define the markers
const markers =
'marker1': [2, 5],
'marker2': [7, 8]
;
// Function to draw the markers
function setMarkers(markers, ratioPxSec, height)
for (marker in markers)
let x = markers[marker][0] * ratioPxSec; // Start x position of the marker
let y = 0; // Start y position of the marker
let w = (markers[marker][1] - markers[marker][0]) * ratioPxSec; // Width of the marker
let h = parseFloat(height); // Height of the marker
ctx.fillStyle = "rgb(127, 51, 2, 0.9)"; // Set the color of the marker
ctx.fillRect(x, y, w, h); // Draw a rectangle
setMarkers(markers, ratioPxBySeconds, h); // Call the function
// Calculate the new dimensions & redraw
function resize()
const progressBar = document.getElementById('progress-bar');
const w = canvas.width = progressBar.clientWidth;
const h = canvas.height = progressBar.clientHeight;
const ratioPxBySeconds = parseFloat(w) / videoDuration;
setMarkers(markers, ratioPxBySeconds, h);
// On page resize, call the resize() function
window.addEventListener("resize", resize, false);
);
body
background-color: black;
.video-player
position: relative;
width: 66%;
height: 66%;
.video-player img
width: 100%;
height: 100%;
.video-player video
position: fixed;
top: 0;
left: 0;
min-width: 66%;
min-height: 66%;
width: auto;
height: auto;
z-index: -100;
background-repeat: no-repeat;
.video-player .controls
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
.video-player .controls .progress-bar
position: absolute;
margin-left: 28%;
bottom: 10%;
color: orange;
font-size: 12px;
width: 40%;
height: 8%;
border: none;
background: #434343;
border-radius: 9px;
vertical-align: middle;
cursor: pointer;
#markers
position: absolute;
bottom: 10%;
margin-left: 28%;
border-radius: 9px;
pointer-events: none;
.video-player .controls progress::-moz-progress-bar
color: orange;
background: #434343;
.video-player .controls progress[value]::-webkit-progress-bar
background-color: #434343;
border-radius: 2px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
.video-player .controls progress[value]::-webkit-progress-value
background-color: orange;
video#backgroundvid
position: absolute;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -100;
background-repeat: no-repeat;
<div class="video-player">
<video preload="auto" autoplay loop id="backgroundvid">
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
<img src="https://i.stack.imgur.com/gmK7P.png" style="object-fit:cover" id="backgroundvid">
<div class="controls">
<progress id="progress-bar" class="progress-bar" style="object-fit:cover; z-index=10000" min="0" max="100" value="0">0% played</progress>
</div>
</div>
编辑:
添加了 resize() 函数以在屏幕调整大小时更新标记
(通常,当您将视频全屏播放时会发生这种情况)
// Calculate the new dimensions & redraw function resize() const progressBar = document.getElementById('progress-bar'); const w = canvas.width = progressBar.clientWidth; const h = canvas.height = progressBar.clientHeight; const ratioPxBySeconds = parseFloat(w) / videoDuration; setMarkers(markers, ratioPxBySeconds, h); // On page resize, call the resize() function window.addEventListener("resize", resize, false);
【讨论】:
我更改了标记填充样式以允许透明度。不透明的矩形隐藏了进度。 谢谢。我得到的有点乱(高亮条有点高):i.stack.imgur.com/WuFbc.jpg 好的,它是 10%,我更改了它并修复了它。谢谢。以上是关于在 HTML5 视频中突出显示播放器搜索栏的主要内容,如果未能解决你的问题,请参考以下文章
Thymeleaf 布局中的 Bootstrap 导航栏突出显示
突出显示在 Android 设置应用程序的搜索结果中找到的菜单项