I'm building a web app and I need to check if the client has a camera after the user clicks on a button.
I'm currently using this script but it seems not to work on IE.
navigator.getMedia = ( navigator.getUserMedia || // use the proper vendor prefix
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
navigator.getMedia({video: true}, function() {
//has camera
}.bind(this), function() {
//no camera
}.bind(this));
So what's the best method?
Might be problem with:
navigator.getUserMedia();
This feature has been removed from the Web standards. Though some
browsers may still support it, it is in the process of being dropped.
Avoid using it and update existing code if possible; see the
compatibility table at the bottom of this page to guide your decision.
Be aware that this feature may cease to work at any time.
Obtained via:
MDN web docs
Try: mediaDevices.getUserMedia() as a singleton
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
/* use the stream */
})
.catch(function(err) {
/* handle the error */
});
Even if it's not solution you will future-proof your code.
EDIT:
T.J. Crowder pointed out that indeed the deprecated navigator.getUserMedia(); is listed as not working in IE.
Related
I am trying to get the absolute device orientation across different mobile devices (android + IOs) and browsers
in a more or less reliable way. I would rather be able to understand if the orientation I am receiving is relative and not show the compass instead of showing wrong values.
I have been googling back and forth for days and I haven't found a definitive answer yet (I am
a javascript and web dev novice).
I see that the Full-Tilt library should be doing exactly
that but it has a non commercial license. I intend to use this result in a potentially commercial project, moreover, I would like to understand what's happening.
Nowadays most deviceorientation events are returning relative values.
deviceorientationabsolute is not supported by firefox and it's an experimental feature, I can fallback on it when other things fail but it cannot be the main solution.
So far I've got to this line of reasoning (pseudocode):
if(mobile)
if(webkitmobilecompassheading)
window.addEventListener("deviceorientation", handleOrientationWebkit, true);
else if(deviceorientationabsolute)
window.addEventListener("deviceorientation", handleOrientationAbsolute, true);
else
"bad luck"
I have no idea where to look to understand how many devices I would miss out on with the following reasoning, and if there is a better way.
For Android it works auto, for iOS it needs to be clicked to start it.
Here's a part of code you can use for that
startBtn.addEventListener("click", startCompass);
function startCompass() {
if (isIOS) {
DeviceOrientationEvent.requestPermission()
.then((response) => {
if (response === "granted") {
window.addEventListener("deviceorientation", handler, true);
} else {
alert("has to be allowed!");
}
})
.catch(() => alert("not supported"));
} else {
window.addEventListener("deviceorientationabsolute", handler, true);
}
}
function handler(e) {
const degree = e.webkitCompassHeading || Math.abs(e.alpha - 360);
}
Full tutorial is here, try demo also
https://dev.to/orkhanjafarovr/real-compass-on-mobile-browsers-with-javascript-3emi
I'm trying to create a script which will run when any browser console is opened or closed. Is there any way to detect if the browser console in all browsers (Firefox/IE/Chrome/Safari/Opera) is open or not via JavaScript, jQuery, or any other client-side script?
If you are willing to accept an interference for the user,
you could use the debugger statement, as it is available in all major browsers.
Side note: If the users of your app are interested in console usage, they're probably familiar with dev tools, and will not be surprised by it showing up.
In short, the statement is acting as a breakpoint, and will affect the UI only if the browser's development tools is on.
Here's an example test:
<body>
<p>Devtools is <span id='test'>off</span></p>
<script>
var minimalUserResponseInMiliseconds = 100;
var before = new Date().getTime();
debugger;
var after = new Date().getTime();
if (after - before > minimalUserResponseInMiliseconds) { // user had to resume the script manually via opened dev tools
document.getElementById('test').innerHTML = 'on';
}
</script>
</body>
devtools-detect should do the job. Try the simple demo page.
devtools-detect → detect whether DevTools is open, and its orientation.
Supported Browsers:
DevTools in Chrome, Safari, Firefox & Opera
Caveats:
Doesn't work if DevTools is undocked (separate window), and may show a false positive if you toggle any kind of sidebar.
I don't think it is directly possible in JS for security reasons.But in here
they are claiming that it is possible and is useful for when you want something special to happen when DevTools is open. Like pausing canvas, adding style debug info, etc.
But As #James Hill tell in this, I also thinks even if a browser chose to make this information accessible to the client, it would not be a standard implementation (supported across multiple browsers).
Also can also try this one also here.
It's not possible in any official cross browser way, but if the occasional false positive is acceptable, you can check for a window.onresize event. Users resizing their windows after loading a page is somewhat uncommon. It's even more effective if you expect users will be frequently opening the console, meaning less false positives as a percentage.
window.onresize = function(){
if ((window.outerHeight - window.innerHeight) > 100) {
// console was opened (or screen was resized)
}
}
Credit to https://stackoverflow.com/a/7809413/3774582. Although that question is chrome specific, the concept applies here.
To expand on this, if you need a very low tolerance on false positives, most window resizes will trigger this event dozens of times because it is usually done as a drag action, while opening the console will only trigger this once. If you can detect this, the approach will become even more accurate.
Note: This will fail to detect if the console is already open when the user visits the page, or if the user opens the console in a new window.
(function() {
'use strict';
const el = new Image();
let consoleIsOpen = false;
let consoleOpened = false;
Object.defineProperty(el, 'id', {
get: () => {
consoleIsOpen = true;
}
});
const verify = () => {
console.dir(el);
if (consoleIsOpen === false && consoleOpened === true) {
// console closed
window.dispatchEvent(new Event('devtools-opened'));
consoleOpened = false;
} else if (consoleIsOpen === true && consoleOpened === false) {
// console opened
window.dispatchEvent(new Event('devtools-closed'));
consoleOpened = true;
}
consoleIsOpen = false;
setTimeout(verify, 1000);
}
verify();
})();
window.addEventListener('devtools-opened', ()=>{console.log('opened')});
window.addEventListener('devtools-closed', ()=>{console.log('closed')});
Here is a code that worked for me.
This solution works like a charm
https://github.com/sindresorhus/devtools-detect
if you are not using modules - disable lines
// if (typeof module !== 'undefined' && module.exports) {
// module.exports = devtools;
// } else {
window.devtools = devtools;
// }
and result is then here
window.devtools.isOpen
I for my project use the blur event.
function yourFunction() {}
window.addEventListener('blur',(e)=>{e.preventDefault(); yourFunction()})
This will execute yourFunction when the window loses focus.
For instance when someone opens the DevTools.
Okay seems like it also fires when you try to access a different window... so maybe not the best solution.
Maybe pair it with looking at the width of the browser.
If it chainged you can be pretty sure about it I think
I've got simple video stream working via getUserMedia, but I would like to handle case when webCam what i'm streaming from becomes disconnected or unavailable. So I've found oninactive event on stream object passed to successCallback function. Also I would like to restart video stream when exactly same webcam/mediaDevice will be plugged in.
Code example:
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
navigator.getUserMedia(constrains, function successCallback(stream) {
this.video.src = URL.createObjectURL(stream);
stream.oninactive = function (error) {
//this handler runs when device becomes unavailable.
this.onStreamInactive(error, stream);
}.bind(this);
}.bind(this), function errorCallback () {});
Based on the example above how i can:
Detect recently connected media device
Check is it the same device what I was streaming from
A better way would be to use MediaDevices.ondevicechange() as mentioned in the other answer in this thread, but it is still behind a flag on Chrome. Instead of using ondevicechange() to enumerate devices, poll MediaDevices.enumerateDevices() at regular interval when you start the call, at end of every poll interval compare the list of devices you get from the devices in the previous poll. This way you can know the new devices added/remove during the call.
A little late to answer, but it looks like you can use MediaDevices.ondevicechange to attach an event handler, and then in the event handler you can query MediaDevices.enumerateDevices() to get the full list. Then you inspect the list of devices, identify the one that was recently added by comparing by a cached list you have, and comparing properties to a record you kept of the properties of the current device. The links have more thorough examples.
Adapted from the ondevicechange reference page
navigator.mediaDevices.ondevicechange = function(event) {
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
devices.forEach(function(device) {
console.log(device);
// check if this is the device that was disconnected
});
});
}
Note that the type of the device objects returned by enumerateDevices is described here
Browser Support
It looks like it's pretty patchy as of writing this. See this related question: Audio devices plugin and plugout event on chrome browser for further discussion, but the short story is for Chrome you'll need to enable the "Experimental Web Platform features" flag.
I'm trying to use the JavaScript FullScreen API, using workarounds for current non-standard implementations from here:
https://developer.mozilla.org/en/DOM/Using_full-screen_mode#AutoCompatibilityTable
Sadly, it behaves very erratically. I only care about Chrome (using v17), but since I was having problems I did some tests in Firefox 10 for comparison, results are similar.
The code below attempts to set the browser to fullscreen, sometimes it works, sometimes not. It ALWAYS calls the alert to indicate it is requesting fullscreen. Here's what I've found:
It USUALLY sets fullscreen. It can get to a state where this stops working, but the alert still happens, i.e. it is still requesting FullScreen, but it doesn't work.
It can work if called from a keypress handler (document.onkeypress), but not when called on page loading (window.onload).
My code is as follows:
function DoFullScreen() {
var isInFullScreen = (document.fullScreenElement && document.fullScreenElement !== null) || // alternative standard method
(document.mozFullScreen || document.webkitIsFullScreen);
var docElm = document.documentElement;
if (!isInFullScreen) {
if (docElm.requestFullscreen) {
docElm.requestFullscreen();
}
else if (docElm.mozRequestFullScreen) {
docElm.mozRequestFullScreen();
alert("Mozilla entering fullscreen!");
}
else if (docElm.webkitRequestFullScreen) {
docElm.webkitRequestFullScreen();
alert("Webkit entering fullscreen!");
}
}
}
requestFullscreen() can not be called automatically is because of security reasons (at least in Chrome). Therefore it can only be called by a user action such as:
click (button, link...)
key (keydown, keypress...)
And if your document is contained in a frame:
allowfullscreen needs to be present on the <iframe> element*
* W3 Spec:
"...To prevent embedded content from going fullscreen only embedded content specifically allowed via the allowfullscreen attribute of the HTML iframe element will be able to go fullscreen. This prevents untrusted content from going fullscreen..."
Read more: W3 Spec on Fullscreen
Also mentioned by #abergmeier, on Firefox your fullscreen request must be executed within 1 second after the user-generated event was fired.
I know this is quite an old question but it is still the top result in Google when searching for FireFox's error message when calling mozRequestFullScreen() from code that wasn't triggered by any user interaction.
Request for full-screen was denied because
Element.mozRequestFullScreen() was not called from inside a short
running user-generated event handler.
As already discussed this is a security setting and therefore is the correct behaviour in normal browser environment (end user machine).
But I am writting an HTML5-based digital signage application which runs under a controlled environment without any user interaction intended. It is vital for my apllication to be able to switch to fullscreen automatically.
Luckily FireFox offers a possibilty to remove this restriction on the browser, which is rather hard to find. I will write it here as future reference for everybody finding this page via the Google search as I did
On the about:config page search for the following key and set it to false
full-screen-api.allow-trusted-requests-only
For my digital signage application I also removed the prompt the browser shows when entering fullscren:
full-screen-api.approval-required
Hopefully this might save someone the hours I wasted to find these settings.
You have nothing wrong with your function. In Firefox, if you call that function directly, it will prevent to for full-screen. As you know, Request for full-screen was denied because docElm.mozRequestFullScreen(); was not called from inside a short running user-generated event handler. So, You have to call the function on event such as onClick in Firefox.
Full Screen Mode
Another unexpected issue with requestFullscreen() is that parent frames need to have the allowfullscreen attribute, otherwise Firefox outputs the following error:
Request for fullscreen was denied because at least one of the document’s containing elements is not an iframe or does not have an “allowfullscreen” attribute.
Aside from iframes, this can be caused by your page being within a frameset frame. Because frameset is deprecated, there is no support for the HTML5 allowfullscreen attribute, and the requestFullscreen() call fails.
The Firefox documentation explicitly states this on MDN, but I think it bears reiterating here, for developers who might not read the documentation first.... ahem
Only elements in the top-level document or in an with the allowfullscreen attribute can be displayed full-screen. This means that elements inside a frame or an object can't.
I realize this is an old post, but in case someone else finds this I'd like to add a few suggestions and sample code.
To help avoid this error...
Failed to execute 'requestFullscreen' on 'Element': API can only be
initiated by a user gesture.
Don't test for the existence of requestFullscreen(), which is a method. Instead, test for the existence of a property like document.fullscreenEnabled.
Also consider the following...
Move your fullscreen check into its own function so you can reuse it.
Make DoFullScreen() reusable by passing the element you want to affect as a parameter.
Use a guard clause at the top of DoFullScreen() to exit out of the function immediately if the window is already in fullscreen mode. This also simplifies the logic.
Set a default value for your DoFullScreen() element parameter to ensure the requestFullscreen() method is always called on an existing element. Defaulting to document.documentElement will probably save you some keystrokes.
// Move your fullscreen check into its own function
function isFullScreen() {
return Boolean(
document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement
);
}
// Make DoFullScreen() reusable by passing the element as a parameter
function DoFullScreen(el) {
// Use a guard clause to exit out of the function immediately
if (isFullScreen()) return false;
// Set a default value for your element parameter
if (el === undefined) el = document.documentElement;
// Test for the existence of document.fullscreenEnabled instead of requestFullscreen()
if (document.fullscreenEnabled) {
el.requestFullscreen();
} else if (document.webkitFullscreenEnabled) {
el.webkitRequestFullscreen();
} else if (document.mozFullScreenEnabled) {
el.mozRequestFullScreen();
} else if (document.msFullscreenEnabled) {
el.msRequestFullscreen();
}
}
(function () {
const btnFullscreenContent = document.querySelector(".request-fullscreen-content");
const el = document.querySelector(".fullscreen-content");
// Request the .fullscreen-content element go into fullscreen mode
btnFullscreenContent .addEventListener("click", function (){ DoFullScreen(el) }, false);
const btnFullscreenDocument = document.querySelector(".request-fullscreen-document");
// Request the document.documentElement go into fullscreen mode by not passing element
btnFullscreenDocument .addEventListener("click", function (){ requestFullscreen() }, false);
})();
How do I detect if a browser supports HTML5 by
JS
(or)
jquery AND mootools.
Use modernizr to detect HTML5 and CSS features.
As the other suggested the best option is to use Modernizr, because it was created especially to do this work.
I don't know any plugin in jQuery that covers this functionality (jQuery.supports doesn't check much) but if you want you could try mooModernizr witch extends MooTools Browser.Features object
Another completely valid option is to check Modernizrs source code, and implment that with the features you want to detect.
To detect the video tag support is quite easy:
if (typeof HTMLVideoElement == 'function') {
alert('<video> tag supported');
}
That's in my opinion a simplistic version. Here is how the many times mentioned modernizr does it, which is a bit more bullet proof probably:
function supportsVideo() {
var elem = document.createElement('video'),
bool = false;
// IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
try {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"');
// Workaround required for IE9, which doesn't report video support without audio codec specified.
// bug 599718 # msft connect
var h264 = 'video/mp4; codecs="avc1.42E01E';
bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
}
} catch(e) { }
return bool;
}
Check out modernizr. It is an open source javascript library that specializes in detection of html5 / css3 features:
http://www.modernizr.com/