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.
Related
I am testing Agora features for a web app that already uses webRTC. Currently, it works with one separate track for audio and two video tracks: one for the camera and another for the screen share.
When I tried to share the screen I couldn`t publish it without unpublish the camera track, like the doc for 4.x sdk version says: https://docs.agora.io/en/video-calling/develop/product-workflow?platform=web
Agora.io screen share sequence diagram
How can I solve this? For me appears to be a typical case on a video chat, where one user shares his screen and keeps showing his audio and video to present something.
My code:
async startScreenShare(id?: string): Promise<void> {
let stream: MediaStream;
if (!id) {
stream = await (navigator.mediaDevices as any).getDisplayMedia({
audio: false,
video: true,
});
} else {
const constraint = {
audio: false,
video: {
mandatory: {
chromeMediaSource: 'screen',
chromeMediaSourceId: id,
},
},
};
stream = await navigator.mediaDevices.getUserMedia(constraint as any);
}
const videoTrack = stream.getTracks()[0];
this.rtc.screenVideoTrack = AgoraRTC.createCustomVideoTrack({
mediaStreamTrack: videoTrack,
});
this.rtc.client.unpublish(this.rtc.localVideoTrack);
await this.rtc.client.publish(this.rtc.screenVideoTrack);
}
It is working but losing the camera track.
An AgoraRTCClient object can publish only one video track.
Create new AgoraRTCClient to publish another track.
See "Enable both screen sharing and video" section of Agora Docs.
I am using getusermedia to record audio in my website. I've included the javascript of getusermedia. The record function works fine on website but doesn't even popup for permission in when opened on mobile.
var constraints = {
audio: true,
video: false
}
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
permissiongiven = 1;
});
this is the sample code which prompt me for permission but doesn't work on mobile.
How can I make it work on both device. Any help is appreciated.
Thanks.
Edit :- The code is now working fine on mobile as well. Maybe it was solved from chrome updates or security certificates of website. Thanks all for help.
Note that on mobile devices, you have to use SSL to use getUserMedia(). Check out if you're accessing your website with a http:// prefix. Try change it to https:// and it should work fine.
I found this website useful in answering this question
https://caniuse.com/#search=getusermedia
It says getUserMedia only supported from Chrome for Android version 70 (released Oct 16 2018)
Check MDN, then make sure your browser supports it. You need Chrome for Android 52+ it says. FWIW 68 works for me.
You should also feature-check and catch errors:
if (!navigator.mediaDevices) {
console.log("Sorry, getUserMedia is not supported");
return;
}
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => permissiongiven = 1)
.catch(error => console.log(error));
Depending on the error you get, we might learn more.
NotFoundError means no camera or mic detected on the device.
NotAllowedError means user permission not granted, or you're in an iframe or not https.
navigator.mediaDevices.getUserMedia Browser compatibility
i had no idea that navigator.getUserMedia was deprecated (at least for Samsung, which is what i was testing on), and i found this article on web audio with a code sample that i barely modified:
function initGetUserMedia() {
navigator.mediaDevices = navigator.mediaDevices || {}
navigator.mediaDevices.getUserMedia = navigator.mediaDevices.getUserMedia || function(constraints) {
let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia not supported by this browser'));
} else {
return new Promise((resolve, reject) => {
getUserMedia.call(navigator, constraints, resolve, reject);
});
}
}
}
Try this code with ssl site:
<script>var constraints = {audio: true, video: false}
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {{permissiongiven = 1;});</script>
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 want to capture video with the webcamera.
And there is the right decision:
window.onload = function () {
var video = document.getElementById('video');
var videoStreamUrl = false;
navigator.getUserMedia({video: true}, function (stream) {
videoStreamUrl = window.URL.createObjectURL(stream);
video.src = videoStreamUrl;
}, function () {
console.log('error');
});
};
but produces an error in the browser:
[Deprecation] URL.createObjectURL with media streams is deprecated and will be removed in M68, around July 2018. Please use HTMLMediaElement.srcObject instead. See https://www.chromestatus.com/features/5618491470118912 for more details.
how to use HTMLMediaElement.srcObject for my purposes ? Thanks for your time!
MediaElement.srcObject should allow Blobs, MediaSources and MediaStreams to be played in the MediaElement without the need to bind these sources in the memory for the lifetime of the document like blobURIs do.
(Currently no browser support anything else than MediaStream though...)
Indeed, when you do URL.createObjectURL(MediaStream), you are telling the browser that it should keep alive this Source until your revoke the blobURI, or until the document dies.
In the case of a LocalMediaStream served from a capturing device (camera or microphone), this also means that the browser has to keep the connection to this device open.
Firefox initiated the deprecation of this feature, one year or so ago, since srcObject can provide the same result in better ways, easier to handle for everyone, and hence Chrome seems to finally follow (not sure what's the specs status about this).
So to use it, simply do
MediaElement.srcObject = MediaStream;
Also note that the API you are using is itself deprecated (and not only in FF), and you shouldn't use it anymore. Indeed, the correct API to capture MediaStreams from user Media is the MediaDevices.getUserMedia one.
This API now returns a Promise which gets resolved to the MediaStream.
So a complete correction of your code would be
var video = document.getElementById('video');
navigator.mediaDevices.getUserMedia({
video: true
})
.then(function(stream) {
video.srcObject = stream;
})
.catch(function(error) {
console.log('error', error);
});
<video id="video"></video>
Or as a fiddle since StackSnippetsĀ® overprotected iframe may not deal well with gUM.
I'm on Chrome 25 successfully using getUserMedia and RTCPeerConnection to connect audio from a web page to another party, but I'm unable to get the API to stop the red blinking indication icon in the Chrome tab that media is being used on that page. My question is essentially a duplicate of Stop/Close webcam which is opened by navigator.getUserMedia except that the resolution there isn't working. If I have a page that just uses getUserMedia with no remote media (no peer), then stopping the camera turns off the blinking tab indicator. Adding remote streams seems to be a/the issue. Here's what I've currently got for my "close" code:
if (localStream) {
if (peerConnection && peerConnection.removeStream) {
peerConnection.removeStream(localStream);
}
if (localStream.stop) {
localStream.stop();
}
localStream.onended = null;
localStream = null;
}
if (localElement) {
localElement.onerror = null;
localElement.pause();
localElement.src = undefined;
localElement = null;
}
if (remoteStream) {
if (peerConnection && peerConnection.removeStream) {
peerConnection.removeStream(remoteStream);
}
if(remoteStream.stop) {
remoteStream.stop();
}
remoteStream.onended = null;
remoteStream = null;
}
if (remoteElement) {
remoteElement.onerror = null;
remoteElement.pause();
remoteElement.src = undefined;
remoteElement = null;
}
if (peerConnection) {
peerConnection.close();
peerConnection = null;
}
I've tried with and without the removeStream() call, I've tried with and without the stop() call, I've tried the element.src="" and element.src=null, I'm running out of ideas. Anyone know if this is a bug or user/my error in the use of the API?
EDIT: I set my default device (using Windows) to a camera that has a light when it's in use, and upon stopping, the camera light goes off, so perhaps this is a Chrome bug. I also discovered that if I use chrome://settings/content to change the microphone device to anything other than "Default", Chrome audio fails altogether. And finally, I realized that using element.src=undefined resulted in Chrome attempting to load a resource and throwing a 404 so that's clearly not correct... so back to element.src='' on that.
Ended up being my fault (yes, shocking). Turns out I wasn't saving localStream correctly in the onUserMediaSuccess callback of getUserMedia... once that was set, Chrome is turning off the blinking recording icon. That didn't explain the other anomalies, but it closes the main point of the question.
I just got this working yesterday after trawling through the WebRTC specification. I don't know if this is the "right" way to do it, but I found that renegotiating the PeerConnection with a new offer after removing the stream did the trick.
var pc = peerConnections[socketId];
pc.removeStream(stream);
pc.createOffer( function(session_description) {
pc.setLocalDescription(session_description);
_socket.send(JSON.stringify({
"eventName": "send_offer",
"data":{
"socketId": socketId,
"sdp": session_description
}
}));
},
function(error) {},
defaultConstraints);