JQuery play/pause on HTML5 video is slow - javascript

I have an HTML5 video that I want to play/pause when you click anywhere on the video. The code I wrote below works, but if I click the video a few times it starts to get slow and will even freeze sometimes. I saved the selectors in variables hoping that would take care of the issue, but it hasn't made a noticeable difference. Is there a bug in my code that I'm not seeing and the console isn't detecting? Or is there just a better way to write this so it isn't so slow? By the way, the intro-vid ID is on the <video> element in the HTML.
var $video = $('video')[0];
var $introVid = $('#intro-vid');
// If the video is playing, pause it when clicked
$introVid.on('play', function() {
$introVid.click(function() {
$video.pause();
});
});
// If the video is paused, play it when clicked
$introVid.on('pause', function() {
$introVid.click(function() {
$video.play();
});
});
EDIT: Here is the HTML
<video id="intro-vid" controls>
<source src="placeholder.mp4" type="video/mp4">
<source src="placeholder.webm" type="video/webm">
Your browser does not support the video tag.
</video>

You should not bind event handlers inside of other handlers, this way them quickly multiply causing troubles. Try this instead:
var $video = $('video')[0];
var $introVid = $('#intro-vid');
$introVid.click(function () {
$video.paused ? $video.play() : $video.pause();
});

Related

Autoplay video IPhone low power mode not working

I have a video which is integral to my design and on load the video plays on all devices except IPhones while in low power mode. Using the autoplay attribute the video will start on load in most browsers.
<div class="footage">
<video width="320" height="240" autoplay muted playsinline loop id="videoMob">
<source src="./img/video.mp4" type="video/mp4">
</video>
</div>
After finding out that this did not work I decided to add a .ready function in jquery which activates the video to play if paused on load. Disappointingly this also did not work.
$( document ).ready(function() {
var video = $('#videoMob')[0];
video.paused ? video.play() : video.pause();
});
Please suggest any other ideas?
Came across this too, and found that iOS uses the suspend event (https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/suspend_event) on low-power-mode. This event actually occurs after the video has loaded the few frames and emmited some on load events.
Using this suspend event we're able to show a fallback UI. For safe measure we can revert this UI if the video ever plays again, say on user interaction.
const videoElement = document.getElementById('myVideo');
videoElement.addEventListener('suspend', () => {
// suspended loading. Show play UI..
});
videoElement.addEventListener('play', () => {
// remove play UI
});
The answer from #paulcol. wasn't working for me as the suspend event fired every time... not sure why. On browser, on mobile, low-battery, full batttery, it always fired.
Below is a snippet which relied on the play() function not working (if the battery was low, for example) and adds the controls UI to the video if it doesn't...
<video id="myVideoID" preload="true" muted playsinline autoplay>
<source src="..." type="video/mp4" >
</video>
const videoElement = document.getElementById('myVideoID');
videoElement.play().then(() => {}).catch((error) => {
videoElement.setAttribute("controls","controls");
});
RcNeil solution worked. There is code for react fix.
You don't need then function, you can just catch the error and show controls.
const videoCurrent = useRef<HTMLVideoElement | null>(null);
useEffect(() => {
if (videoCurrent.current) {
videoCurrent.current.play().catch(() => {
if (videoCurrent.current) videoCurrent.current.controls = true;
});
}
}, []);
...
return (
<video ref={videoCurrent} preload="true" muted playsinline autoplay>
<source src="..." type="video/mp4" >
</video> )

How to handle Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()

Below is my code in aspx page to allow playing audio's of wav format in the browser but with my current code I am unable to play wav audios in Chrome browser but it works in Firefox. How can I handle this exception?
<script>
window.onload = function () { document.getElementById("audio").play(); }
window.addEventListener("load", function () { document.getElementById("audio").play(); });
</script>
<body>
<audio id='audio' controls autoplay>
<source src="Sounds/DPM317.wav" type="audio/wav" />
Your browser does not support the audio element.
</audio>
</body>
For Chrome they changed autoplay policy, so you can read about here:
var promise = document.querySelector('audio').play();
if (promise !== undefined) {
promise.then(_ => {
// Autoplay started!
}).catch(error => {
// Autoplay was prevented.
// Show a "Play" button so that user can start playback.
});
}
Try using a callback like this with the catch block.
document.getElementById("audio").play().catch(function() {
// do something
});
I don't know if this is still actual for you, but I still leave my comment so maybe it will help somebody else.
I had same issue, and the solution proposed by #dighan on bountysource.com/issues/
solved it for me.
So here is the code that solved my problem:
var media = document.getElementById("YourVideo");
const playPromise = media.play();
if (playPromise !== null){
playPromise.catch(() => { media.play(); })
}
It still throws an error into console, but at least the video is playing :)
All new browser support video to be auto-played with being muted only
so please put
<video autoplay muted="muted" loop id="myVideo">
<source src="https://w.r.glob.net/Coastline-3581.mp4" type="video/mp4">
</video>
Something like this
URL of video should match the SSL status if your site is running with https then video URL should also in https and same for HTTP
adding muted="muted" property to HTML5 tag solved my issue
I am using Chrome version 75.
add the muted property to video tag
<video id="myvid" muted>
then play it using javascript and set muted to false
var myvideo = document.getElementById("myvid");
myvideo.play();
myvideo.muted = false;
edit: need user interaction (at least click anywhere in the page to work)
I second Shobhit Verma, and I have a little note to add : in his post he told that in Chrome (Opera for myself) the players need to be muted in order for the autoplay to succeed... And ironically, if you elevate the volume after load, it will still play...
It's like all those anti-pop-ups mechanic that ignore invisible frame slid into your code...
php-echoed html and javascript is :
10-second setTimeout onLoad of body tag that rises volume to maximum, video with autoplay and muted='muted' (yeah that $muted_code part is = "muted='muted")
echo "<body style='margin-bottom:0pt; margin-top:0pt; margin-left:0pt; margin-right:0pt' onLoad=\"setTimeout(function() {var vid = document.getElementById('hourglass_video'); vid.volume = 1.0;},10000);\">";
echo "<div id='hourglass_container' width='100%' height='100%' align='center' style='text-align:right; vertical-align:bottom'>";
echo "<video autoplay {$muted_code}title=\"!!! Pausing this video will immediately end your turn!!!\" oncontextmenu=\"dont_stop_hourglass(event);\" onPause=\"{$action}\" id='hourglass_video' frameborder='0' style='width:95%; margin-top:28%'>";
In my case I had to wait for a user interaction, so I set a click or touchend listener.
const isMobile = navigator.maxTouchPoints || "ontouchstart" in document.documentElement;
function play(){
audioEl.play()
}
document.body.addEventListener(isMobile ? "touchend" : "click", play, { once: true });

Change video source after the first video ends

I have two video files in my design. The first one is logo reveal animation and the second one is logo animation. I want to load the first video only when the page loads every time. And i want to load the second video after the first video ends.
Here my target is: 1st video plays when the page loads(only one time - every page load). If the first video ends, the second video will plays in the loop. I don't want to show the logo reveal(1st) again and again. How to do this. Hope i'll be getting the solution.
Here are the code i have.
HTML :
<video width="400" controls id="myVideo" autoplay>
<source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
<source src="http://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
JS
document.getElementById('myVideo').addEventListener('ended',myHandler,false);
function myHandler(e) {
alert();
var videoFile = 'https://static.videezy.com/system/resources/previews/000/002/165/original/Black-cat-in-green-grass.mp4';
$(' #myVideo source').attr('src', videoFile);
$("#myVideo")[0].load();
}
Demo : https://jsfiddle.net/jLa1s62w/
You almost got it.
document.getElementById('myVideo').addEventListener('ended', myHandler, false);
function myHandler(e) {
alert();
var videoFile = 'https://static.videezy.com/system/resources/previews/000/002/165/original/Black-cat-in-green-grass.mp4';
$(' #myVideo source').attr('src', videoFile);
$('#myVideo').attr("loop", true); /* 1 */
$("#myVideo")[0].load();
document.getElementById('myVideo').removeEventListener('ended', myHandler, false) /* 2 */
}
1) Loop attribute so the second video loops.
2) Remove event listener so the video isn't replaced again.
https://jsfiddle.net/yuriy636/jLa1s62w/1/
Note: If you are using jQuery, you can also use jQuery's event method:
$('#myVideo').on('ended',myHandler) and $('#myVideo').off('ended',myHandler)

unload play delay for html 5 video

I'm not sure if it's the structure of my code or there's something I'm missing in my code, however it's seems I am have a slightly slow loading with my html video in Safari. The video plays for at least 1sec before it's actually visible... is the a way I can create a delay before the video starts playing? click here
<video preload="auto" autoplay volume="3" id="video-wall__content">
<source src="video/ad.mp4" type="video/mp4">
<source src="video/ad.ogv" type="video/ogg">
</video>
I have added...
$(window).load(function () {
$(document.body).fadeIn(2000);
('#video-wall-wrapper').get(0).play();
});
Try this.
$(window).load(function () {
$(document.body).fadeIn(2000, function(){
('#video-wall-wrapper').get(0).play();
});
});
The video will start only when fadeIn is complete. As per specs, fadeIn accepts 2 arguments.
duration: A string or number determining how long the animation will run.
complete: A function to call once the animation is complete.
This is holds true for every async event in jQuery. You always have a way to provide callback functions.
<video preload="auto" autoplay volume="3" id="video-wall__content">
autoplay: Instructs the UA to automatically begin playback of the
video as soon as it can do so without stopping.
Source.
So yeah, that basically defies the whole sense of starting the video with jQuery.

capturing video source on html5 video play event

My goal is to get the src of the video playing, when the video is played.
I currently have the following code:
<!doctype html>
<html>
<head>
</head>
<body>
<video width="320" height="240" controls>
<source src="video.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
<script type='text/javascript'>
var vid = document.getElementsByTagName('video')[0];
vid.addEventListener('play', function() {
console.log('video source:',this.src);
}, false);
</script>
</body>
</html>
So my first problem is that this.src doesn't work; it outputs an empty string. I assume this is because the src isn't actually part of the video tag, but is in the source child tag.
I then tried to add into my function the following:
for (var p in this) {
console.log(p, this[p]);
}
I did this to see if I could find any properties referencing it.. but I don't see anything that directly references it? So is the only way to get the source really to grab the child source nodes? If so... then...
My 2nd question, how would I determine which src attribute is actually being used to play the video? IOW if video.mp4 was actually used to play the video, I want to know that value, but if video.ogg was actually used to play the video, I want to know that value instead.
You can try this way:
var vid = document.getElementsByTagName('video')[0];
vid.addEventListener('play', function() {
console.log('video source:',this.currentSrc);
}, false);
Looks like media elements have a currentSrc property to get the chosen media file.
The HTML5 video element already has events, so there is no need to add a listener. This is how I would do it.
var myVid = document.getElementById('videoId');
if(myVid != null)//if possibility of no video loaded in DOM
{
myVid.onplay = function () {
console.log('video source: ' + myVid.currentSrc);
};
}

Categories