I have a problem with the custom cursor image when hovering over a video element.
HTML
<video id="videoPlayer">
<source src="video/sanaa-faizal.mp4" type="video/mp4">
<source src="video/sanaa-faizal.ogg" type="video/ogg">
</video>
SCRIPT
<script>
var videoPlayer = document.getElementById('videoPlayer');
// Auto play, half volume.
videoPlayer.volume = 1;
// Play / pause.
videoPlayer.addEventListener('click', function () {
if (videoPlayer.paused == false) {
videoPlayer.pause();
videoPlayer.firstChild.nodeValue = 'Play';
} else {
videoPlayer.play();
videoPlayer.firstChild.nodeValue = 'Pause';
}
});
</script>
CSS
video {
max-width: 100%;
height: auto;
cursor: url(../img/icon-play.png), auto;
}
Now the custom cursor image does appear correctly over the video element BUT only when you move the cursor. As soon you stop moving the cursor it goes back to default. Does anybody have a clue how to fix this?
Related
I want try to display some information inside div content when player is paused, but problem is because this is displayed when player is paused and when is seeked.
I have create example:
var video = $('#video')[0];
video.addEventListener("playing", function() {
$('.text').text('playing');
});
video.addEventListener("pause", function() {
$('.text').text('pause');
});
video {
width:300px;
height:150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text">test</div>
<video id="video" controls>
<source id="mp4" src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
</video>
If you seeking you will see that player is change event to pause. Can't find solution to display something only when player is paused. Any idea?
You can add another event listener for seeking using the WebEvent seeking which is fired when a seek operation began.
Check the Code Snippet below for a practical example of using the seeking event.
var video = $('#video')[0];
video.addEventListener("playing", function() {
$('.text').text('playing');
});
video.addEventListener("pause", function() {
$('.text').text('pause');
});
video.addEventListener("seeking", function() {
$('.text').text('seeking');
});
video {
width:300px;
height:150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text">test</div>
<video id="video" controls>
<source id="mp4" src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
</video>
When I try to click on video using js in Friefox click and display in console the id of the video it doesn't work. Why?
$('.videoclass').click(function() {
console.log(this);
var id = $(this).attr("id");
console.log(id);
})
<video controls="" id="ui-id-1" class="videoclass" style="position: absolute; top: 118px; left: 61px;" width="320" height="240"> <source id="videoavantuuid" src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4"> </video>
Firefox controls is the Whole Video Tag
Problem
"When I try to click on video using js in Friefox Firefox click and display in console the id of the video it doesn't work. Why? "
Explanation
Firefox has a play button center poster and Chrome does not. This is an obvious indicator that FF has controls attribute that covers the entire tag and Chrome does not, it's controls are accessible only at the bottom where the bar is.
Firefox video tag is interpreting the click on it's controls property first so the click event registered on .vid is never fired or more likely event was fired then e.stopPropagation() was called so nothing else would be triggered by a click.
Recap
To summarize so far:
Firefox video tag behavior: responds to click events with play/pause but no other callbacks are triggered.
Firefox controls interacts with all click events directed to the video tag.
Solution ⭐
If you need controls on the video tag, then do not register the click event on the video tag. Register an alternate yet similar event instead:
mousedown,focus, contextmenu, etc.
Demo
Review the Demo with Firefox:
There's 3 video tags:
#ID [controls] Event Result on Firefox v.60.0.2
#vid0 ---- true ------ click --------- Plays video / Does not run callback
#vid1 --- false ------ click --------- Does not play video / Runs callback
#vid2 ---- true ------ focus --------- Plays video / Runs callback ⭐
$('.vid').on("click", identify);
$('.ff').on('focus', identify); //⭐
function identify(e) {
var eventcurrentTarget = e.currentTarget.id;
var eventTarget = e.target.id;
var thisId = this.id;
console.log({
eventcurrentTarget,
eventTarget,
thisId
});
}
figure {
width: 320px;
margin: 0 auto 20px 0
}
figcaption {
font-size: 32px
}
.as-console-wrapper {
margin-left: 325px;
width: 40%;
min-height: 96%
}
.as-console-row:after {
display: none !important
}
<figure>
<figcaption>#vid0</figcaption>
<video id="vid0" class="vid" width="320" height="240" controls>
<source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4">
</video>
</figure>
<figure>
<figcaption>#vid1</figcaption>
<video id="vid1" class="vid" width="320" height="240">
<source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4">
</video>
</figure>
<figure>
<figcaption>#vid2 ⭐</figcaption>
<video id="vid2" class="ff" width="320" height="240" controls>
<source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4">
</video>
</figure>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Change the below piece of the code
$('.videoclass').click(function() {
to
$(document).on('click', '.videoclass', function(){
and it should work.
I found a possible bug in Chrome.
Basically HTML5 native video controls are still visible when using backface-visibility:hidden on HTML5 video tag.
To reproduce it, click 12 times on the button in the example below.
Problem is visible on:
Google Chrome Version 56.0.2924.87 (64-bit)
Google Chrome Version 59.0.3033.0 canary (64-bit) (CANARY)
Test case works on:
Firefox 52.0 (64-bit)
Firefox 53.0a2 (2017-03-06) (64-bit)
I would like to know if you have faced this issue before and a possible work around to it.
PS: I am aware that could created some custom video controls, but I prefer to use the native ones.
let elmBtn = document.getElementById('btn');
let elmVideo = document.getElementById('video');
let elmBox = document.getElementById('box');
let rotateY = 0;
// start style
elmVideo.style.transform = `scaleZ(1) translateZ(-500px) rotateY(${rotateY}deg)`;
elmVideo.style.backfaceVisibility = 'hidden';
elmBox.style.transform = `scaleZ(1) translateZ(-500px) rotateY(${rotateY}deg)`;
elmBox.style.backfaceVisibility = 'hidden';
elmBtn.addEventListener('click', event => {
rotateY += 10;
elmVideo.style.transform = `scaleZ(1) translateZ(-500px) rotateY(${rotateY}deg)`;
elmBox.style.transform = `scaleZ(1) translateZ(-500px) rotateY(${rotateY}deg)`;
});
#wrapper {
perspective: 1000px;
}
#box {
width: 150px;
height: 50px;
background-color: red;
}
#btn {
position: fixed;
top: 0;
left: 0;
}
<div id="wrapper">
<video id="video" preload="metadata" controls>
<source src="http://html5demos.com/assets/dizzy.mp4" type="video/mp4">
<source src="http://html5demos.com/assets/dizzy.webm" type="video/webm">
<source src="http://html5demos.com/assets/dizzy.ogv" type="video/ogg">
</video>
<div id="box"></div>
</div>
<button id="btn">Click me to rotate</button>
You can hide the controls with this little JavaScript:
var vid = document.getElementById(id);
vid.controls = false;
and this to make them visible again:
vid.controls = true;
I hope you can you use this workaround.
You're probably thinking why not just use html's video loop to loop the video. The thing is when I loop the video, it is not smooth and seamless. I've tried to look for other solutions but found none. So I'm trying to instead, make the video jump back to the start when it ends (or nearly ends).
How do I do this using javascript?
<video autoplay id="testvideo" width="100%" height="900px">
<source src="examplevideo.mp4" type="video/mp4" />
</video>
This will loop your video once it reaches the end:
var video = document.getElementById('testvideo')
// When the 'ended' event fires
video.addEventListener('ended', function(){
// Reset the video to 0
video.currentTime = 0;
// And play again
video.play();
});
<video id="testvideo" autoplay controls>
<source src="http://techslides.com/demos/sample-videos/small.mp4" />
</video>
If you want to do it earlier, you could check timeupdate - in this case I'll check if we reached 75% of the video.
var video = document.getElementById('testvideo')
// When the 'ended' event fires
video.addEventListener('timeupdate', function(){
if(video.currentTime > video.duration * .75){
// Reset the video to 0
video.currentTime = 0;
// And play again
video.play();
}
});
<video id="testvideo" autoplay controls>
<source src="http://techslides.com/demos/sample-videos/small.mp4" />
</video>
Keep in mind that a seek (resetting the time) will always jerk a little bit as the data has to be seeked. The only way to work around that is to potentialy use two videos and transition from one to the other before the other one ends. The following code is a bit extensive but actually pretty simple.
// Get both videos
var video1 = document.getElementById('testvideo');
var video2 = document.getElementById('testvideo2');
// Add an event that will switch the active class when the video is about to end
// CSS3 transitions will take into effect and fade one into the other.
video1.addEventListener('timeupdate', function(){
if(video1.currentTime > video1.duration - .5){
video1.className = '';
video2.className = 'active';
video2.play();
}
});
video2.addEventListener('timeupdate', function(){
if(video2.currentTime > video2.duration - .5){
video2.className = '';
video1.className = 'active';
video1.play();
}
});
// This will reset the video to be replayed
video1.addEventListener('ended', function(){
video1.currentTime = 0;
});
video2.addEventListener('ended', function(){
video2.currentTime = 0;
});
video {
position: absolute;
top: 0;
left: 0;
-webkit-transition: opacity 500ms;
transition: opacity 500ms;
}
video.active {
z-index: 1;
opacity: 1;
-webkit-transition-delay: 200ms;
transition-delay: 200ms;
}
<video id="testvideo" class="active" autoplay controls>
<source src="http://techslides.com/demos/sample-videos/small.mp4" />
</video>
<video id="testvideo2" controls>
<source src="http://techslides.com/demos/sample-videos/small.mp4" />
</video>
I found this similar question here, however the answer did not work in my case.
My JsFiddle: http://jsfiddle.net/leongaban/yvne6fnt/
HTML
<div style="position: fixed; top: 0; width: 100%; height: 100%; z-index: -1;">
<video id="hero_video" controls="" autoplay="autoplay" preload poster="http://media.w3.org/2010/05/sintel/poster.png" style="width:100%; height:100%">
<source id="mp4" src="http://leongaban.com/v6/videos/clouds.mp4" type="video/mp4">
<source id="webm" src="http://leongaban.com/v6/videos/clouds.webm" type="video/webm">
<source id="ogv" src="http://leongaban.com/v6/videos/clouds.ogv" type="video/ogg">
<p>Your user agent does not support the HTML5 Video element.</p>
</video>
JS
$("#hero_video").bind('stop', function(e) {
console.log('stopped');
alert('stopped');
}, true);
/*
$("video").bind('stop', function(e) {
console.log('stopped');
alert('stopped');
}, true);
*/
This works if you remove the 3rd argument from your function:
$("#hero_video").bind('stop', function(e) {
console.log('stopped');
alert('stopped');
});
Notice that this will only be triggered at the beginning and of the video. If you want to also trigger an event on pause, you have to also include the pause event:
$("#hero_video").bind('stop pause', function(e) {
console.log('stopped');
alert('stopped');
});
JsFiddle: http://jsfiddle.net/yvne6fnt/8/
Not sure why this works though, since the default for that argument is true. http://api.jquery.com/bind/