I'm trying to take video and audio from my webcam using getMedia(), but my browser always block the function. I'm using Google Chrome, and this icon appears near Favorite Icon: http://puu.sh/4pLAk.png
The JS is an example of MDN: https://developer.mozilla.org/en-US/docs/Web/API/Navigator.getUserMedia
HTML:
<!DOCTYPE html>
<html>
<body>
<button onClick="getMedia()">Ok</button>
<body>
<html>
JS:
function getMedia()
{
navigator.getMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
navigator.getMedia (
// constraints
{
video: true,
audio: true
},
// successCallback
function(localMediaStream) {
var video = document.querySelector('video');
video.src = window.URL.createObjectURL(localMediaStream);
video.onloadedmetadata = function(e) {
// Do something with the video here.
};
},
// errorCallback
function(err) {
console.log("The following error occured: " + err);
}
);
}
What I'm doing wrong?
When prompted for camera or mic access and you hit the "Deny" button, Chrome will save that choice on future calls to getUserMedia on that site. Yo'll want to click on the video icon that you mentioned and change the permissions to allow camera and/or mic access. See this page for an example of what this looks like.
I encountered similar problem, but related to microphone access.
As tom vLine answered, Chrome blocks device access if you serve your file via file://(note that on Microsoft Edge and Firefox it worked via file:://).
One solution i've found for Chrome:
open chrome an type in the URL chrome://version/
copy the value of "Command Line" field in your command line and append
--allow-file-access-from-files and run it
after Chrome opened and enter your file:// url.
For starting Chrome always like that, right click on Chrome icon, and then click on properties. In the Shortcut tab append to the Target value all the command line parameters from 2.
Hope this helped someone :-)
Related
How can I access the webcam from my chrome extension?
Whenever I try to access the camera from a regular html file it seems to be working fine but when I use the same code in my extension it doesn't work.
In order to be able to access the webcam you need to get permission which you cannot do from the contents.js, but what you can do is create a button in the options page which requests the permission.
Here are the steps:
1)
Create an options.html file and add a reference to the manifest.json like this:
"options_page": "options.html"
2)
Create an options.js file, link it in the options.html file and add a button that will trigger the request for webcam access by adding the following lines:
<button id="requestPermission">Click for permission prompt</button>
<script src="options.js"></script>
Inside the options.js file add the following lines:
let button = document.getElementById('requestPermission');
button.onclick = ()=>{
console.log('ya');
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({ audio: false, video: { width: 1280, height: 720 } },
(stream) => {
console.log('success');
},
(err) => {
console.error(`The following error occurred: ${err.name}`);
}
);
} else {
console.log("getUserMedia not supported");
}
};
After following these steps you can right click your extension's icon and press options, this will open the options page where you can press the button and allow the extension to use the camera.
I have a webpage served via https with the following script:
const userMediaConstraints = {
video: true,
audio: true
};
navigator.mediaDevices.getUserMedia(userMediaConstraints)
.then(stream => {
console.log("Media stream captured.")
});
When I open it in Firefox or Safari, a prompt asking for permission to use camera and microphone appears. But not in Chrome or Opera. There the access is blocked by default and I have to go to site settings and manually allow the access, which is set to Default(ask).
window.isSecureContext is true.
navigator.permissions.query({name:'camera'}) resolves to name: "video_capture", onchange: null, state: "prompt".
It looks like Chrome and Opera should show prompt, but they do not. I tested it on a different machine with different user that had no prior history with the website with the same result.
What could be wrong?
You've said you've tried Safari, which suggests to me you're on a Mac.
This issue on the Chrome issues list fits your description really well. (I got there from this on the webrtc/samples GitHub project.) It comes down to a Mac OS security setting. Quoting comment #3:
Please check in Mac system preferences > Security & Privacy > Privacy > Microphone, that Chrome is checked.
(In your case since you want video, you'd also probably have to tick the box under Security & Privacy > Privacy > Camera or similar.)
It turns out, having video with autoplay attribute in HTML or similar lines on page load in Javascript prevent Chrome from showing the prompt.
HTML that causes this problem:
<video autoplay="true"></video>
Javascript that causes this problem:
localVideo = document.createElement('video');
videoContainer.append(localVideo);
localVideo.setAttribute('id','localVideo');
localVideo.play();
My guess is that the issue has to do with Chrome autoplay policy. Perhaps, Chrome treats my website as providing bad user experience and blocks the prompt?
I removed <video> from HTML and altered Javascript to create a relevant DOM on getUserMedia:
let localStream = new MediaStream();
let localAudioTrack;
let localVideoTrack;
let localVideo;
const userMediaConstraints = {
video: true,
audio: true
};
navigator.mediaDevices.getUserMedia(userMediaConstraints)
.then(stream => {
localAudioTrack = stream.getAudioTracks()[0];
localAudioTrack.enabled = true;
localStream.addTrack(localAudioTrack);
localVideoTrack = stream.getVideoTracks()[0];
localVideoTrack.enabled = true;
localStream.addTrack(localVideoTrack);
localVideo = document.createElement('video');
videoContainer.append(localVideo);
localVideo.setAttribute('id','localVideo');
localVideo.srcObject = localStream;
localVideo.muted = true;
localVideo.play();
});
And now I get the prompt.
I want to get a video from the webcam using JS but no footage.
MESSAGE:
DOMException: Could not start video source
App.js
const video = document.getElementById("video");
function startVideo() {
navigator.getUserMedia(
{
video: {}
},
stream => (video.srcObject = stream),
err => console.log(err)
);
}
startVideo();
index.html
...
<body>
<video id="video" width="720" height="540" autoplay muted></video>
</body>
...
thanks for your help
If anyone else is having this problem and nothing else helps. Make sure that your camera is not already claimed/used by a different software/browser.
TLDR: I have tested your code and had to change it a bit:
https://codepen.io/puradawid/pen/PoqxzPQ
It looks like the problem lays here:
navigator.getUserMedia({
video: {}
},
stream => { video.srcObject = stream },
err => console.log(err)
);
Regarding to docs navigator.getUserMedia is deprecated and there is navigator.mediaDevices.getUserMedia that supports it. However, changing that up doesn't solve the correct problem which is your callback functions. This method returns Promise that is controlled by .then(), so changing it allows me to see my face in codepen:
navigator.mediaDevices.getUserMedia({
video: true
}).then(
stream => (video.srcObject = stream),
err => console.log(err)
);
I ran into this problem on certain android devices (Sony XA2) when trying to toggle the camera on a mobile browser because I am calling navigator.mediaDevices.getUserMedia repeatedly on each camera toggle.
The solution that I found was to make sure to stop all the tracks in previous streams that you created.
this.stream.getTracks().forEach(t => {
t.stop();
this.stream.removeTrack(t);
});
Without the previous code you can't seem to toggle camera on certain Android devices: (Demo),
(Code)
The error shown was DOMException: Requested device not found
By stopping previous tracks: you are able to start a new stream:
(Demo)
Code
Note: The following code snippet doesn't seem to execute in stack overflow due to security restrictions, so please use the jsfiddle links.
class Camera {
constructor({ video }) {
this.facingMode = "environment";
this.video = video;
video.onloadedmetadata = () => {
video.play();
};
}
async toggleCamera() {
if (this.facingMode === "environment") {
this.facingMode = "user";
} else {
this.facingMode = "environment";
}
try {
if (this.stream){
/* On some android devices, it is necessary to stop the previous track*/
this.stream.getTracks().forEach(t => t.stop());
}
this.stream = await navigator.mediaDevices.getUserMedia({
video: {
facingMode: this.facingMode,
}
});
} catch (e) {
console.error(e);
}
this.video.srcObject = this.stream;
}
}
const camera = new Camera({
video: document.querySelector("video"),
});
const button = document.querySelector("button");
button.addEventListener('click', () => {
camera.toggleCamera();
});
<button>
Toggle Camera
</button>
<video></video>
In Windows 10 go to settings->privacy->App permission(left side)->Microphone-> enable 'Allow apps to access your microphone'
After that retry with your JS program....It will work!!
If anyone have such an error and you are working on a laptop. You can try bending your laptop monitor in both directions. Sometimes the cable comes loose. This helped in my case.
Also look into Feature-Policy HTTP header, both on the website and on the host web server config, and make sure camera access is allowed.
I have tried all the other solution but nothing is work. Then finally i need to uninstall my camera driver in Device Manager and then scan for hardware changes. Try to run the app again and it's working.
I'm building electron desktop app in windows 10.
electron: 15.3.0
Source video that helped me: https://www.youtube.com/watch?v=XE2ULFlzkxw
I went to the browser settings for camera and noticed that the default camera was showing as "Leap Motion" which is not a standard camera device. I changed to an actual webcam and the problem was solved.
Sometimes this type of error also appears when you try to make a peer-to-peer call system and your tests are done on the same device. The camera is already used by the initiator and the receiver can no longer activate the camera.
I created an audio object and want to play it when user leave the window. So, my code is here:
$('body').on('mouseleave', function(){
var audio = new Audio( 'quite-impressed.mp3' )
audio.play()
})
It works well in Firefox. It also works in Chrome if I click in the page and then leave mouse outside of the body. But, when I leave the mouse without clicking in the page an error showed in the console and the audio does not play
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first. https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
But, in this example site it works fine without interacting with the page. How can I make it possible? Thanks in advance.
It seems they use an AudioContext to play that sound.
Chrome did came back a few months ago about blocking the AudioContext API, because a lot of fair uses were not prepared for such restriction and thus got broken by it.
But M71, which will get released in December 2018 will reenable that restriction, you can read about it here: https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio
// this will work in Chrome < 70 but not af
onmouseout = e => {
const ctx = new AudioContext();
const osc = ctx.createOscillator();
osc.connect(ctx.destination);
osc.start(0);
osc.stop(1);
}
Outsourced live example, since Stacksnippets are always granted the user gesture anyway: https://jsfiddle.net/zy3ev8ka/
Try this:
window.audio = new Audio( 'quite-impressed.mp3' )
$('body').on('mouseleave', function(){
audio.play()
})
This worked for me on Chrome 77:
On address bar: chrome://settings/content/sound
Turn off "Allow sites to play sound (recommended)"
Turn it on again
if your js play function is not running and if your code is correct then this may help,you have to allow your browser to get that sound file
just goto settings =>privacy and security => site-settings =>sound.
and then add your local url at add to play section..
As far as I know the only way to capture audio from user microphone at real time is by using Flash plugin (need to get user permission) or Java.
Does someone know any other way like HTML5 or JavaScript? All my program is built with HTML5 and I don't want to use another technology.
You can use navigator.getUserMedia.
For example:
(function(){
getMedia = ( navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
getMedia(
{
video: false,
audio: true
},
function (localMediaStream) {
var video = document.createElement('video');
video.src = window.URL.createObjectURL(localMediaStream);
video.onloadedmetadata = function(e) {
//deal with data
};
},
function (err) {
console.log("The following error occured: " + err);
}
);
})();
See Mozilla Developer Network for more info.
Note: This only works in Chrome, recent Firefox (20+), and Opera (12+), but not in Internet Explorer.