Html5 Video Custom Additional Seek Bar

How to add a seek slider to html5 video player?

try something like that.

#custom-seekbar span.hover:after{
content: '■';
display:block;
position: absolute;
background-color: red;
color: red;
top: 0;
right: 0;
}
$("#custom-seekbar").hover(function(){
$(this).find("span").addClass("hover");
}, function(){
$(this).find("span").removeClass("hover");
})

var sliderCanMove = false;

$("#custom-seekbar").on("mousedown", function(){
sliderCanMove = true;

});

$(window).on("mousemove", function(e){
if(sliderCanMove){
var offset = $("#custom-seekbar").offset();
var left = ((e.clientX + offset.left));
var totalWidth = $("#custom-seekbar").width();
var percentage = ( left / totalWidth );
var vidTime = vid.duration * percentage;
vid.currentTime = vidTime;
}
});

$(window).on("mouseup", function(){
sliderCanMove = false;
});

updated fiddle here.

HTML5 Video custom additional seek bar

var vid = document.getElementById("video");vid.ontimeupdate = function(){  var percentage = ( vid.currentTime / vid.duration ) * 100;  $("#custom-seekbar span").css("width", percentage+"%");};
$("#custom-seekbar").on("click", function(e){ var offset = $(this).offset(); var left = (e.pageX - offset.left); var totalWidth = $("#custom-seekbar").width(); var percentage = ( left / totalWidth ); var vidTime = vid.duration * percentage; vid.currentTime = vidTime;});//click()
#custom-seekbar{    cursor: pointer;  height: 10px;  margin-bottom: 10px;  outline: thin solid orange;  overflow: hidden;  position: relative;  width: 400px;}#custom-seekbar span{  background-color: orange;  position: absolute;  top: 0;  left: 0;  height: 10px;  width: 0px;}
/* following rule is for hiding Stack Overflow's console */.as-console-wrapper{ display: none !important;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script><div id="custom-seekbar">  <span></span></div><video id="video" width="400" controls autoplay>    <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video>

Re-position HTML5 video seekbar

Have you checked out? MDN: Video player styling basics?

Edit: Here is an example of a progress bar with your overlay. You may need to mess with element positioning, but you should properly nest/scope your elements.

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';}
.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;}
<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" alt="">  <div class="controls">    <progress class="progress-bar" min="0" max="100" value="0">0% played</progress>  </div></div>

Highlight player seekbar in HTML5 video

You can use a canvas that you will superimpose on top of your progress-bar,

Then you will have just to draw the markers in this canvas.

Just making slight changes in the html (adding an id to the progress-bar 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>

Adding the CSS to style place the canvas (same CSS property than your progress-bar)

#markers{
position: absolute;
bottom: 10%;
margin-left: 28%;
border-radius: 9px;
pointer-events: none;
}

Note the pointer-events: none; If you don't put it, you can't have access to the control of your progress-bar.

And so, the javascript to create & insert the canvas, and then place the markers on it.

// 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 loadedvideo.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" alt="" 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>

Create a Seekbar like vimeo video player (HTML5)

I was changing the currentTime according to mousemove.

line.addEventListener("mousemove", function(e) {
if (mouseDown) {
video.currentTime = Number(
e.layerX / (line.clientWidth / 100) * (duration / 100)
).toFixed(1);
}
});

and leaving the width of elapse bar to the currentTime. But I'm reading currentTime in every 1s.

setInterval(function() {
elapsed.style.width = video.currentTime / (duration / 100) + "%";
}, 1000);

That's why it's not responsive. Even if I slide quickly, the width of the elapse bar will only move after another second.

How to implement html5 video custom video progress bar in angular?

I imagine you already have an angular app?

If so:

  1. Create your component
ng g c video

  1. Inside video.component.ts
@Component({
selector: 'app-video',
templateUrl: './video.component.html',
styleUrls: ['./video.component.scss']
})
export class VideoComponent implements OnInit {

video;
videoPlaying:boolean;
percentage;

ngOnInit() {
this.video = document.getElementsByTagName("video")[0];
}

togglevideo(){
if(!this.videoPlaying){
this.video.play();
this.videoPlaying = true;
}else{
this.video.pause();
this.videoPlaying = false;
}
}

onTimeUpdate(){
this.percentage = (this.video.currentTime / this.video.duration) * 100;
}

  1. Inside video.component.css (or .scss)
#container {
margin-top: 15px;
}

#container button{
padding: 15px;
background: black;
color: white;
}
#container .progress-bar {
margin-top: 15px;
width: 100%;
border: 2px solid black;
}
#container .progress-bar span{
height: 5px;
display:block;
background: red;
width: 0%;
transition: width 0.25s ease;
}

#container button:active, #container button:focus{
outline: none;
}

  1. Inside video.component.html
<video (timeupdate)="onTimeUpdate()" width="50%" height="50%">
<source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4">
</video>
<div id="container">
<button (click)="this.togglevideo()">
<i [className]="videoPlaying ? 'fa fa-pause' : 'fa fa-play'" aria-hidden="true"></i>
</button>
<div class="progress-bar">
<span [style.width]="percentage + '%'">

</span>
</div>

</div>

  1. In the place you want to use your component, inside the html file:
<app-video></app-video>

Custom HTML5 video seekbar not working as video progress

I don't use React but you need these fixes:

  • (1) Add an event Listener of "timeupdate" to your video element.

  • (2) Calculate the [video timeline] scrubber's position as:


    seekbarValue = ( (seekbarCurrentTime / seekbarDuration) * seekbarMax );

How to add markers in html5 video player on video progress indication bar?

You are on the right track with calculating the width of the #current-time bar. Outside of the timeupdate listener do the same for each range or marker.

Loop over each position of the marker and calculate the offset of the left property just like you did with the width property. This will give you the position of each marker on the timeline.

Then in the loop create each marker, give it the left property value and add them, for example, to the #seekbar.

// Video and seekbar
const video = document.getElementById('videoplayer');
const seekBar = document.getElementById('seekbar');

// Positions of markers in seconds.
const positions = [3, 6.5, 7];

// Set the markers when we CAN know the duration of the video.
video.addEventListener('loadedmetadata', () => {

// Add each marker to the #seekbar element.
positions.forEach(function(position) {

// Is position within range of the duration?
if (position <= video.duration) {

// Calculate position in percentage..
const left = (position / video.duration) * 100 + '%';

// ..create marker and give it the left value..
const marker = document.createElement('div');
marker.classList.add('bubles');
marker.style.left = left;

// ..and add the marker to the #seekbar.
seekBar.appendChild(marker);
}
});
});

This would place each marker on the timeline with a percentage value. After the loop continue with listening to the timeupdate event.

If you want to incorporate ranges, like in your example, than it would require some modification. But this will help get you started on where you are trying to go.



Related Topics



Leave a reply



Submit