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.
Related
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.
Trying to access IP Camera that is connected to a wifi.
I am connected to that wifi but I am getting error. If I try open using vlc I am able to connect but not getUserMedia has null.
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent {
#ViewChild('video') video: any;
constructor() {
}
hasGetUserMedia() {
return !!(navigator.mediaDevices &&
navigator.mediaDevices.getUserMedia);
}
ngAfterViewInit() {
if (this.hasGetUserMedia()) {
// Good to go!
console.log("Gooddd................");
} else {
alert('getUserMedia() is not supported by your browser');
}
let _video = this.video.nativeElement;
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(function (stream) {
_video.src = window.URL.createObjectURL(stream);
_video.play();
}).catch(function (err) {
console.log(err);
});
}
}
}
<video #video width="640" height="480" autoplay></video>
This happens when you dont have any device to capture video or capture audio
try checking if your webcam and your microphone are working fine
Try without "audio: true". Its help for my. (Microphone are not work).
And check webcam on other sites.
Maybe need check permissions for this page.
try changing this line:
_video.src = window.URL.createObjectURL(stream);
with this one:
_video.srcObject = stream;
Use this line to initialize the webcam and microphone:
navigator.mediaDevices.getUserMedia({ audio: true, video: true });
In my case i have connected external camera through USB i was able to get the devices, i was getting kind of devices as audiooutput and videoinput, and there was no audioinput(microphone device) but while i was requesting for devices i passed constraints as..
function Webcam(){
this.constraints = {
video: true,
audio: true
}
this.userMedia = null;
this.mediaDevices = navigator.mediaDevices;
this.initialize = function(){
this.userMedia = this.mediaDevices.getUserMedia(this.constraints);
}
}
let webcam = new Webcam();
webcam.initialize();
So Promise not satisified and getting error as Requested device not found.
Try attaching an earpiece or earplug with microphone to your PC. mine has no microphone that was why I got that error
This issue can also occur on some mobile devices (Sony XA2 running Android) if you had previously already created a MediaStream.
The solution that I found was to make sure to stop all the tracks of previous streams that you created.
this.stream.getTracks().forEach(t => {
t.stop();
// I don't think removeTrack is necessary, but just keeping it.
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: I also answered a related question here: https://stackoverflow.com/a/73550841/1123985
I have mic and camera but I was getting the same error. I was pretty sure that was related to laptop setting, because I tried everything. turns out my laptop was blocking access to the media. I am using linux and laptop brand name is MSI, I started to look for any sign that related to the camera setting. On F6 button, my laptop has a webcam icon. So I clicked on
fn + F6
It works now. most likely sometimes I click on fn+* keys to see any difference and I blocked the camera access.
I have a listener defined in my content script in chrome extension:
document.addEventListener("startRecording", function(data) {
chrome.runtime.sendMessage({'action' : 'captureCurrentTab'});
});
and have a function defined in my extension.js:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.action == "captureCurrentTab"){
captureCurrentTab();
}
});
function captureCurrentTab() {
chrome.tabs.getSelected(null, function(tab) {
chrome.tabCapture.capture(MediaStreamConstraint, handleCapture);
});
}
var MediaStreamConstraint = {
//audio: true,
video: true,
videoConstraints: {
mandatory: {
chromeMediaSource: 'tab',
minWidth: 1920,
maxWidth: 1920,
minHeight: 1080,
maxHeight: 1080
}
}
};
function handleCapture(stream) {
console.log('content captured');
console.log("Adding Stream: ", stream);
}
but when i send message to start recording from my web application like this:
var event = document.createEvent('Event');
event.initEvent('startRecording');
document.dispatchEvent(event);
then extension throws exceptions:
1) Error in response to tabCapture.capture: MediaStream is mandatory.
2) Unchecked runtime.lastError while running tabCapture.capture: Extension has not been invoked for the current page (see activeTab permission). Chrome pages cannot be captured.
Here are the permissions i have supplied:
"permissions": [
"tabCapture",
"tabs",
"activeTab",
"http://*/*",
"https://*/*" ,
"http://localhost:1615/*"
]
But when I click on my extension button and repeat the same process (send message for recording) then everything works fine. I don't know why I have to click extension button every time to start capturing screen.
How can I start it automatically?
I have also defined shortcut keys for my extension. When I press them before sending message for recording then everything works fine. but when I triggered/simulate them from my application then again end up with same exception.
Please help.
Problem here is that Chrome loses track of the fact that this event was initiated with a click. It is therefore not "invoked".
You should instead bind a click event listener in your content script code/context, and send the message from there directly. I think it should be enough for Chrome to accept that as invocation by the user.
Alternatively, direct sending of a message to the extension bypassing the content script may work. This is achievable with "externally_connectable" method (docs).
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 :-)
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.