How to add audio/video mute/unmute buttons in WebRTC video chat
Asked Answered
M

3

15

I'm trying to create WebRTC video chat. Now I'm stacked on creating media-tracks buttons (mute video to enable or disable video sending, and mute audio to make the same with audio). Here is my code.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
  <script type="text/javascript" src="http://cdn.peerjs.com/0.3/peer.min.js"></script>
  <script>
  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

  var myStream;
  var peer = new Peer({key: 'PeerJS key'});
  var setOthersStream = function(stream){
    $('#others-video').prop('src', URL.createObjectURL(stream));
  };

  var setMyStream = function(stream){
    myStream = stream;
    $('#video').prop('src', URL.createObjectURL(stream));

  };

  peer.on('open', function(id){
    $('#peer-id').text(id);
  });

  peer.on('call', function(call){
    call.answer(myStream);
    call.on('stream', setOthersStream);
  });

  $(function(){
    navigator.getUserMedia({audio: true, video: true}, setMyStream, function(){});

    $('#call').on('click', function(){
      var call = peer.call($('#others-peer-id').val(), myStream);
      call.on('stream', setOthersStream);
    });
  });

  peer.on('error', function(e){
    console.log(e.message);
  });

Can anyone guide me please?

Mossbunker answered 26/12, 2015 at 8:9 Comment(0)
M
16

finally I got it work! The first answer for question from this "webrtc video stream stop sharing" guided me to the right direction. I created two new functions to mute video and audio, and bound them to appropriate buttons in html file. And finally it became look like this:

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

var myStream;
var peer = new Peer({key: 'PeerJS key'});

var setOthersStream = function(stream){
  $('#others-video').prop('src', URL.createObjectURL(stream));
};

var setMyStream = function(stream){
  myStream = stream;
  $('#video').prop('src', URL.createObjectURL(stream));
};

peer.on('open', function(id){
  $('#peer-id').text(id);
});

peer.on('call', function(call){
  call.answer(myStream);
  call.on('stream', setOthersStream);
});

$(function(){
  navigator.getUserMedia({audio: true, video: true}, setMyStream, function(){});
  $('#call').on('click', function(){
    var call = peer.call($('#others-peer-id').val(), myStream);
    call.on('stream', setOthersStream);
  });
});

peer.on('error', function(e){
  console.log(e.message);
});

//create button to toggle video
var video_button = document.createElement("video_button");
video_button.appendChild(document.createTextNode("Toggle hold"));

video_button.video_onclick = function(){
  myStream.getVideoTracks()[0].enabled = !(myStream.getVideoTracks()[0].enabled);
}

var audio_button = document.createElement("audio_button");
video_button.appendChild(document.createTextNode("Toggle hold"));

audio_button.audio_onclick = function(){
  myStream.getAudioTracks()[0].enabled = !(myStream.getAudioTracks()[0].enabled);
}

Hope it will help to someone.

Mossbunker answered 29/12, 2015 at 6:45 Comment(2)
Hello, I am coming here after reading The evolution of webRTC and failing to make it work. While this thing is just simpler, and just works. Can someone please confirm which is the standard way, and which one should i use! Thanks a ton :DPreternatural
work perfect bro, just disable local video stream, the remote peers will cannot see videoBernie
F
21

The video and audio tracks in your stream have an enabled attribute you can modify. E.g.:

function muteMic() {
  myStream.getAudioTracks().forEach(track => track.enabled = !track.enabled);
}

function muteCam() {
  myStream.getVideoTracks().forEach(track => track.enabled = !track.enabled);
}
Freespoken answered 27/12, 2015 at 21:25 Comment(8)
This will stop both video and audio streams. That's not what the question asked.Epps
@NafiuLawal It merely pauses (mutes) them, but yes, I've updated the answer to mute camera and microphone independently. Thanks!Freespoken
This approach doesn't work for me, webcam LED is still onNoctilucent
@LevKostychenko If you use Firefox this doesn't happen. If you're using Chrome, this is crbug.com/642785.Freespoken
@Freespoken but how google solved this problem for google meet e.g.&Noctilucent
@LevKostychenko I believe they use this answer for microphone, but probably stop() the camera track and call getUserMedia to get camera again on unmute to avoid the light. This should work in most modern browsers (even Firefox has a 60 minute grace period). I also found Firefox has the same bug on Windows now.Freespoken
@Freespoken yep, calling getUserMedia should help in this case but for me even when I call getUserMedia, an interlocutor still gets the previous stream (I decided so, looking at stream id) what causes the error? Maybe you know how to pass the newly created stream into existing peer? I've already asked this question: #75316037Noctilucent
@LevKostychenko you can try replaceTrack.Freespoken
M
16

finally I got it work! The first answer for question from this "webrtc video stream stop sharing" guided me to the right direction. I created two new functions to mute video and audio, and bound them to appropriate buttons in html file. And finally it became look like this:

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

var myStream;
var peer = new Peer({key: 'PeerJS key'});

var setOthersStream = function(stream){
  $('#others-video').prop('src', URL.createObjectURL(stream));
};

var setMyStream = function(stream){
  myStream = stream;
  $('#video').prop('src', URL.createObjectURL(stream));
};

peer.on('open', function(id){
  $('#peer-id').text(id);
});

peer.on('call', function(call){
  call.answer(myStream);
  call.on('stream', setOthersStream);
});

$(function(){
  navigator.getUserMedia({audio: true, video: true}, setMyStream, function(){});
  $('#call').on('click', function(){
    var call = peer.call($('#others-peer-id').val(), myStream);
    call.on('stream', setOthersStream);
  });
});

peer.on('error', function(e){
  console.log(e.message);
});

//create button to toggle video
var video_button = document.createElement("video_button");
video_button.appendChild(document.createTextNode("Toggle hold"));

video_button.video_onclick = function(){
  myStream.getVideoTracks()[0].enabled = !(myStream.getVideoTracks()[0].enabled);
}

var audio_button = document.createElement("audio_button");
video_button.appendChild(document.createTextNode("Toggle hold"));

audio_button.audio_onclick = function(){
  myStream.getAudioTracks()[0].enabled = !(myStream.getAudioTracks()[0].enabled);
}

Hope it will help to someone.

Mossbunker answered 29/12, 2015 at 6:45 Comment(2)
Hello, I am coming here after reading The evolution of webRTC and failing to make it work. While this thing is just simpler, and just works. Can someone please confirm which is the standard way, and which one should i use! Thanks a ton :DPreternatural
work perfect bro, just disable local video stream, the remote peers will cannot see videoBernie
D
8

Use MediaStreamTrack.enabled.

let mic_switch = true;
let video_switch = true;

function toggleVideo() {
  if(localStream != null && localStream.getVideoTracks().length > 0){
    video_switch = !video_switch;

    localStream.getVideoTracks()[0].enabled = video_switch;
  }

}

function toggleMic() {
  if(localStream != null && localStream.getAudioTracks().length > 0){
    mic_switch = !mic_switch;

    localStream.getAudioTracks()[0].enabled = mic_switch;
  }     

Same for remote stream also.

Domiciliate answered 7/4, 2020 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.