Hello! I’ve built a simple animation that makes my videos pop up when you click on the thumbnail. I’m using the Video element to display them.
When the video element is exited, the video continues to play in the background, sound audible. I’m looking for a way to pause or stop the video when the player is exited (hidden)
Looking at your page, you are using Webflow’s native video player, and you are showing/hiding several of them using interactions for a kind of lightbox-effect. My guess is that you want this behavior for all of them. When video is playing, and the video overlay is closed, that video should be automatically paused.
All good.
Webflow’s video player uses Embedly, which uses Playerjs - so you can accomplish this by detecting the hide ( using a MutationObserver ), and then pause the videos using Playerjs.
Place this in your before-/body custom code area.
Here’s what it does;
Inventories the Embedly videos on your page, and creates a set of Players to reference them
Inventories the DIVs that will show/hide from your interaction. We know these are all immediate children of your player-wrapper DIV. On these overlays, we install a MutationObserver to detect when a hide happens.
The MutationObserver function detects the hide, and uses playerjs to pause it.
IMPORTANT: This is working great on your site with Vimeo vids. My guess in Youtube, etc. would also work as long as you’re using the Webflow native video control, you’ll probably get the Embedly playerjs setup.
<script src="https://cdn.embed.ly/player-0.0.11.min.js"></script>
<script>
$(document).ready(function() {
// Selecting the iframes by class and creating players for each
var players = [];
$('.player-wrapper .embedly-embed').each(function(index, elem) {
players[index] = new playerjs.Player(elem);
});
// Create a MutationObserver instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === 'style') {
var displayStyle = $(mutation.target).css('display');
if (displayStyle === 'none') {
// Find the index of the hidden div
var index = $(mutation.target).index();
// Pause the corresponding video
players[index].pause();
}
}
});
});
// Observe each child div for changes in its 'style' attribute
$('.player-wrapper').children().each(function(index, elem) {
observer.observe(elem, {
attributes: true
});
});
});
</script>
EDIT: Adding this here for later, since I might expand on this approach for a more generic solution.
Hi, thank you for the code, I managed to make it work on my site.
But what code in addition do I use when I would like to reset the videos to frame 0 when hidden?
My problem is that when I play (for example) video 1, then switch to video 2 and play it, and then go back to video 1, the player is not visible because the video is only paused on the frame I left it, but not stopped and reset. So users maybe don’t get it that they have to click or hover on the paused video again to play it.
I would prefer the videos to be reset once they’re hidden.
It’s difficult to imagine your UX setup here. “Hidden” usually refers to situations where the video container is actually hidden, e.g. a lightbox, popup, or videos that are in a tab, slider or accordion. You should still see the trigger that opened the video originally.
If you’re trying to do something different, this might not be the right approach for your situation. I generally need build these custom for each client because the code to detect the hidden state change depends entirely on the UX design.
However if everything’s working as you want and you just need to reset the video to the start, you can try something like this.
player.currentTime = 0; // Reset the video
player.pause(); // Stop the video