HTML5 video addEventListener 'ended' not fired - javascript

I have made a video slider that cycles trough video's. I tested the code several time when I was working on it, but a week later when I set the content online it did not function anymore.
What the problem is:
Firefox > Works fine, the addEventListener gets called and all is well
Chrome > Works fine, no errors but the addEventListener is not called and the cycle is not continued.
Is this a common Chrome bug, or did I bug my own code?
The cycle that I have created is this>
/* SLIDER */
var counter = 0;
var vid_count = 2;
var logotime = 2000;
var waittime = 5000;
function mainRotation(index){
loadVideo(index);
}
function loadVideo(index){
var video = document.getElementById('slideVideo' + index);
if(video.getAttribute("src")==null) {
video.setAttribute("src", './templates/tacticalghillies/video/slidevideo_' + index + '.mp4');
video.load();
}
else{
video.currentTime = 0;
$('#slideVideo' + index).show();
}
$('#slideImage').addClass('fadeout');
var timing = setInterval(function(){
showVideo(index, function(){
if(counter < vid_count-1){
counter++;
mainRotation(counter);
}
else{
mainRotation(counter);
counter = 0;
}
});
clearInterval(timing);
}, waittime)
}
function showVideo(index, cb){
//fade in video opacity
//play video
//video ended:
var video = document.getElementById('slideVideo' + index);
video.play();
console.log("playing");
video.addEventListener('ended', myHandler, false);
function myHandler(e){
if(!e) { e = window.event; }
console.log("eddd");
$('#slideImage').removeClass('fadeout');
var timer = setInterval(function() {
clearInterval(timer);
$('#slideVideo' + index).hide();
cb();
}, logotime);
}
}
Just to be clear this is the HTML that corrosponds with this piece of code:
<div class="animation">
<img class="a_aligned" id="slideImage" src="./images/slide_holder.png">
<video class="a_aligned slideVideo" width="1280" style="max-width:1280px;" id="slideVideo0" ></video>
<video class="a_aligned slideVideo" width="1280" style="max-width:1280px;" id="slideVideo1" ></video>
<img class="a_aligned" style="z-index:-1;" src="./images/slide_overlay.png">
</div>

Exactly same problem here... Didn't find yet how to solve this situation.
For information, this exactly same code was working well yesterday. It happend when I updated Chrome to the version 38.0.2125.104
Actually my exact code is :
$(videoBack).on("ended", function(){ [...]
Edit: Because I had a demo to do, I have use a quick fix, but I still have to figure why Chrome doesn't take the ended event anymore.
Quick fix:
setTimeout(function(){ [...] }, 1400);

Related

Moving through Vimeo videos with Javascript

I would like to play through Vimeo videos in sequence with JavaScript with continuous playback and looping through items. The following code moves to the second video at the end of the first but the same functions are not called at the end of the second video. Only the end of the first video shows Called! in the Javascript console, not the end of the second.
The Vimeo Player SDK has player.getVideoId() but not player.setVideoId() so I used a hack to load the next video: setting the source of the iframe and starting the Vimeo player anew. I wonder if this is the problem and the listener for the end of the video is attached to the discarded player.
Another issue with this code is that it exits fullscreen to load the next video.
I attempted this CodePen that sets the Vimeo Player on any element instead of an iframe and was unable to change the played video.
What is a cleaner or effective way of changing videos with the Vimeo Player SDK?
The HTML is:
<div class="vimeo">
<div class="resp-iframe-container container-centered">
<iframe class="resp-iframe" scrolling="no" frameborder="no" src="https://player.vimeo.com/video/238301525" allowfullscreen="" data-ready="true"></iframe></div></div>
And the javascript is:
var l = ["238301525", "496371201", "238301525", "496371201", "..."];
window.current = 0;
var increment = function() {
window.current += 1;
if (window.current == l.length) {
window.current = 0;
}
};
var decrement = function() {
window.current -= 1;
if (window.current < 0) {
window.current = l.length - 1;
}
};
prevA.addEventListener("click", function() {
decrement();
loadPlayer();
});
nextA.addEventListener("click", function() {
increment();
console.log("here!");
loadPlayer();
console.log("there!");
});
var loadPlayer = function() {
console.log("Called!");
var iframe = document.querySelector('iframe');
iframe.src = "https://player.vimeo.com/video/" + l[window.current];
var player = new Vimeo.Player(iframe);
player.autoplay = true;
var treatEvent = function(data, eventLabel) {
// Custom code...
if ("end" == eventLabel) {
console.log("incrementing automatically");
increment();
loadPlayer();
}
};
var onPlay = function(data) {
treatEvent(data, "play");
}
var onPause = function(data) {
treatEvent(data, "pause");
}
var onSeeked = function(data) {
treatEvent(data, "seeked");
}
var onEnd = function(data) {
treatEvent(data, "end");
}
player.on('play', onPlay);
player.on('pause', onPause);
player.on('seeked', onSeeked);
player.on('ended', onEnd);
setTimeout(function() {
//console.log("Trying to play...");
player.play().then(function() {
// the video was played
console.log("success: video played");
}).catch(function(error) {
console.log("Error! " + error.name);
});
}, 1000);
}
loadPlayer();
It seems that the Vimeo Player keeps track of whether it was initialized, adding a tag data-vimeo-initialized="true" in the HTML element.
One solution is to use the Vimeo Player SDK function .loadVideo():
var song_iframe = document.querySelector("iframe#song_video");
var song_player = new Vimeo.Player(song_iframe);
var on_song_end = function(data) {
// Logic to get the new id.
song_player.loadVideo(newId).then(function() {
song_player.play();
});
};
song_player.on("ended", on_song_end);

Ending a video in HTML using JavaScript events?

I am displaying a YouTube video on my html page using JavaScript.
How do I hide the video and retain the page that displayed the video using JavaScript?
I need to hide the video on a button click.
My code looks like this:
function addVideo(qId){
alert("a video");
var $videoComp = '<div class="vid" id="myytplayer"><iframe id="ifr" width="560" height="315" src="//www.youtube.com/embed/ac7KhViaVqc" allowfullscreen=""></iframe></div><div class ="main"><button class="btn btn-success" id="one" >Close video</button></div>';
$('.create-elem').append($videoComp);
$(".main").click(function(){
//$(".vid").hide();
//$("#one").hide();
function stopthevideo(){
var myPlayer = document.getElementById('myytplayer');
myPlayer.stopVideo();
}
});
This is what I do to identify end of video.
var myVideo = document.getElementById("video1");
myVideo.addEventListener('ended',onVideoEnded,false);
function onVideoEnded(e) {
if(!e) { e = window.event; }
// Make your things here
hideVideo = true;
}
Or you can always try work with https://developers.google.com/youtube/js_api_reference#Playback_status
Hope one of these will help you :)
The try to set video position at the ended event:
Save the start time and duration time to variable after loadedmetadata event.
var myVideo = document.getElementById("video1");
var videoStartTime = 0;
var videoEndTime = 0;
myVideo.addEventListener('loadedmetadata', function() {
videoStartTime = 2;
videoEndTime = 4;
this.currentTime = videoStartTime;
}, false);
If current time is greater than start time plus end of video time, pauses the video.
myVideo.addEventListener('timeupdate', function() {
if(this.currentTime > videoStartTime + videoEndTime ){
this.pause();
}
});

How do I keep the <video> and the <canvas> duplicate at same frame?

I have the following code setup to display the canvas duplicate of the video when paused so it can display a greyscale version of the paused image. As you'll notice the paused frame is always behind the video.
I've tried setting pixelScan() to only happen when the video is paused or ended, and I've experimented with the setTimeout() and requestAnimationFrame() all with no luck. But, that's most likely due to my own lack of skill with JavaScript haha
I just seem to keep getting caught up with this issue and I know there has to be plenty fixes to this simple issue
http://coreytegeler.com/ethan/
var processes={
timerCallback:function() {
if (this.v2.paused || this.v2.ended) {
return;
}
this.ctxIn.drawImage(this.v2,0,0,this.width,this.height);
this.pixelScan();
var self=this;
},
doLoad:function(){
this.v2=document.getElementById("video");
this.cIn=document.getElementById("cIn");
this.ctxIn=this.cIn.getContext("2d");
this.cOut=document.getElementById("cOut");
this.ctxOut=this.cOut.getContext("2d");
var self=this;
setTimeout(function() {
self.timerCallback();
}, 34);
this.v2.addEventListener("playing", function() {
self.width=v.videoWidth;
self.height=v.videoHeight;
cIn.width=v.videoWidth;
cIn.height=v.videoHeight;
cOut.width=v.videoWidth;
cOut.height=v.videoHeight;
self.timerCallback();
}, false);
this.v2.addEventListener('ended', function() {
openInfo();
v2.pause();
v2.loop = true;
stateAnimate.animate({path: playBtn, fill:"white"}, 300, "ease-in-out");
loopAnimate.animate({path: loopOn, fill:"white"}, 200, "back-in");
});
},
pixelScan: function() {
var frame = this.ctxIn.getImageData(0,0,this.width,this.height);
for(var i=0; i<frame.data.length;i+=4) {
var grayscale=frame.data[i]*.3+frame.data[i+1]*.59+frame.data[i+2]*.11;
frame.data[i]=grayscale;
frame.data[i+1]=grayscale;
frame.data[i+2]=grayscale;
}
this.ctxOut.putImageData(frame,0,0);
return;
}
}
You can use the pause event:
this.v2.addEventListener('pause', function() {
// process frame here
}, false);

html5 video can't play after pause

I am struggling with the auto pause and then play(manual) again issue.The video is pausing after 2 seconds which is fine. Now there is another button and on click that button the video should start playing from the position it was paused.
Here is my code(html):
<div class="restart">Restart after pause</div>
<video id="video" width="400" height="400" id="video" src="http://media.w3.org/2010/05/sintel/trailer.mp4" controls autoplay />
jquery:
jQuery(document).ready(function ($) {
$('#video').get(0).play();
setInterval(function () {
if ($('#video').get(0).currentTime >= 2) {
$('#video').get(0).pause();
}
}, 100);
$(".restart").click(function(event){
$('#video').get(0).play();
setInterval(function () {
if ($('#video').get(0).currentTime >= 6) {
$('#video').get(0).pause();
}
}, 100);
});
});
I am definitely not on the right path regarding current time and set time.Please suggest.
The JSFiddle is
http://jsfiddle.net/squidraj/KmQxL/10/
Thanks in advance.
Please review this fiddle: http://jsfiddle.net/VZuuF/1/
I got rid of your setIntervals as they are unneccessary with the timeupdate event available.
$(document).ready(function()
{
var checkedFirst = false;
var checkedSecond = false;
$player = $('#video').get(0);
$player.play();
$player.addEventListener('timeupdate', function(event)
{
console.log($player.currentTime);
if ($player.currentTime >= 2 && !checkedFirst)
{
checkedFirst = true;
$player.pause();
}
if ($player.currentTime >= 6 && !checkedSecond)
{
checkedSecond = true;
$player.pause();
}
});
$(".restart").click(function(event)
{
$player.play();
});
});

infinte loop while trying to display buffer symbol as pics preload

I am really getting frustrated with this. So I am making a slideshow with javascript but while all the images are being loaded I would like to show a buffering symbol..
here is the buffering symbol code.. if you have a better way of doing it please speak up.
function loadAnimation(){
setTimeout(
"document.getElementById('main_photo_img').src = 'images/loadBar1.jpg'", 300);
setTimeout(
"document.getElementById('main_photo_img').src = 'images/loadBar2.jpg'", 600);
setTimeout(
"document.getElementById('main_photo_img').src = 'images/loadBar3.jpg';", 900);
}
that displays 3 images that make up a buffer animation.
my code for playing it until an image is loaded is this..
while(!pic1.onload){
loadAnimation();
}
All that happens though is an infinite loop.
Try something like this:
function loadAnimation() {
var i = 0,
timer;
(function k() {
var cur = i++ % 3 + 1;
document.getElementById('main_photo_img').src = 'images/loadBar' + cur + '.jpg';
timer = setTimeout(k, 300);
})()
return {
cancel: function () {
clearTimeout(timer);
}
};
}
....
var animation = loadAnimation();
pic1.onload = animation.cancel; //The cancel will be called when pic1 loads. You may add other code in the cancel function if needed
I'd probably just use a gif or css background sprites, setting src dynamically is probably the hackiest way to do this I've seen to date ;p
Here's a recursive setTimeout version which I think is what you're looking for.
var i = 0, intervalId;
function animate(){
var newImg = 'images/loadBar' + ((i++ % 3) + 1) + '.jpg'
document.getElementById('main_photo_img').src = newImg;
intervalId = setTimeout(animate, 300);
}
And again, you'd stop this with
clearInterval(intervalId);
To start it with the first image showing up immediately you'd simply call
animate();
But to have the first image wait 300ms before showing, you would do
intervalId = setTimeout(animate, 300);

Categories

Resources