Stop/skip video manually on click - javascript

I am trying to end a video when a user clicks a skip button allowing a user to skip the video.
I have been using the following, which is all good, and allows me to trigger an action when the video ends.
HTML
<video autoplay>
<source src="video.mp4" type="video/mp4">
</video>
<button class="skip">Skip video</button>
JS
$('video').on('ended',function(){....
//do stuff here
}
however, I want to do something like the following, but not sure how to implement this.
$('.skip').click(function(){
$('video').end();
});

The end() method in jQuery using to get back to the previous selector.
Description from jQuery docs :
End the most recent filtering operation in the current chain and return the set of matched elements to its previous state.
To stop the video get dom object and then use HTMLMediaElement#pause method. Although finally trigger the ended event programmatically using trigger() method.
$('.skip').click(function(){
$('video').trigger('ended')[0].pause();
});

$('.skip').click(function(){
$('video')[0].load();
$('video')[0].pause();
});

Moving a video to the end of playback is not a straightforward operation as you need to first get the length of the video, then move to that point.
A much simpler alternative is to extract the logic that's invoked under ended and call it when the button is clicked too. Try this:
$('video').on('ended', function() {
videoEnded();
})
$('.skip').click(function() {
$('video')[0].pause();
videoEnded();
});
function videoEnded() {
// do stuff here
}
Working example

Related

javascript not executed with setTimeout but does with button click event

I am trying to view a video stream from an IP camera in a web page, when the stream can be played I want it to start automatically. Trying to do that with a timer, try to play and if that fails, try again.
The timer (timeout) doesn't seem to do that, however if I execute the script using a button, it does. What am I missing?
see the code below.
thanks,
Ron
PS: I commented out the setTimeout functions, to make the button work.
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
function playVid() {
var videoElem = document.getElementById("IPcamerastream");
var playPromise = videoElem.play();
// In browsers that don’t yet support this functionality playPromise won’t be defined.
if (playPromise !== undefined) {
playPromise.then(function() {
// Automatic playback started!
videoElem.controls = true;
}).catch(function(error) {
// Automatic playback failed.
// setTimeout(playVid, 1000);
});
}
}
//setTimeout(playVid, 1000);
</script>
<button onclick="playVid()" type="button">Play Video</button><BR>
<video id="IPcamerastream" src="http://192.168.2.8:8080" width="960" height="540"></video>
</body>
</html>
Look into the features of the video html5 tag:(https://www.w3schools.com/tags/tag_video.asp)
one of the optional attributes is autoplay (Specifies that the video will start playing as soon as it is ready) so there is no need to set timeout.
<video id="IPcamerastream" src="http://192.168.2.8:8080" width="960" height="540" autoplay></video>
Move your script below the video element, and you should not need the timeout at all, because the element will already be initialized when the script is executed. So document.getElementById should resolve the element right away.
Using timers will introduce race conditions. If anything, you should add a listener to the DOMContentLoaded event.
Welcome Ron,
This is a well formatted question, but target browser info could also assist in helping you resolve your issue. Please consider adding it in future!
As for your problem, you tell us that you wish the video to autoplay, I'm assuming on page load?
I've also removed the duplicate source paste.
In this case, you only call playVid() from within the promise erroring out. The initial call is bound to the button click event.
In short, only clicking the button will initiate the playVid() function.
You need to add an event listener for DOM readiness and call playVid() within that. Otherwise, it's only being called when you click your button!
document.addEventListener('DOMContentLoaded', (event) => {
//the event occurred
playVid();
});
You can also use the autoplay HTML option in the video tag.
lang-html
<video {...} autoplay />
I had an almost similar problem ، when I received the video stream in a webrtc project, the video would not be displayed without clicking a button.
if you want to play automatically received stream video, you should add "muted" in the video tag.

firefox 25 does not have play() defined for audio tags?

I have the following audio tag:
<audio preload>
<source src='/sounds/notify.ogg' type='audio/ogg'>
</audio>
I want to play it through js, so naturally I would expect calling $("audio").play() to do it (it's the only audio tag on the page), but I get an error stating play isn't defined. Upon inspecting it that is the case. The audio element has no play property. Every tutorial or resource I read says this is all you need to do, but... well, I just can't do it. Is my version of FF just broken or am I somehow missing something not stated in these various texts?
play() is a DOM method, not a jQuery method, which means that you'll need to get the actual DOM element before being able to get the play property. To get the actual DOM element, you can use the jQuery get() method:
$('audio').get(/*insert element index*/).play();
or simply use array indices:
$('audio')[/*insert element index*/].play();
And for even more choice, you can do something like this:
$('audio').eq(/*insert element index*/).prop('play')();
You could even do something like this to play each audio element:
$('audio').each(function () { this.play(); });
As Qantas mentioned play is not a jQuery method, but you can easily add it if desired as below:
$.fn.play = function() {
return this.each(function() {
this.play();
});
}

Receive events from multiple HTML5 videos

I have multiple videos and want to get an event from all of them. But I get only the event from one of them (tested in Chrome). Why?
HTML:
<video id="video1" preload="auto" src="video1.ogg"></video>
<video id="video2" preload="auto" src="video2.ogg"></video>
JS:
$('video').on('canplay', function(){
console.log($(this).attr('id'));
});
jsFiddle
EDIT:
Ok.. it is really strange. On the very first load I get sometimes both events. But after that on every reload I get just an event from one of them!? Here a screenshot of my console:
The problem is that the 'canplay' event has already fired by the time you register it. I believe this is because jsFiddle wraps your code inside of $(window).load(.... If you were to move the script into the html, like on this example, it should work.
Most of the time, if you know for sure that your script is going to run synchronously right after the video element is created with a src, you can assume that none of those events have been fired. But, just to be safe, and especially when you don't know how your code will be used, I recommend something like this:
function handleCanplay(video) {
console.log($(video).attr('id'));
};
$('video').each(function () {
//first, check if we missed the 'canplay' event
if (this.readyState >= this.HAVE_FUTURE_DATA) {
//yup, we missed it, so run this immediately.
handleCanplay(this);
} else {
//no, we didn't miss it, so listen for it
$(this).on('canplay', function () {
handleCanplay(this);
});
}
});
Working example here.

Multiple dynamically added HTML Videos not muting

I have a bunch of html videos being added to the dom via jquery append (HTML string)
I want them to be inserted MUTED.
The problem is, right now they're not getting muted, even when I inject them with the muted prop.
When I remove the muted attrib on the video tag, and try something like $('video').prop("muted",true); it WILL mute them, but only AFTER they have all loaded.
Do I try adding the videos another way, or find an onLoad method for the html videos and trigger a mute function when they're ready.
jsfiddle of what they look like after append: http://jsfiddle.net/mvsMG/
Try onloadeddata HTML5 event handler:
$(document).ready(function(e) { //do NOT use $(window).load; it will not mute all videos
// mute all the videos when data is loaded for each
$('video').on('loadeddata', function(e) {
//console.log('onloadeddata', e.target);
$(this).prop('muted', true);
});
});
Here is the demo fiddle.
Note: I don't know which browser you are testing with but you should check out this browser-support list for HTML5 muted (loop and autoplay) attributes.

HTML5 <Video> "Loop" with a gap or delay of few seconds

I am using the HTML 5 "Video" tag to show the video on my page with the "Loop" feature or attribute.
Is there any way we can add a delay or gap between video using the "Loop" attribute??
<video id="myVideo" autoplay loop src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4">
Please refer the link to see the Video tag code > "http://jsfiddle.net/nrf5fbh8/1/"
Please suggest!
Updated my code, my video tag DO NOT have controls.
Thanks!
Expanding on my comment above, basically instead of using the loop attribute you can set up a listener and place a function within the listener to replay the video after a specified amount of time(in milliseconds) once the video has ended. The JS would look like this:
document.getElementById('myVideo').addEventListener('ended',myHandler,false);
function myHandler(e) {
console.log('ended');
setTimeout(function(){
document.getElementById('myVideo').play();
}, 5000);
}
Updated Fiddle

Categories

Resources