Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webRTC: Add audio later or disable microphone using peerJS

I am currently writing an application that enables user to start a video call via webRTC using peerJS. Now I want users to be able to decide if they want add audio or not, but without restarting the call.

As I see it - and according to this answer - there is no way to control the microphone using the browser. Suppose I start the call with video and audio enabled I could mute the video element on the partners side. I don't want to do that. Why? I imagine that somebody could use the developer console of the browser and unmute the video element, thus spying on the caller without his or her knowledge.

So for now it seems that I would have to re-call the partner and activate both, video and audio, now if the user wants video only I would have to re-call again.

My question: Is there a better way to do it? Also, if answering the call is there a way to determine wether it is a video-only or a video and audio call?

like image 371
stiller_leser Avatar asked Apr 01 '14 10:04

stiller_leser


2 Answers

By accident I found this blog post from Mozilla. The interesting part starts beneath the headline "Muting audio and video streams". Here you will find the following line of code:

mediaStream.getVideoTracks()[0].enabled = !(mediaStream.getVideoTracks()[0].enabled);

That basically means that you can disable the Video-Track. As it turns out, the same is possible with:

mediaStream.getAudioTracks()[0].enabled = false;

Which will mute the audio stream. If this is applied to the localStream like so:

Participant.prototype.startCall = function(){

     var participant = this;

     var target = participant.callees[0];

     navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

     navigator.getUserMedia({
          audio: true,
          video: true
     },function(stream){
          console.log("called");
          //IMPORTANT LINE HERE
          stream.getAudioTracks()[0].enabled = false;
          participant.localStream = stream;
          participant.call = participant.peer.call(target, stream);
     },function(error){
          console.log(error);   
     });
};

it seems to disable the audio stream. As you can see I store the localStream as a property of my object and am later able to activate the audio-stream by using

myObj.localStream.getAudioTracks()[0].enabled = true;

As far as I can judge you can't do the same operation on the remoteStream. But I will have to verify this thru further testing.

like image 87
stiller_leser Avatar answered Oct 03 '22 00:10

stiller_leser


It seems like what you're looking for is a way to revoke access to the microphone or webcam, so that the data stream ceases, indicator light goes off, and if the camera is re-activated, the user is prompted again.

According to the W3C WebRTC Spec, you should be able to do this:

A script can indicate that a track no longer needs its source with the MediaStreamTrack.stop() method. When all tracks using a source have been stopped, the given permission for that source is revoked and the source is stopped. If the data is being generated from a live source (e.g., a microphone or camera), then the user agent should remove any active "on-air" indicator for that source.

In the peerJS API docs there is no mention of the stop() method, but you should be able to call it on the browser's WebRTC implementation, using the stream that you pass to peerJS's call() function, which I'll call stream:

var s = function(t) {
    t.stop();
}
stream.getAudioTracks().map(s);

This should cause the browser to revoke audio access.

However, I would not be too concerned about the security of leaving an open WebRTC connection in the user's browser. If someone was able to hack into the browser, they already will have access to the user's unencrypted passwords, and the camera indicator (if available) will be on in any event.

Good luck!

like image 37
drnugent Avatar answered Oct 03 '22 00:10

drnugent