Video Audio still plays when the parent div is hidden - javascript

when my video's parent element is hidden is still plays the audio of the video. I need the audio to stop playing, thank you! Also if you'd like to take a look at the actual website feel free to have a look: https://accela-6b408f29a6797bfc3f-ecd2f4351342a.webflow.io/
(P.S. You will only be able to view the video screen once every 45 minutes to please block cookies for this website if you'd like to see it multiple times)
(The video can be skipped by clicking "Skip Video" then the sound continues
This is the code used to display the video:
/*Idea: add listener for hover while playing show pause*/
var bunnyVideo = document.getElementById("bVideo");
var el = document.getElementById("playButton");
//var ey = document.getElementById("pauseButton");
var replay = document.getElementById("replayButton");
//Hide replay button at start
replay.style.visibility='hidden';
pauseButton.style.visibility='hidden';
function playPause() {
replay.style.visibility='hidden';
if (bunnyVideo.paused)
{
bunnyVideo.play();
el.className = "";
}
else
{
bunnyVideo.pause();
el.className = "playButton";
}
}
function playPauseControls() {
replay.style.visibility='hidden';
if (!bunnyVideo.paused) {
el.className = "";
} else {
el.className = "playButton";
}
}
function hideHoverPauseButton(){
replay.style.visibility='hidden';
if (!bunnyVideo.paused) {
el.className = "";
} else {
el.className = "playButton";
}
}
function showHoverPauseButton(){
replay.style.visibility='hidden';
if (!bunnyVideo.paused) {
el.className = "pauseButton";
} else {
el.className = "playButton";
}
}
function videoEnd() {
replay.style.visibility='visible';
el.className = "";
bunnyVideo.setAttribute("controls","controls");
}
function showControls(){
bunnyVideo.setAttribute("controls","controls");
}
function hideControls(){
bunnyVideo.removeAttribute("controls","controls");
}
/*Google Analytics Tracker Function*/
/*Assuming you've already set up the Google Analytics script function on your webpage. This just activates a trigger event when the video plays.*/
/*function bunnyVideoView() {
ga('send', 'event', {
'eventCategory': 'Bunny Video',
'eventAction': 'play',
'eventLabel': 'Bunny Video View'
});
}*/
/* You can play with this to hide controls or not */
bunnyVideo.addEventListener("click", playPause, false);
bunnyVideo.addEventListener("play", playPauseControls, false);
bunnyVideo.addEventListener("pause", playPauseControls, false);
bunnyVideo.addEventListener("mouseover", hideControls, false);
bunnyVideo.addEventListener("mouseout", hideControls, false);
bunnyVideo.addEventListener("mouseover", showHoverPauseButton, true);
bunnyVideo.addEventListener("mouseout", hideHoverPauseButton, true);
el.addEventListener("mouseover", showHoverPauseButton, true);
el.addEventListener("mouseover", hideControls, false);
replay.addEventListener("mouseover", hideControls, false);
bunnyVideo.addEventListener("ended", videoEnd, false);
/*Google Analytics Tracker*/
/*bunnyVideo.addEventListener("play", bunnyVideoView, false);*/
<center>
<div class="video-wrapper1">
<video id="bVideo">
<source src="https://github.com/intricate-rogue/AccelaFiles/blob/master/accela-video-withsound.mp4?raw=true
" type="video/mp4" />
</video>
<div id="playButton" class="playButton" onclick="playPause()"></div>
<div id="pauseButton" class="pauseButton" onclick="playPause()"></div>
<div class="replayButton" id="replayButton" onclick="playPause()"></div>
</div>
</center>

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);

Why is Pjax causing a load conflict with html5 video?

I'm using barba.js to create smooth page transitions with GSAP. Initially I had issues with reinitialising my jS but this is now working (debugged). However, I have an issue with html5 video - clicking on a thumbnail opens a full screen version of the video in a video modal, on a clean page load this doesn't autoplay and has custom controls which are linked to my own jS file - default controls are hidden.
For some reason when I switch pages using PJAX and the page reloads the default controls are shown, and my custom video player controls no longer control the video in question. What's weird is they still play the audio, but the video looks like it is overridden by the original file with controls enabled, I can play both videos simultaneously and hear both, but only see one video.
Basically there seems to be incompatibility between PJAX and html5 video, here is my barba.js which controls the PJAX transition (note the reinit of scripts which I have tested and which works):
barba.init({
transitions: [{
name: 'diffuse-transition',
leave(data) {
return gsap.to(data.current.container, {
opacity: 0
});
},
beforeEnter: ({ next }) => {
window.scrollTo(0, 0);
reinitScripts();
},
enter(data) {
return gsap.from(data.next.container, {
opacity: 0
});
}
}]
});
Then the html for the modal:
<div id="modalVideoWrapper">
<div id="modalVideo">
<div id="modalVideoInner">
<video id="modalVideoInteract" src="clients/moo/video/MOO_Advert_Render_v2_2.mp4" preload="auto"
poster="clients/moo/images/MOO_Video_Placeholder.jpg" class="projectFeedVideo"></video>
<div id="controls">
<div id="progressBar"><span id="progress"></span></div>
<button id="playpause" title="play" onclick="togglePlayPause()">Play</button>
</div>
<img class="close-modal" alt="Close" src="assets/icons/icon_close_modal.png" />
</div>
</div>
</div>
Then the video modal jS which works perfectly on a full page reload, just not through PJAX:
/* Set Globals */
var video = document.getElementById("modalVideoInteract");
/* End Set Globals */
/* Trigger Video Modal */
$(".pF1-Right video, #projectIntro .watchVideo").click(function () {
$("body").addClass("lock-scroll");
$("#modalVideoWrapper").fadeTo("slow", 1);
});
$(".close-modal").click(function () {
video.pause();
$('#modalVideoInteract').get(0).currentTime = 0.3;
$("#modalVideoWrapper").fadeOut("300", 0);
$("body").removeClass("lock-scroll");
});
$("#modalVideoInteract").click(function () {
$("#playpause").click();
});
/* End Trigger Video Modal */
/* Custom Controls */
video.controls = false;
function togglePlayPause() {
var playpause = document.getElementById("playpause");
if (video.paused || video.ended) {
playpause.title = "Pause Video";
playpause.innerHTML = "Pause";
video.play();
}
else {
playpause.title = "Play Video";
playpause.innerHTML = "Play";
video.pause();
}
}
function updateProgress() {
var progress = document.getElementById("progress");
var value = 0;
if (video.currentTime > 0) {
value = Math.floor((100 / video.duration) * video.currentTime);
}
progress.style.width = value + "%";
}
video.addEventListener("timeupdate", updateProgress, false);
video.addEventListener('play', function () {
var playpause = document.getElementById("playpause");
playpause.title = "Pause Video";
playpause.innerHTML = "Pause";
}, false);
video.addEventListener('pause', function () {
var playpause = document.getElementById("playpause");
playpause.title = "Play Video";
playpause.innerHTML = "Play";
}, false);
video.addEventListener('ended', function () {
this.pause();
playpause.title = "Play Again";
playpause.innerHTML = "Play Again";
}, false);
/* End Custom Controls */
What am I missing here?
Worked it out, weirdly enough several parts of the page needed to be removed so that they would reinitialise properly, so I added this to the barba transition jS:
barba.init({
transitions: [{
name: 'diffuse-transition',
leave(data) {
return gsap.to(data.current.container, {
opacity: 0
});
},
beforeEnter: ({ next }) => {
window.scrollTo(0, 0);
reinitTitleScene();
reinitScripts();
},
enter(data) {
return gsap.from(data.next.container, {
opacity: 0
});
},
afterLeave() {
reinitModal();
}
}]
});
function reinitTitleScene() {
$('#titleScene').remove();
}
function reinitModal() {
$('#modalVideoInteract').remove();
}
Hope this helps someone in need :)

Custom Controls for HTML5 Videos don't work

I am customising a video in html and css. So far the play button works and the full screen mode works too. But if I try to drag the slider (the one next to PLAY button) it is meant to change the position in the video too. Same with the volume button (next to MUTE button) - it doesn’t work if I try to slide it.
I wonder what is wrong with my code as I was partially following a tutorial and that’s the way they used for the tutorial.
<div id="video-container">
<!-- Video -->
<video id="video-container__video" width="640" height="365">
<source src='_assets/media/big_buck_bunny.mp4' type='video/mp4'>
</video>
<!-- Video Controls -->
<div id="video-controls">
<button type="button" id="video-controls__play-pause">Play</button>
<input type="range" id="video-controls__seek-bar" value="0">
<button type="button" id="video-controls__mute">Mute</button>
<input type="range" id="video-controls__volume-bar" min="0" max="1" step="0.1" value="1">
<button type="button" id="video-controls__full-screen">Full-Screen</button>
</div>
window.onload = function() {
//video
var video = document.getElementById("video-container__video");
//Buttons
var playButton = document.getElementById("video-controls__play-pause");
var muteButton = document.getElementById("video-controls__mute");
var fullScreenButton = document.getElementById("video-controls__full-screen");
//sliders
var seekBar = document.getElementById("video-controls__seek-bar");
var volumeBar = document.getElementById("video-controls__volume-bar");
//event listener for the play and pause button
playButton.addEventListener("click", function() {
if (video.paused == true) {
video.play();
//button text will change to Pause
playButton.innerHTML = "Pause";
} else {
//pause the video
video.pause();
//button will update its text to play
playButton.innerHTML = "Play";
}
});
// Event listener for the full-screen button
fullScreenButton.addEventListener("click", function() {
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.mozRequestFullScreen) {
video.mozRequestFullScreen(); // Firefox
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen(); // Chrome and Safari
}
});
//event listener for the change bar
seekBar.addEventListener("change", function() {
//calculate the new time
var time = video.duration * (seekBar.value / 100);
//update the video time
video.currentTime = time;
});
//the change bar will move as the video plays
video.addEventListener("timeupdate", function() {
//Calculate the slider value
var value = (100 / video.duration) * video.currentTime;
//Update the slider value
seekBar.value = value;
})
//pause the video when the slider handle is being dragged
seekBar.addEventListener("mousedown", function() {
video.pause();
});
//play the video when the
seekBar.addEventListener("mouseup", function() {
video.play();
});
volumeBar.addEventListener("change", function() {
//update the video volume
video.volume = volumeBar.value;
});
}

Start Video When It becomes In Focus

I'm trying to figure out a way to get my video to start playing only once it becomes in focus of the viewport. The video will be in a bunch of text of an article and I would like it to only play when the user scrolls down to it
<script>
window.onload = function() {
// Video
var video = document.getElementById("video");
// Buttons
var playButton = document.getElementById("play-pause");
var playButtonImg = document.getElementById("playButtonImg");
var muteButton = document.getElementById("mute");
var muteButtonImg = document.getElementById("muteButtonImg");
// Event listener for the play/pause button
playButton.addEventListener("click", function() {
if (video.paused == true) {
// Play the video
video.play();
// Update the button text to 'Pause'
playButtonImg.src = "pause-sm.png";
} else {
// Pause the video
video.pause();
// Update the button text to 'Play'
playButtonImg.src = "play-sm.png";
}
});
video.addEventListener("ended", function(){
playButtonImg.src = "replay-sm.png";
});
// Event listener for the mute button
muteButton.addEventListener("click", function() {
if (video.muted == false) {
// Mute the video
video.muted = true;
// Update the button text
muteButtonImg.src = "mute-sm.png";
} else {
// Unmute the video
video.muted = false;
// Update the button text
muteButtonImg.src = "volume-sm.png";
}
});
// Pause the video when the seek handle is being dragged
seekBar.addEventListener("mousedown", function() {
video.pause();
});
}
</script>
If you can use jQuery, waypoints is what you seek:
http://imakewebthings.com/waypoints/

How can I detect whether my audio stream is: playing, paused or finished?

I'm working on an online radio website and am trying to detect what state the audio player is currently in for the user.
The current setup I've got is often wrong in knowing this and if I'm on iOS and I pause from the lock screen player instead, it will still think it's playing because I never clicked the html pause button.
Finally how is it possible to detect when my stream has fully ended. I've tried: onstalled="", onwaiting="", onerror="", onended="". But none of them work 100% of the time. The closest one to work would be: onstalled="", but even that only had a 60% success rate or so (occasionally when I'm loading the site it would tell me it has ended).
HTML:
<audio autoplay="" id="player" title="" oncanplay="radioLoaded()">
<source src="...">
</audio>
Javascript:
function radioLoaded() {
if (player.paused) {
document.getElementById('radioplaypause').innerHTML = varRadioResume;
} else if (player.play) {
document.getElementById('radioplaypause').innerHTML = varRadioPause;
} else {
document.getElementById('radioplaypause').innerHTML = varRadioLoading;
}
window.player = document.getElementById('player');
document.getElementById('radioplaypause').onclick = function () {
if (player.paused) {
player.play();
this.innerHTML = varRadioPause;
} else {
player.pause();
this.innerHTML = varRadioResume;
}
}
};
function radioEnded() {
document.getElementById('radiolivetext').innerHTML = 'OFFLINE';
document.getElementById('radioplayer').style.display = 'none';
document.getElementById('radioinformation').style.display = 'none';
};
Try this, with some corrections/notes to the code in general:
function radioLoaded() {
// move this line to the top
window.player = document.getElementById('player'); // !!! <-- name too generic, possibility of global collisions
var playPauseButton = document.getElementById('radioplaypause');
if (player.paused) {
playPauseButton.innerHTML = varRadioResume;
} else if (player.play) {
playPauseButton.innerHTML = varRadioPause;
} else {
playPauseButton.innerHTML = varRadioLoading;
}
playPauseButton.onclick = function () {
if (player.paused) {
player.play();
this.innerHTML = varRadioPause;
} else {
player.pause();
this.innerHTML = varRadioResume;
}
};
player.onended = function () {
console.log('ended');
};
// other helpful events
player.onpause = function () {
console.log('paused...');
}
player.onplay = function () {
console.log('playing...');
}
player.onprogress = function (e) {
console.log(e.loaded + ' of ' + e.total + ' loaded');
}
};

Categories

Resources