getUserMedia block reload page after user change - javascript

Is it possible to detect that the user has 'enabled' the microphone/video for the webpage without having to get the user to refresh the page manually after an access denied & manual user enable?
basically it is disabled, when the user enables it I want to refresh the page automatically.
navigator.getUserMedia (
// 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) {
if(err === PERMISSION_DENIED) {
// Explain why you need permission and how to update the permission setting
}
}
);

Related

RTCmulticonnection use existing getUserMedia stream

I prepared a webcam streaming app and therefore previewed a users webcam in a video tag using "navigator.mediaDevices.getUserMedia".
After the user hits a button and "RTCmulticonnection" opens a room, I want to add the preview webcam / video to be used as webcam-stream.
I just don't get it working.
The part Im going to show you starts after the socket.io Connection is established - the "connection.open" method also returns that the room has been created and the connection is established. So Signaling works - I just don't know how to simply attach my Video to the (RTCmulsiconnection) connection Object.
I have tried to use the "attachStreams" method, but remained unsuccessfully.
//Get Users Webcam
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).then(function(stream) {
$("#mediaPreview").show();
let preview = document.getElementById('mediaPreviewVideo');
preview.srcObject = stream;
preview.volume = 0;
preview.play();
});
//Start stream
$("#btnMediaStreamStart").on('click', function(e) {
//Prevent Default & Hide
e.preventDefault();
//Add Classes
$("#mediaPreviewVideo").addClass('webcam-online');
$("#mediaStreamStatus").show().addClass('bg-success').html('<small><strong>Live</strong></small>');
connection.socketURL = 'localhost:9001/';
let connectionRoom = '123';
connection.open(connectionRoom, function(e) {
if (e === true) {
connection.attachStreams.forEach(function(localStream) {
//How to attach the cam stream? Is my previously created video even part of the "streams"?
});
connection.mediaConstraints = {
audio: {
deviceId: selectAudio
},
video: {
deviceId: selectVideo
}
};
}
});
Try using
connection.addStream(stream);
where stream is your already captured stream - perhaps via getUserMedia()

Detect if browser is waiting for media permission?

Is there a way in javascript to check if Browser(Any Browser) is waiting for user to Allow permission for Microphone or Camera?
Note:- Based on this, I want to determine if media permission was already saved. i.e. if permission is saved then the popup will not appear.
EDIT
MEDIA = ( navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia ||
navigator.getUserMedia );
get_user_media: function() {
jQuery("instruction_image_id").show();
(MEDIA.bind(navigator))(
{audio: true, video: false},
media_success(),
media_error()
);
}
media_success: function() {
jQuery("instruction_image_id").hide();
}
EDIT
Note:- I need a Cross Browser solution. THIS(Marked as duplicate) thread's solution works well only with Chrome.
The time between waiting can be checked here, see start and end of permission:
// Start the permission.
navigator.getUserMedia (
// constraints
{
video: true,
audio: true
},
// successCallback
function(localMediaStream) {
// End the permission
var video = document.querySelector('video');
video.src = window.URL.createObjectURL(localMediaStream);
video.onloadedmetadata = function(e) {
// Do something with the video here.
};
},
// errorCallback
function(err) {
if(err === PERMISSION_DENIED) {
// Explain why you need permission and how to update the permission setting
}
}
);

Calling getUserMedia with new constraints causes black screen (MediaStream.ended=true)

On my nexus4 (Android 4.4.4) I am trying to switch between 'user' facing camera and 'environment' facing camera.
Accessing either one directly works.
Switching between them bij making another call to navigator.getUserMedia() setting new constraints fails. The failure results in a black screen video & MediaStream.ended=true.
Why is MediaStream.ended=true on my second call to getUserMedia?
In my view I dynamically create buttons for the number of video sources. Two in this case. Clicking the buttons will call camera.getUserMedia() and passes in a media source:
camera.getUserMedia = function(source){
var constraints = {
video: true,
audio: false
};
if(source){
constraints.video = {optional: [{
sourceId: source.id
}]};
}
navigator.getMedia(
constraints,
function(stream) {
var vendorURL = window.URL || window.webkitURL;
video.src = vendorURL.createObjectURL(stream);
video.play();
streaming = true;
},
function(err) {
...
}
);
};
I have solved this problem by storing the stream on the camera object and then before binding the stream to the video element I will call stop on it. Not really sure what is exactly happening though (maybe somebody can add the explanation in the comments).
camera.getUserMedia = function(source){
if(camera.stream){
camera.stream.stop();
}
...
navigator.getMedia(
constraints,
function(stream) {
camera.stream = stream;
...
},
function(err) {
...
}
);
};

WebRTC works in Chrome but not Firefox

I read several other questions on a related issue, but none answered my question. I have an odd issue where I am able to use WebRTC to audio chat from chrome to firefox but not firefox to chrome.
Basically, when a user wishes to audio chat, he/she clicks a button #audioChatBtn, which uses getUserMedia() to setup a stream. The thing is, clicking #audioChatBtn from Firefox doesn't fire the onaddstream callback on Chrome, but clicking the button from Chrome fires onaddstream on Firefox. Thus, I can audio chat from Chrome to Firefox but not the other way around. I have been trying to figure this out for several hours, but I'm hoping maybe someone here has an answer.
Relevant source:
var configuration = {
'iceServers': [
{ url: 'stun:stun.l.google.com:19302' },
{ url: 'stun:stun1.l.google.com:19302' },
{ url: 'stun:stun2.l.google.com:19302' },
{ url: 'stun:stun3.l.google.com:19302' },
{ url: 'stun:stun4.l.google.com:19302' }
]
};
var pc = RTCPeerConnection(configuration);
var myStream = null;
var currentAudioIndex = 0; // Number of created channels
var myAudioEnabled = false;
// send any ice candidates to the other peer
pc.onicecandidate = function (evt) {
if (evt.candidate)
$(document).trigger("persistState", { mode: 'rtc', 'candidate': evt.candidate });
};
// let the 'negotiationneeded' event trigger offer generation
pc.onnegotiationneeded = function () {
pc.createOffer(localDescCreated, logError);
}
// once remote stream arrives, play it in the audio element
pc.onaddstream = function (evt) {
console.log('creating and binding audio');
var idx = (currentAudioIndex++);
var audioElement = $('#audio' + idx);
if (audioElement.length == 0) {
var audio = $('<audio id="audio' + idx + '" autoplay>');
$('body').append(audio);
audioElement = $('#audio' + idx);
}
var audioObject = audioElement[0];
attachMediaStream(audioObject, evt.stream);
};
function localDescCreated(desc) {
pc.setLocalDescription(desc, function () {
$(document).trigger("persistState", { mode: 'rtc', 'sdp': pc.localDescription });
}, logError);
}
function logError(e) {
bootbox.alert("Audio chat could not be started.");
}
function hasGetUserMedia() {
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
server.onPersist = function(msg) {
if (msg.mode == "rtc") {
if (msg.sdp)
pc.setRemoteDescription(new RTCSessionDescription(msg.sdp), function () {
// if we received an offer, we need to answer
if (pc.remoteDescription.type == 'offer')
pc.createAnswer(localDescCreated, logError);
}, logError);
else
pc.addIceCandidate(new RTCIceCandidate(msg.candidate));
}
}
// On click, start audio chat from this user.
$('#audioChatBtn').click(function() {
if (!hasGetUserMedia()) {
bootbox.alert('Audio conferencing is not supported by your browser. (Currently only supported by Chrome, Firefox, and Opera web browsers.)');
return;
}
if (myAudioEnabled) {
myStream.stop();
displayAlert('Streaming closed', 'Audio chat is off');
$('#audioChatBtn').removeClass('btn-success').addClass('btn-primary');
} else {
getUserMedia({ video: false, audio: true }, function (localMediaStream) {
myStream = localMediaStream;
pc.addStream(localMediaStream);
displayAlert('Streaming...', 'Audio chat is enabled');
$('#audioChatBtn').removeClass('btn-primary').addClass('btn-success');
}, logError);
}
myAudioEnabled = !myAudioEnabled;
});
What I've tried
Tried using 'optional': [{ 'DtlsSrtpKeyAgreement': 'true' }] in the configuration after reading this question
Tried creating a new RTCPeerConnection() each request
Tried using native browser functions instead of adapter.js.
Explored Web Audio API instead of getUserMedia()
Firefox does not currently support onnegotiationneeded, because we currently don't support re-negotiation of an existing connection. All addStream/addTrack and a single createDataChannel (if you want to use them) need to be done before createOffer() or createAnswer. You can createDataChannel() after you connect, if you created on before createOffer.
Adding a stream after they're connected won't work.
An (annoying) alternative is to create a new set of PeerConnections to replace the old ones (using a DataChannel in the old pair as a signaling channel for lower latency)
Resolving this is high on our priority list, but will take a few more releases.
After a lot of debugging, I came to realize that the bug has nothing to do with my code but has to do with Firefox's implementation of WebRTC. Firefox doesn't trigger the onnegotiationneeded callback, so I have to do it hackily using a timeout (and hope that the stream information has been relayed to the remote client before the function fires). Obviously, this is a firefox bug and I will report it, hoping that they fix the bug in the next build.
getUserMedia({ video: false, audio: true }, function (localMediaStream) {
myStream = localMediaStream;
pc.addStream(localMediaStream);
displayAlert('Streaming...', 'Audio chat is enabled');
$('#audioChatBtn').removeClass('btn-primary').addClass('btn-success');
// Need this for Firefox
if (webrtcDetectedBrowser == 'firefox')
setTimeout(pc.onnegotiationneeded, 5000);
}, logError);

Desktop capture chrome plugin

I was developing a chrome plugin in which captures desktop screen. I am using the sample plugin example given here...
https://developer.chrome.com/extensions/samples#desktop-capture-example
But in this example as we click the start button a dialog pop ups which asks the user which screen or window to share but I want to share my current screen what changes do I make in
this code
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function gotStream(stream) {
console.log("Received local stream");
var video = document.querySelector("video");
video.src = URL.createObjectURL(stream);
localstream = stream;
stream.onended = function() { console.log("Ended"); };
}
function getUserMediaError() {
console.log("getUserMedia() failed.");
}
function onAccessApproved(id) {
if (!id) {
console.log("Access rejected.");
return;
}
navigator.webkitGetUserMedia({
audio:false,
video: { mandatory: { chromeMediaSource: "desktop",
chromeMediaSourceId: id } }
}, gotStream, getUserMediaError);
}
var pending_request_id = null;
document.querySelector('#start').addEventListener('click', function(e) {
pending_request_id = chrome.desktopCapture.chooseDesktopMedia(
["screen"], onAccessApproved);
});
document.querySelector('#cancel').addEventListener('click', function(e) {
if (pending_request_id != null) {
chrome.desktopCapture.cancelChooseDesktopMedia(pending_request_id);
}
});
what should be the value of the chromeMediaSourceId so that the default selection is the current screen;
basically i want to avoid this screen ..
Plz help...
Regards
You can't do this. The manifest permission allows you to provide this feature but the user still has to select the screen and hit share.
Like others said, this is a security feature to prevent your extension from triggering this without informing the user.

Categories