How to gracefully stop html5 video playback - javascript

Is there a way to cleanly stop the html5 video playback ?
There are options like:
Set videoElement.src = "" . This throws an error on the video element, with code = 4.
OR
call videoElement.load(). This sets the readyState = 0 but there is not much documentation around it.

UX Perspective
Looking on Google for the difference between pause and stop gave me various results which I can summrize as:
Pause: Playback is stopped. Hitting play again continues from last position.
Stop: Playback is stopped. Hitting play again continues from beginning
At least from the UX point of view that covers all grounds
Stopping of loading of media
If your real goal is to stop the buffering process from happening as well, then your current approach seems to be entirely correct, running the following code is not triggering any errors for me in any browser I tried.
var video = document.querySelector("video");
video.play();
setTimeout(function() {
video.pause(0);
video.setAttribute("src", "");
}, 5000);
<video id="video" controls="" preload="none" mediagroup="myVideoGroup" poster="http://media.w3.org/2010/05/sintel/poster.png" style="height:180px">
<source id="mp4" src="http://media.w3.org/2010/05/sintel/trailer.mp4" type="video/mp4">
<source id="webm" src="http://media.w3.org/2010/05/sintel/trailer.webm" type="video/webm">
<source id="ogv" src="http://media.w3.org/2010/05/sintel/trailer.ogv" type="video/ogg">
</video>

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

HTML5 Video player start playing from wrong time

I want to control the video to start playing from the exact time value as given in the JS code below.
But the player does not do as expect.
For example, if I do vid.currentTime = 1.2, the player will start from 00:00 sec. Or if I do 22, the player will start from timeline 00:21 sec
I am not sure it is because not possible to get the accurate timeline from mp4 (codec challenge)?
Thanks!
var vid = document.getElementById("video1");
vid.currentTime = 2;
vid.play();
<video id="video1" width="320" height="240">
<source src="http://example.com/movie.mp4" type="video/mp4" />
</video>
I think you should wait for the browser to load the metadata and then trigger the event on meta data loading. Let say if you want to start the video 21 seconds onward:
document.getElementById('video1').addEventListener('loadedmetadata', function(){
this.currentTime = 21;
}, false);

JQuery play/pause on HTML5 video is slow

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

How to change current time of a paused html5 video and start playing from that position?

I have a html 5 video on a page like this:
<video preload="none" id="movie" poster="http://my_poster_url.com/sourcefile.jpeg" controls>
<source id="mp4" type="video/mp4" src="http://my_mp4.com/sourcefile.mp4"></source>
<source id="webm" type="video/webm" src="http://my_webm.com/sourcefile.webm"></source>
</video>
Below that video I have a navigation where you can skip to different times in the video. It works perfectly when the video is playing, but when paused following error occurs:
InvalidStateError: An attempt was made to use an object that is not,
or is no longer, usable
Here the function:
$('#my_video_navigation a').click(function () {
var start_in_seconds=...//a variable that gets the time from a json based on the navigation index
$("#movie").get(0).currentTime = start_in_seconds;
$("#movie").get(0).play();
}
I added an if/else statement wether the video is paused or not:
if ($('#movie').get(0).paused) {
$("#movie").get(0).play();
}
and then tried to set the current time like above and even with a set timeout function so that it will wait till the video loaded and is playing but that didn't work. What am I doing wrong or what did I forget?
You should change the currentTime field of the media element, as you can see here in the API doc. There is also an example code here, at MDN
For reference, the sample code there:
var mediaElement = document.getElementById('mediaElementID');
mediaElement.seekable.start(); // Returns the starting time (in seconds)
mediaElement.seekable.end(); // Returns the ending time (in seconds)
mediaElement.currentTime = 122; // Seek to 122 seconds
mediaElement.played.end(); // Returns the number of seconds the browser has played
where the mediaElementID is the id of the audio or video tag.
Edit: It seems I've misread your question. I will take a further look.

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.

Categories