Controlling the HTML 5 video controller with javascript? - javascript

I was wondering how I could control/edit the status bar of an html5 video controller (i think that's what its called.. Its the bar that has your current position in the video)?
What I'm trying to do is create a program that will enable a user to pick part of the video and loop it over and over again.
Once a user hits a button, there will be 2 slider buttons underneath the progress bar, (one for beginning and ending) and the user can select the beginning and ending times by sliding the sliders and having the program highlight the portion they selected.
What I am confused about is how the video element (progress bar) is effected by the java script, and how to make the selection portion of the bar. (the highlighted section)
any help would be awesome.
here are pictures of what I am trying to explain
http://imgur.com/a/XX1e3#0
Thanks Guys

The progress bar of a <video> element isn't really "affected" by JS, per se...
The progress bar is little more than a <div> with coloured <div>s inside (to show progress).
The video object (the JS object) has properties and methods which control playback/position, and fire update events to allow you to react.
<video id="my-video" src="/media/my-video.mp4"></video>
Then the JS properties of that object are pretty straightforward:
var video = document.querySelector("#my-video");
video.play(); // plays
video.pause(); // pauses
video.currentTime; // gets or sets the current playback time
video.duration; // gets the length of the media file
// stop doesn't exist, but it's easy enough to make
video.stop = function () { video.pause(); video.currentTime = 0; };
video.addEventListener("timeupdate", function () {
/* more of the video has played */
});
All you really need to do here, is spend some time thinking about how the bar itself will operate.
If 100% of the bar is equal to 100% of the video's duration, then as users click on other divs to move them around, you can figure out where those cursors are on the time-bar...
eg: your bar is 500px, your video is 300 seconds.
The user sets one cursor to 100px from the left of the bar (100px/500px == 0.2 * 300s == 60s).
So now you know that when you loop back around, you're going to set video.currentTime = 60;.
How do you know when to do that?
video.addEventListener("timeupdate", function () {
var end_percent = end_cursor_pos_px / bar_width_px,
start_percent = start_cursor_pos_px / bar_width_px,
end_time = video.duration * end_percent;
if (video.currentTime > end_time) {
/* set video.currentTime to the "start_time" */
video.currentTime = video.duration * start_percent;
}
});
As a performance consideration, you should update the start-percent/end-percent whenever the user moves either cursor.
Then, when the video tells you it's played more, you should calculate the percentage of the duration.
Note that you might not have the full duration available to you until the video has played a bit (or until it's played all the way through, even).
There is a "loadedmetadata" event you can listen to, that will tell you when you've got it all.
But still, if only 30 seconds have loaded, 50% of 30 seconds is still 50%.
If you want that not to be the way it works, then you need to work around it, either by waiting for that event (even if the video has to be 100% done), or by sending it in a JSON request, or reading it from headers in an AJAX "HEAD" request.
The math for the positions of the cursors and bar is pretty easy, too.
As long as you guarantee that the cursors stay within the bounds of the bar, (and the user hasn't scrolled the window to the point where part of the bar is off-screen, left or right), it's just going to be:
var start_cursor = startEl.getBoundingClientRect(),
end_cursor = endEl.getBoundingClientRect(),
scrub_bar = scrubEl.getBoundingClientRect();
var start_percent = (start_cursor.left - scrub_bar.left) / scrub_bar.width,
end_percent = (end_cursor.left - scrub_bar.left) / scrub_bar.width;
If they have scrolled left/right, then you just want to add window.pageXOffset to those values.
There isn't much more to it.
Just be sure to update the start/end percent any time a cursor gets moved, and check your playback percentage against the end-percent, and update the currentTime, any time it's gone past (the callbacks happen several times a second).
Hope that helps a little.

Related

Parallax Video Progess Scrolling

I'm looking to create a video parallax background, but I want that the progress of the video corresponds to where I am on my webpage.
For example :
When im on the top of the page the video is at 0 seconds,
in the middle at 50% of its total runtime
and finishes only when I reach the bottom of the page.
You have to break down the big problem into smaller problems.
First, you need to get your video's duration :
var vid = document.getElementById("myVideo");
duration = vid.duration;
Next, you need to get the scroll amount in percentage
function getVerticalScrollPercentage (elm) {
var p = elm.parentNode
return (elm.scrollTop || p.scrollTop) / (p.scrollHeight - p.clientHeight ) * 100
}
Next, you need to dynamically set your video's currentTime (in seconds), you can do it this way :
vid.currentTime = duration * percentage / 100;
And finally, you need to set the currentTime again, whenever the scroll amount changes. That is achieved by using an event listener, on the body for example.
object.addEventListener("scroll", myScript);
Now put it all together :)

JS - Audio player with progress bar and tags on it

I need to make an audio player using HTML/CSS and JS. The player should be simple, with play button and progress bar. However I need to implement a way that users can add tags on the audio file (on progress bar). Something like a player from SoundCloud. Where there is a tiny line on bar at specified time, and when you hover that, a popup window comes out with some message.
Is it possible with HTML5's <audio></audio> tags to get millisecond representation using JavaScript?
Or the best idea is to create a custom audio player?
EDIT
I am following this example -> http://alexkatz.me/posts/building-a-custom-html5-audio-player-with-javascript/
And there is a function which I am trying to edit. So when I do:
function moveplayhead(event)
{
var newMargLeft = event.clientX - getPosition(timeline);
console.log(newMargLeft);
if (newMargLeft >= 0 && newMargLeft <= timelineWidth)
{
playhead.style.marginLeft = newMargLeft + "px";
}
if (newMargLeft < 0)
{
playhead.style.marginLeft = "0px";
}
if (newMargLeft > timelineWidth)
{
playhead.style.marginLeft = timelineWidth + "px";
}
}
I get in console number of seconds. How can I place small red label (for example) to mark this area. And then add a popup..
You should be able to add a progressing line on your developed audio player with below logic steps:
Create an audio player function (javascript)
Create a timer function (javascript)
Specify an intervall where you want to "tap-out" the trigger that will indicate to move the progress line. (javascript)
Create the transition sliding. (Javascript or CSS)
Create stacking layer using z-index (so you can have your audio player on one layer, and the progressing line on a layer ontop the audio player.) - (CSS)
Since the interaction between each step will probably be needed to work relatively fast, you should stay in javascript as much as possible, without to many interaction with CSS and HTML.

HTML5 video how can i zoom at particular time while playing to particular position and come back to normal automatically

I have a video and i need to zoom at particular point (top-left) at particular time suppose exactly at 10 seconds so i need a smooth transition of moving up and coming back to its original position automatically
video.addEventListener("timeupdate", function(){
// check whether we have passed 5 minutes,
// current time is given in seconds
if(this.currentTime >= 10) {
//do something
document.getElementById("mainvideo").style.height='400px';
}
});
You can try addEventListener and checking current status making changes in dom

How to add one class at a time if two divs are ovelapped in the same position

I am stuck in one problem and tried a lot but couldn't get the solution.
What happens is, there is an mp3 player and below that player there is a strip what holds pictures (comments from users) based on the mp3 progress.
When ever the progress bar of the player reach the start of the image it ads "active" class to the image so people can see that at this time this user commented.
Now the problem I am facing is that at 01:46 there are two images that overlap each other and due to this overlap the javascript is adding active class to both images which I don't want, I want if the progress bar reach the start of the first image it will make it active but as soon as the second image starts (which is overlapped) the second image gets active so that there would be only 1 active at a time. same as soundcloud comments.
No matter if the first image duration will be less but this is what i wanted to achieve, as these images will be dynamic and user can choose where ever they want to comment i can not give the specific class to overlapped images so something needs to be done through javascript which i am stuck badly.
Because now there are two overlapped but in future it can be three four or how many overlapped so i want a effect that when we move the mouse from left to right on these images how the hover effect makes pictures active and as the second picture gets in focus that become active, i want it to be that way.
Can any expert help me with this?
I am using this function to get the left position of the progress bar meets the image to add "active" class and when the width of the image end it will remove the active class
$(document).ready(function() {
function highlightImg(progress){
progress = parseFloat(parseFloat(''+progress).toFixed(1));
var imgs = $('img.comment');
imgs.map(function (i, im)
{
var img = $(im);
var currentImgLeftPos = parseFloat(parseFloat(im.style.left).toFixed(1));
var currentImgRightPos = $(this).width() / $(this).parent().width() * 100;
console.log(progress);
console.log('left' ,currentImgLeftPos);
img.removeClass('active'); // remove active from other images
if (progress > currentImgLeftPos - 1 && progress < currentImgLeftPos + currentImgRightPos ) {
$('#imgwidimg').text('this'+currentImgRightPos);
img.addClass('active'); // add the class when needed
}
}
);
}
And with this function i am making the jplayer progress update
$('#jquery_jplayer_2').on($.jPlayer.event.timeupdate, function(e){
var progress = document.querySelector('.jp-play-bar').style.width;
highlightImg(progress);
});
Here's a fiddle demonstrating the problem.
Please try with this.
if (progress > currentImgLeftPos - 1 && progress < currentImgLeftPos + currentImgRightPos ) {
$('#imgwidimg').text('this'+currentImgRightPos);
imgs.removeClass("active"); //add this line to your code
img.addClass('active'); // add the class when needed
}

width of div flickering between previous width and current width

I have developed an audio slider (the slider down the bottom which allows you to scrub through the track) similar to SoundCloud's, and it all works perfectly, except for one thing; it flickers back and forth between the width [/ time] of the previous playing track, and the current playing track.
I have no idea as to why this is happening and have been stumped on it for quite a while.
This is my current block of JavaScript & jQuery:
function trackToSlider(wave){
// get the duration of current playing song
var waveDuration = wave.getDuration();
// check every 0.1s how far in the song is
var getWidthAndMax = setInterval(function(){
// currentWidth is the current percentage of the width of the slider from 100%
var currentWidth = (wave.getCurrentTime() / waveDuration) * 100;
makeSliderIncrease(currentWidth, waveDuration);
}, 100);
function makeSliderIncrease(currentWidth, maxWidth){
// if the current time is more than or equal to the songs duration, set the width of the slider to 100% and clear the interval
if(currentWidth >= maxWidth){
clearInterval(getWidthAndMax);
$('#inner-slider').css('width', '100%');
// otherwise set the width percentage equal to currentwidth
} else {
$('#inner-slider').css('width', currentWidth + '%');
}
}
}
Here are the relative elements inside my HTML:
<!-- play or pause track button !-->
<div onclick="trackToSlider(wave);"></div>
<!-- the audio slider which keeps on flickering !-->
<div class="audio-slider-container">
<div id="outer-slider">
<div id="inner-slider"></div>
</div>
</div>
I hope you all sort of understand where I am at currently. I have attempted to comment everything to make it easier to understand.
I feel like the problem is that because it's set a width already, before it moves onto the next track, when the new track attempts to set the new width, it's flicking between the two widths consistently, but I could be wrong.
All help or suggestions are appreciated,
Thanks. :-)
I think it's beacouse you use the same div for every track. My assumption is that your clearInterval function resets currentWidth of wave, and makes it go back to 0 invoking tracktoSlider twice. But that's all I can say based on given code. Try to add a #inner-slider to html each time you start a new track, and remove it each time when track ends

Categories