Video and audio permissions in JavaScript - javascript

I need to tell if a person dismisses the media popup or blocks the media popup
const [permissions, setPermissions] = useState(false)
const handleClick = () => {
setPermissions('pending');
navigator.getUserMedia({ video: true, audio: true }, stream => {
stream.getTracks().forEach(track => {
return setPermissions(track.enabled);
});
}, (error) => {
if(error ==='DOMException: Permission denied'){
setPermissions('denied')
}
if(error === 'DOMException: Permission dismissed'){
setPermissions('dismissed')
}
});
};
I tried using the error string that I got back but it is not working. I need to be able to tell the difference between the errors. Does anyone have a good way to do this? Thanks!

You can't tell the difference in any exact way. Browsers are very uncooperative with Javascript code that tries to access media devices but doesn't get permission from the user. Because cybercreeps.
I've had a bit of success with this to see if the user denied access:
Try again. If you get an immediate (within a couple of seconds) error they probably have already denied access to the devices. If it takes longer, they probably are looking at a repeat of the permission dialog.
Not a great situation. Especially if you want to explain to the user how to go back and un-deny permission. But it's a necessary privacy feature in the surveillance era.

Related

Chrome, allow autoconnect for HID device

So I'm trying to read out a USB-scale thats connected to my pc. I use chrome's experimental HID api.
I use Tampermonekey as userscript injector to extend a website's functionality.
The script I inject looks like this:
navigator.hid.requestDevice({ filters: [{ vendorId: 0x0922, productId: 0x8003}] }).then((devices) => {
if (devices.length == 0) return;
devices[0].open().then(() => {
if(disconnected) {
disconnected = false
}
console.log("Opened device: " + devices[0].productName);
devices[0].addEventListener("inputreport", handleInputReport);
devices[0].sendReport(outputReportId, outputReport).then(() => {
console.log("Sent output report " + outputReportId);
});
});
});
When I run it just like this(inline) I get the message in chrome:
DOMException: Failed to execute 'requestDevice' on 'HID': Must be handling a user gesture to show a permission request.
Basically, the code needs to be inside an event listener and the listener needs to be triggered by user input to run.
Al fine and dandy, except that this has to be initialized hundreds of times a day. I tried running this code in edge and here it just works without user input.
Is there a way I can disable this security feature(completely or only for the site im using it on) in chrome? I know edge is based on chromium so I expect it to be possible, but am unable to find how/where
You can use HID.getDevices() to retrieve an HID device that the user has already granted access to.
My suggestion would be to check for the device you want with getDevices first. If you can't find the device, then make something the user can interact with that will allow you to use requestDevice to connect to the device.

Getting "ScreenCaptureError" in Chrome using Kurento Media Server

I'm trying to share my screen with Kurento WebRtc server. But getting this error:
NavigatorUserMediaError {name: "ScreenCaptureError", message: "", constraintName: ""}
There is no errors in Firefox with same code.
Constraints using for webrtc:
var constraints = {
audio: true,
video: {
mandatory : {
chromeMediaSource: 'screen',
maxWidth: 1920,
maxHeight: 1080,
maxFrameRate: 30,
minFrameRate: 15,
minAspectRatio: 1.6
},
optional: []
}
}
var options = {
localVideo : video,
onicecandidate : onIceCandidate,
mediaConstraints : constraints
}
webRtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options,function(error) {
if (error) {
return console.error(error);
}
webRtcPeer.generateOffer(onOfferPresenter);
});
How do I share my screen using chrome and kurento?
Sharing a screen with Kurento through WebRTC, is exactly the same as sharing the webcam: get the stream from the client and negotiate the endpoint. The tricky part when doing screenshare is to get the stream. The kurento-utils-js library will give you a little help on that, as you can create the WebRtcPeer object, in the client, indicating that you want to share your screen or a window. You just need to make sure that you
have an extension installed to do screen-sharing in Chrome. In FF, it's enough to add the domain to the whitelist. Check this extension.
pass a valid sendSource value (screen or window) in the options bag when creating the kurentoUtils.WebRtcPeer object
have a getScreenConstraints method in your window object, as it will be used here. getScreenConstraints should return a valid set of constraints, depending on the browser. YOu can check an implementation of that function here
I think that should be enough. We are doing screen sharing with the library, using our own getScreenConstrains and extension, and it works fine. Once you have that, doing screen sharing with the kurento-utils-js library is quite easy. Just need to pass the sendSource value when creating the peer like so
var constraints = {
audio: false,
video: true
}
var options = {
localVideo: videoInput, //if you want to see what you are sharing
onicecandidate: onIceCandidate,
mediaConstraints: constraints,
sendSource: 'screen'
}
webRtcPeerScreencast = kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv(options, function(error) {
if (error) return onError(error) //You'll need to use whatever you use for handling errors
this.generateOffer(onOffer)
});
The value of sendSource is a string, and it depends on what you want to share
'screen': will let you share the whole screen. If you have more than one, you can choose which one to share
'window': lets you choose between all open windows
[ 'screen', 'window' ]: WARNING! Only accepted by Chrome, this will let the user choose between full screens or windows.
'webcam': this is the default value of you don't specify anything here. Guess what'll happen ;-)

I cannot get authData by using authWithOAuthRedirect with Chrome on IOS

I am integrating my project with facebook auth login, and I want to support Chrome on IOS. I noticed that I have to handle both authWithOAuthPopup and authWithRedirect (firebase user-auth) in this case. However Chrome IOS did not support Popup auth currently.
I simplify my code and shows the case how it won't work in Chrome on IOS
var rootRef = new Firebase('https://docs-sandbox.firebaseio.com/web/uauth');
rootRef.onAuth( function(authData){
alert('getAuth');
alert(authData);
console.log(authData);
});
$('#login').on('click', function(e){
rootRef.authWithOAuthPopup("facebook", function(err, authData){
if(err && err.code === 'TRANSPORT_UNAVAILABLE'){
rootRef.authWithOAuthRedirect("facebook", function(err, authData){
if(authData){
alert('redirect');
alert(authData);
}
})
}
})
});
Link here http://jsfiddle.net/blackbing/zjunuzec/5/ for more detail.
It works on Safari IOS. If login success, it will alert [object], but it shows null in Chrome on IOS.
any idea?
I think that I figure out what the problem is.
First of all, it is said getAuth is synchronized in document, but It is not reliable synchronized on authWithOAuthRedirect. So when the page redirect to the original page. I can't get authData so that I can't decide if user is signin. (but actually user is signed in).
Second, since callback in "authWithOAuthRedirect" is not possible to be called, the callback function can't get authData anyway. It just could be called if occur error, right? I suggest to notice this behavior that in document.
Anyway: I think the snippet in document have to correct :
https://www.firebase.com/docs/web/guide/user-auth.html#section-popups
the callback in authWithFunction is for handling error, not suggested to deal with authData, onAuth is a better way to get authData. I update a snippet on my gist [https://gist.github.com/blackbing/f77d04cbed4b0059af2e]
var ref = new Firebase("https://<your-firebase>.firebaseio.com");
rootRef.onAuth( function(authData){
//It is a better way to get authData instead of get from auth callback function
console.log(authData);
});
// prefer pop-ups, so we don't navigate away from the page
// auth callback is to handle if occur error
ref.authWithOAuthPopup("google", function(err) {
if (err) {
if (err.code === "TRANSPORT_UNAVAILABLE") {
// fall-back to browser redirects, and pick up the session
// automatically when we come back to the origin page
ref.authWithOAuthRedirect("google", function(err) { ... });
}
}
});
BTW, I found a similar question https://stackoverflow.com/a/26416696/797411, the workaround is not good but I think we met the same problem.

How to detect that system connected with microphone using JavaScript

I'm using getUserMedia() for audio recording and it works correctly but have an issue with it.
I want to display a message before starting recording that any microphone is connected with system or not.
For this I have used following code and run this into chrome but it was not working correctly.
if(navigator.getUserMedia || navigator.webkitGetUserMedia)
{
alert("Microphone is connected with your system");
} else {
alert("Microphone is not connected with your system");
}
when microphone is not connected then also above code giving message "Microphone is connected with your system".
so please suggest me a better way to detect microphone using JavaScript in any browser.
Testing for the existence of these functions does not detect the existence of hardware microphone. It only detects if browser has the API to do so.
The browsers that pass your test need not have a physical microphone plugged into microphone jack. It is simply a newer browser. The browsers that fail the test may have a microphone, but are old browsers that do not contain the API.
Also, at least the getUserMedia function is asynchronous, so any code that depends on using the audio or video must be put in a callback function, not the main script.
See https://developer.mozilla.org/en-US/docs/Web/API/Navigator.getUserMedia for an example of how to write cross-browser code for audio/video input.
Something like this:
function success(stream) {
// we have it
}
function fail(error) {
console.log(error);
if (error === 'NO_DEVICES_FOUND') {
// NO_DEVICES_FOUND (no microphone or microphone disabled)
}
}
navigator.getUserMedia({ audio: true }, success, fail);
Try this
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
// Code for success
}).catch(err => {
if(err.includes("NotFoundError: Requested device not found"))
alert("Mic not detected")
else alert("Error recording audio")
})
If the mic is not detected or unplugged means the catch statement will be executed. You can show your error message here.
You can use this link
I used this method
developer.mozilla.org

Is it possible to trigger share menu on smartphones (via HTML/JS)?

Is there an existing possibility to trigger the share functionality in local browsers on smartphones via HTML or JavaScript?
Of course there are many services which provide a share button. But when I e.g. want to share a website on facebook, I need to be logged in to facebook in the browser I am currently using.
Almost all browsers got an own share functionality build in, which triggers a system menu to choose which app you want to use to share:
This question is about: How to trigger this menu?
I know it is possible to trigger a phone call with a specified prefix in href attribute of links, like tel: or callto:. Maybe such a shortcut for this share menu is also existing? Or some javascript code? Or a totally different way how to do it?
Thanks in advance.
It is possible with a big catch. Currently only available in Chrome for Android, Samsung internet and on Safari (desktop and mobile). And support is coming to Edge and Chrome on desktop http://caniuse.com/#feat=web-share
if (navigator.share) {
navigator.share({
title: document.title,
text: "Hello World",
url: window.location.href
})
.then(() => console.log('Successful share'))
.catch(error => console.log('Error sharing:', error));
}
https://developers.google.com/web/updates/2016/10/navigator-share
I added this as all answers seems outdated by 2018-07-16.
It is possible, but only in a few browsers (MDN Reference), achieved througth the one method API in navigator:
navigator
.share({
title: document.title,
text: 'Hello World',
url: window.location.href
})
.then(() => console.log('Successful share! 🎉'))
.catch(err => console.error(err));
Google's reference: https://developers.google.com/web/updates/2016/10/navigator-share
Also, there was a thing called Web Intends which is a dead project, you should go with navigator.share instead.
It's now possible with the Web Share API!
However, it isn't widely supported as of yet. Currently, it's only available in Safari (mobile and desktop), and Chrome for Android. See Can I Use for details.
According to Introducing the Web Share API on Google Developers, there are several things to keep in mind:
your page needs to be served over HTTPS
you can only call navigator.share(…) in response to a user action, such as a click (i.e., you can't call it on page load)
you should feature-detect it in case it's not available on your users' platform (e.g., via navigator.share !== undefined)
The Google Developers article also notes that URLs shared with the Share API need not be on your own domain—you can share any URL.
Putting that all together, you could use something like this which uses the Share API if it's available, and falls back to sending an email if it's not*:
function createShareButton() {
const btn = document.createElement("button");
const title = document.title;
const text = "Check this out!";
const url = window.location.href;
btn.innerText = "share" in navigator ? "Share" : "Share via e-mail";
btn.onclick = () => {
if (navigator.share !== undefined) {
navigator
.share({
title,
text,
url
})
.then(() => console.log("Shared!"))
.catch(err => console.error(err));
} else {
window.location = `mailto:?subject=${title}&body=${text}%0A${url}`;
}
};
return btn;
}
document.title = "Demo";
document.body.appendChild(createShareButton());
*: Please do consider using a more appropriate fallback, (e.g., social sharing) depending on your use case.
Answered Apr 10 2013
To my knowledge, there is no such implementation in current browsers on mobile OS's. Since the question interested me - a google search revealed there is work being done in this direction:
https://dvcs.w3.org/hg/web-intents/raw-file/tip/spec/Overview.html
http://webintents.org/
Sorry - I do not know a workaround.
It is possible and I wrote a function to have pretty content to share and observe the asynchronous side effects:
const shareContact = async (title, content) => {
const text = `${title}
${content}`;
try {
await navigator.share({
text,
});
} catch (e) {
console.log(e);
}
};
You could use the WebView.addJavascriptInterface() method for android.
First you will need to write a class which fires the intent to open the share menu(take a look here) and then implement that class using the addJavascriptInterface() call. After that all you need to do is call the method from your Javascript.

Categories

Resources