jQuery. Pause video with timeout - javascript

I have several videos on my site that have the same class.
I want to play only one video when hovering over it. As soon as I removed the hover, the video was paused with a delay of 1 second.
I learned how to start a video and pause it. But as soon as I add setTimeout I get an error:
Uncaught TypeError: Cannot read properties of undefined (reading 'pause')
Below I am attaching the html code of my solution:
<a href="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
Also I am attaching the html code of my solution:
var figure = $(".cases__item").hover( hoverVideo, hideVideo );
function hoverVideo(e) {
$('.cases__item-video', this).get(0).play();
}
function hideVideo(e) {
setTimeout(function (){
$('.cases__item-video', this).get(0).pause();
}, 1000);
}
I also add working jsfiddle with my code: https://jsfiddle.net/v7certb6/1/
Please help me to resolve the video pause issue after one second.
I will be very grateful for any help.

The issue is because this in the setTimeout() function handler refers to that function, not to the element reference provided in the invocation of the outer hoverVideo() or hideVideo() functions.
To fix this issue create a variable in the outer scope to retain the reference to this which you use within the setTimeout():
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<a href="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
var figure = $(".cases__item").hover(hoverVideo, hideVideo);
function hoverVideo(e) {
let _this = this;
$('.cases__item-video', _this).get(0).play();
}
function hideVideo(e) {
let _this = this;
setTimeout(function() {
$('.cases__item-video', _this).get(0).pause();
}, 1000);
}
Example Fiddle - note the example is in a fiddle as the cross-site content has issues when played on the main SO site.
As a side note, the JS can be reduced to the following, which has the exact same behaviour just using arrow functions:
$(".cases__item").hover(
e => e.currentTarget.querySelector('.cases__item-video').play(),
e => setTimeout(() => e.currentTarget.querySelector('.cases__item-video').pause(), 1000));

Related

Randomly changing video with JS - javascript

I am a newbie, I want to show random videos when loading the website, I have found this code, change some things and achieve what I wanted, but now I need each video to have a small description and a link I attach this image I want something similar to this, is there someone here who can help me with this, thanks in advance.
https://piic.me/img-134
<video autoplay muted loop id="OracleVid" style="display: auto; max-width:100%;">
<source id="OracleVidSRC"/>
</video>
<script>
var clip = document.querySelector("#OracleVidSRC");
var video = document.querySelector("#OracleVid");
var oracleVidArray = [
"http://localhost/website/wp-content/uploads/2021/10/logitech1_xlarge_preview.mp4",
"http://localhost/website/wp-content/uploads/2021/10/6b_xlarge_preview.mp4",
"http://localhost/website/wp-content/uploads/2021/10/elementor1_xlarge_preview.mp4"
];
window.onload = function oracleFunction() {
clip.src = oracleVidArray[Math.floor(Math.random() * oracleVidArray.length)];;
//video.style = "display: block";
video.load();
}
</script>
You can also see the original code here:
Randomly changing video src with JS
I just want to include this in the js code above, (each video has a different url and description)
<figure class="wp-block-video">
<a rel="noreferrer noopener" href="https://website.com" target="_blank">
<video autoplay="" loop="" muted="" src="http://localhost/website/wp-content/uploads/2021/10/logitech1_xlarge_preview.mp4" playsinline="">
</video>
</a>
<figcaption><strong><code><span style="color:#111111" class="has-inline-color">Description
</span></code></strong><a rel="noreferrer noopener" href="https://website.com" target="_blank">website.com</a></figcaption>
</figure>
Add class "none" in:
<figure class="wp-block-video none">
Edit css class:
.none { display:none; }
Put your code with "<figure" after code with "<video" as below:
<video autoplay muted loop id="OracleVid" style="display: auto; max-width:100%;">
<source id="OracleVidSRC"/>
</video>
<figure class="wp-block-video none">
<a rel="noreferrer noopener" href="https://website.com" target="_blank">
<video autoplay="" loop="" muted="" src="http://localhost/website/wp-content/uploads/2021/10/logitech1_xlarge_preview.mp4" playsinline="">
</video>
</a>
<figcaption><strong><code><span style="color:#111111" class="has-inline-color">Description
</span></code></strong><a rel="noreferrer noopener" href="https://website.com" target="_blank">website.com</a>
And in function oracleFunction() remove class none.

Hide button on videojs play()?

I have a play button inside of a video js video / container and I would like the button to hide(), when the video plays. It works if I just use $('.video-play-btn).hide() on the play function but the problem is I have numerous videos on the page so it is hiding them all, I only want the video that is being played for the button to hide.
html:
<div class="col-lg-6">
<video-js data-video-id="6563228568228"
data-embed="default"
data-application-id=""
class="video-js video-container--outer full-width"
controls
id=""
webkit-playsinline="true" playsinline="true"></video-js>
<!-- play button -->
<button class="video-play-btn btn"><i class="fa fa-play fa-play-video-inline"></i></button>
</div>
jquery:
var videoPlayer = videojs('video-one');
videoPlayer.on('play', function () {
$(this).parent().find('.video-play-btn').hide();
});
What you can do give the button id which is the video id with some prefix or suffix,on play function get the ID of video and embed suffix or prefix and hide that button.
In the below example v_6563228568228 is video id and btn_v_6563228568228 is the button id that is same as video id with prefix of btn_.This way you can provide unique id to your button.
Example.
<div class="col-lg-6">
<video
id="v_6563228568228"
class="video-js"
controls
preload="auto"
width="640"
height="264"
poster="MY_VIDEO_POSTER.jpg"
data-setup="{}"
>
<source src="https://mobamotion.mobatek.net/samples/sample-mp4-video.mp4" type="video/mp4" />
<p class="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading to a
web browser that
<a href="https://videojs.com/html5-video-support/" target="_blank"
>supports HTML5 video</a
>
</p>
</video>
<button class="video-play-btn btn" id="btn_v_6563228568228"><i class="fa fa-play fa-play-video-inline"></button>
</div>
<script>
var videoPlayer = videojs('v_6563228568228');
videoPlayer.on('play', function () {
vid_id = $(this).attr('id');
$("#btn_"+vid_id).hide();
});
</script>

Javascript - Showing TypeError: player is null

var playPauseBtn = document.getElementById("play-pause");
var player = document.getElementById("header-video");
player.removeAttribute("controls"); // <--- error is here
playPauseBtn.onclick = function() {
if (player.paused) {
player.play();
this.innerHTML = '<i class="fa fa-pause" aria-hidden="true"></i>';
} else {
player.pause();
this.innerHTML = '<i class="fa fa-play" aria-hidden="true"></i>';
}
};
<div id="header-container" role="banner">
<div class="top-image test-top"></div>
<!-- top image at the bottom of header -->
<div id="header-video-container" class="zoom">
<img id="header-fallback" src="yourimage.jpg" alt="" />
<!-- fallback image for header video -->
<video id="header-video" controls loop muted playsinline width="1280" height="720" role="img">
<source src="<?php echo get_stylesheet_directory_uri(); ?>/videos/nb-show-reel.mp4" type="video/mp4" />
<!-- if adding track/subtitle see https://developer.mozilla.org/en-US/docs/Learn/Accessibility/Multimedia -->
</video>
</div>
<a id="play-pause" class="hover-anim" aria-hidden="true"><i class="fa fa-play" aria-hidden="true"></i></a>
<!-- video player control -->
</div>
Hey guys I'm using this script for video. But when we inspect things it showing TypeError. So can you guys help me to fix this? Thanks :)
Showing error in this line: player.removeAttribute("controls");
possible reasons are:
1- you are not assigning this id "header-video" to any tag.
OR
2-this JS code ran before the html is actually rendered in browser DOM.
solution:
1- check if you have assigned the same id without spelling errors.
2- use your JS once the DOM is loaded completely.
document.addEventListener("DOMContentLoaded", function() {
// all of your js code.
});
Note: putting your script tag in end of body should also work.

How to add video to playlist by clicking on button with source

I have a problem, I want to add a video by button with source onto playlist. Something like... During the first video plays, there are 3 buttons with mp4 sources. When I click on that buttons, they start playing. Everything works, but I donĀ“t want that thing. I want to make a function when I onclick on a button, video starts playing after the first video. Something like flowplayer - http://flash.flowplayer.org/demos/plugins/javascript/playlist/dynamic.html
function add to position 2.
<body>
<div style="overflow: hidden;">
<video id="video" width="80%" autoplay controls >
<source id="videoSource" src="video/0.mp4" type="video/mp4">
</video>
<a class="btn blue" onclick="changevideo0()">0</a>
<a class="btn blue" onclick="changevideo1()">1</a>
<a class="btn blue" onclick="changevideo2()">2</a>
</div>
<script>
function changevideo0() {
document.getElementById('video').src = "video/0.mp4";}
function changevideo1() {
document.getElementById('video').src = "video/1.mp4";}
function changevideo2() {
document.getElementById('video').src = "video/2.mp4";}
</script>
</body>
I changed your function slightly because it is not efficient to add that many functions just to change one part of it.
Your code was pretty good, just pointing to the wrong element.
function changevideo(source) {
document.getElementById('videoSource').src = source;
}
<body>
<div style="overflow: hidden;">
<video id="video" width="80%" autoplay controls >
<source id="videoSource" src="video/0.mp4" type="video/mp4">
</video>
<a class="btn blue" onclick="changevideo('video/0.mp4')">0</a>
<a class="btn blue" onclick="changevideo('video/1.mp4')">1</a>
<a class="btn blue" onclick="changevideo('video/2.mp4')">2</a>
</div>
</body>
You should consider the following example as logic code, as I have not tested, checked for syntax errors and noor do I know from the top of my head if I should get the length of the video from the source or player element in HTML.
<body>
<script>
var player = document.getElementById("video");
var videolist = {
'video/0.mp4',
'video/1.mp4',
'video/2.mp4'
};
var queuelist = {};
function changevideo() {
if(!queuelist.length == 0){
document.getElementById('videoSource').src = queuelist.shift();
setTimeout(changevideo, player.length * 1000);
} else {
alert("no more video's in queue");
}
}
player.play();
setTimeout('changevideo', player.length * 1000);
</script>
<div style="overflow: hidden;">
<video id="video" width="80%" autoplay controls >
<source id="videoSource" src="video/0.mp4" type="video/mp4">
</video>
<a class="btn blue" onclick="queuelist.append(0)">0</a>
<a class="btn blue" onclick="queuelist.append(1)">1</a>
<a class="btn blue" onclick="queuelist.append(2)">2</a>
</div>
</body>

Displaying different Fancybox based on validation - Too much recursion

I have a list of images and when the image is clicked, I need to do an ajax URL call and validate some parameters.
If the validation is okay, I will have to show the fancybox else I should display another fancybox.
My Issue:
When I click on the image and if the validation is false the other fanybox displays as expected. But if the validation is true, Firebug throws an error saying "too much recursion".
PS:: The expectations is that a video.js player will be shown if the validation is true.
HTML Sample:
<a id="videolink" href="#1" title="Test">
<img class="vidimg" src="1.png" videoId="1" width="180" height="180" />
</a>
<div style="display:none">
<video id="1" poster="1.png" class="video-js vjs-default-skin">
<source src="1362993728.mp4" type='video/mp4'>
<source src="1362993728.webm" type='video/webm'>
<source src="1362993728.ogv" type='video/ogg'>
</video>
</div>
jQuery:
$("a#videolink").click(function(){
$videoId = $(this).children("img.vidimg").attr("videoId");
$isValid = "true" or "false" ; // validation using .ajax() call
if($isValid == 'true'){
$(this).fancybox().click();
}else{
$("#myModal").fancybox().click()
}
});
The "too much recursion" is shown on the line by Firebug:
$videoId = $(this).children("img.vidimg").attr("videoId");
The other fanybox content to be displayed in case of "false":
<div style="display:none">
<div id="myModal"> Invalid Item</div>
</div>
The below changes helped me to have this work as expected.. (there are still some issues in having the fancybox video play).
HTML Sample:
<div style="display:none">
<div id="1">
<video poster="1.png" class="video-js vjs-default-skin">
<source src="1362993728.mp4" type='video/mp4'>
<source src="1362993728.webm" type='video/webm'>
<source src="1362993728.ogv" type='video/ogg'>
</video>
</div>
</div>
jQuery:
$("img.vidimg").click(function(){
$videoId = $(this).attr("videoId");
$isValid = "true" or "false" ; // validation using .ajax() call
if($isValid == 'true'){
$('#' + $videoId ).fancybox().click();
}else{
$("#myModal").fancybox().click()
}
});
Any comments on this related to performance or bad code practice with reference to this code?
I will create a new question here for the video player issue. After this change, the video does not play. :(

Categories

Resources