Prevent unwanted pause() when appending a video element - javascript

In a cordova project, i use the camera plugin. In browser, it creates a video element within a div with class cordova-camera-capture.
Due to the css framework I use (FrameWork7), this div is invisible and I'm unable to take the webcam picture.
So i decided to move the div in my view (in a div with ID capture).
Here is my code:
$(document).on('DOMNodeInserted', function(e) {
var element = e.target;
if ( $(element).is('div.cordova-camera-capture') && !$(element).parent().is('div#capture') ) {
$('#capture').append(element);
}
});
It works, but the video is stopped. I can see the webcam capture but on the console I encounter:
Uncaught (in promise) DOMException: The play() request was interrupted
by a call to pause().
I can fix the fact the video is pause by relaunching it:
$('#capture').find('video').get(0).play();
But I don't find it a convenient way as it doesn't get rid off the primary error.
Is there any way to prevent the pause() call on "moving" the div by appending it? Or any technique to move the element without triggering pause()?

Use autoplay attribute
<video autoplay>

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.

How to mute a looped background video

I am using the Wallpaper plugin to loop a video in the background of a div. The idea is to have a video loop in a background of a div on mute. On hover, the video will have sound.
I couldn't find documentation or ways to mute. Any thoughts? I have tried to mute by adding the lines after the plugin is initialized --
$("video").prop('muted', true);
$("video").attr('muted', 'muted');
I have not seen a reference to the volume of the video in the documentation of the plugin.
However, in an html compliant browser, it can be easily muted by
Asserting the muted property
Setting the volume property to 0
You can do it on the video elements or on the jQuery wrapper.
$('video').prop('volume', 0)
$('video').prop('muted', true)
Since the video elements in your document are created by the wallpaper plugin, you should set the volume or muted property after these have been appended to the DOM. It should not be necessary, but in case of problems you could try setting an event handler for the wallpaper.loaded event.
$('your selector').wallpaper({
//... initialization parameters
}).on('wallpaper.loaded', function(){
$('video', this).prop('muted', true);
});
I would use the property muted="muted" to get the desired result, so long as there's only one video element on the page that will work just fine.
$("video").prop('muted', 'muted');
jsFiddle example
Edit
FYI I checked out the wallpaper plugin and saw that it did indeed do what I suspected which is create a video object. If you really wanted to get specific on what video does what you can use the element that wraps the video then the child video element such as:
$("#pluginElem > video").prop('muted', 'muted');

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

Pause mediaelement.js using jquery

I have initialised the element using:
$('video').mediaelementplayer();
Now I would like to target that video and pause it when a link is pressed:
$('.page_button').live('click', function() {
$('video').pause();
});
Thanks.
Each element with a media player element has a player property defined. This is where all the methods reside. You can access it with either of the following methods:
$('video')[0].player.pause(); // Be sure the video element exists.
$('video').each(function(){this.player.pause()}) // Safe.

html5 video playing twice (audio doubled) with JQuery .append()

Huge WTF that I thought was a bug hidden in the semicomplex web app that I'm making, but I have pared it down to the simplest code possible, and it is still replicable in Firefox, Chrome, and Safari, unpredictably but more than 1/2 of the time.
http://jsfiddle.net/cDpV9/7/
var v = $("<video id='v' src='http://ia600401.us.archive.org/18/items/ForrestPlaysTaik/forresto-plays-taik-piano-360.webm' autobuffer='auto' preload autoplay controls></video>");
$("#player").append(v);
Add a video element.
Video starts to load and play.
Video audio sounds like it is doubled.
Pause the visible video, and one audio track continues.
Delete the video element; the ghost audio keeps playing.
Delete the frame, and the ghost audio stops (though once in Firefox it continued to play after closing the window, and didn't stop until quitting Firefox).
Here is a screen capture to maybe show that I'm not completely crazy: http://www.youtube.com/watch?v=hLYrakKagRY
It doesn't seem to happen when making the element with .html() instead of .append(), so that's my only clue: http://jsfiddle.net/cDpV9/6/
$("#player").html("<video id='v' src='http://ia600401.us.archive.org/18/items/ForrestPlaysTaik/forresto-plays-taik-piano-360.webm' autobuffer='auto' preload autoplay controls></video>");
I'm on OS X 10.6.7.
I think that I have it. Even just creating the JQuery object without adding it to the page causes the ghost player to play: http://jsfiddle.net/cDpV9/8/
var v = $("<video id='v' src='http://ia600401.us.archive.org/18/items/ForrestPlaysTaik/forresto-plays-taik-banjo-360.webm' autobuffer='auto' preload autoplay controls></video>");
For now I can work around this by using .html(). I'll report the issue to JQuery.
Maybe jQuery caches the content of $() before appending it to your player div? So there is another instance of the video tag. It could be an error in jQuery. Have you tried this without Jquery/js?
I would try adding the autoplay attribute after you append the video player. This should then instantiate the play function.
That would be something like this:
var v = $("<video id='v' src='videofile.webm' autobuffer='auto' preload controls></video>");
$("#player").append(v);
v.attr('autoplay','autoplay');
When you create elements in JavaScript i.e. image elements, objects etc, they are loaded instantly and stored in memory as objects. That is why you can preload images before you load a page. It is therefore not a jQuery bug.
Ref: http://www.w3.org/TR/html5/video.html#attr-media-autoplay
When present, the user agent (as described in the algorithm described
herein) will automatically begin playback of the media resource as
soon as it can do so without stopping.
I've got the same problem over here. This seems to be an issue with using the "autoplay" attribute on your video markup.
Remove the autoplay attribute
append your video DOMNode to any node
if you want autoplay behavior, call videodomnode.play() - using jquery this would be $('video')[0].play()
You could get the html of #player and append the video your self, then add the total with .html() like this:
var v = $("#player").html() + "<video id='v' src='http://ia600401.us.archive.org/18/items/ForrestPlaysTaik/forresto-plays-taik-piano-360.webm' autobuffer='auto' preload autoplay controls></video>";
$("#player").html(v);
It's not as good as the .append() function, but if the .append() doesn't work, you might be forced to do something like this.
This one worked best in my case:
var v = '<audio hidden name="media"><source src="text.mp3"><\/audio>';
$('#player').append(v);
$("audio")[$('audio').size()-1].play();
I solved mine by loading video after dom loaded:
$(window).bind("load", function() {
var v = $("<video id='bgvid' loop muted>
<source src='/blabla.mp4' type='video/mp4'>
</source>
</video>");
$(".video-container").append(v);
v.attr('autoplay','autoplay');
});

Categories

Resources