RTCMultiConnection icon indicating copy to clipboard operation
RTCMultiConnection copied to clipboard

Android + Chrome - How to use Back-Camera?

Open Patrick-Vogt opened this issue 7 years ago • 3 comments

Hi Muaz,

is there a proper way to make sure that Chrome always uses the devices back-camera?

I tried to enumerate the devices like following:

navigator.mediaDevices.enumerateDevices()
  .then(gotDevices)
.catch(errorCallback);

var videodeviceId ;
var videolabel;
function gotDevices(deviceInfos) {
  var camcount = 1;   //used for labeling if the device label is not enumerated
  for (var i = 0; i !== deviceInfos.length; ++i) {
      if (deviceInfos[i].kind === 'videoinput') {
        videolabel=deviceInfos[i].label.split(' ')[1];
        //alert(deviceInfos[i].label + '//' +deviceInfos[i].deviceId);
        if (deviceInfos[i].label.match(/back/g) ||
            deviceInfos[i].label.match(/environment/g)) {
          videodeviceId= deviceInfos[i].deviceId;
        }
        else {
          videodeviceId= deviceInfos[i].deviceId;
        }
        camcount++;
      }
  }
}

After that, I use videodeviceid as value for the sourceid in the constraints:

var options = {
     localMediaConstraints: {
         audio: false,
            video: {
           optional: [ // Try width step by step until maximum
               {sourceId: videodeviceId},
               {minWidth: 320},
               {minWidth: 640},
               {minWidth: 800},
               {minWidth: 1024},
               {minWidth: 1280},
               {minWidth: 1600},
               {minWidth: 1920},
               {minWidth: 2560}
           ],
       }
     },

This works so far, the back-camera is used and set in the sourceid (deprecated, I know) but if I stop the stream and change the participants resolution, it shows the front cam again. Thats weird, Firefox is quite easy to use...

Does anyone have a solution? AdapterJs is included and I use the latest version of RTCmultiConnectionV3

Thank you!

Patrick-Vogt avatar Nov 29 '16 18:11 Patrick-Vogt

Please set facingMode (default is user i.e. v3 is forcing front-camera):

connection.mediaConstraints.video.optional = [{
    facingMode: 'application'
}];

Or override default settings:

connection.mediaConstraints.video.optional = [];

muaz-khan avatar Nov 30 '16 03:11 muaz-khan

Thank you Muaz, I changed it in the RTCmulticonnection.js, but I still need to use the explicit SouceID from the Device to access the back-camera... I've read, that this is a quite new problem from Chrome and AdapterJS still can't handle this.

The main problem is, that chrome shows a black camera-screen or the front-camera after an renegotiate/ change of the resolution with a "cut" .

This issue seems appear in the localMediaConstraints, because the sourceId can't be put in within the "options" and my resolution check with the "minWidth" (Detection of the cameras highest possible resolution) needs to be there, otherwise I'll get an overconstraint error...

I hope the standardization phase will be completed soon, that drives me crazy.

Patrick-Vogt avatar Nov 30 '16 20:11 Patrick-Vogt

Where I can use this code :- connection.mediaConstraints.video.optional = [{ facingMode: 'application' }];

in my code

(function( $ ) {
    'use strict';
    
    document.getElementById('open-room').onclick = function() {
        disableInputButtons();
        connection.open(document.getElementById('room-id').value, function() {
            showRoomURL(connection.sessionid);
        });
    };

    document.getElementById('join-room').onclick = function() {
        disableInputButtons();

        connection.sdpConstraints.mandatory = {
            OfferToReceiveAudio: true,
            OfferToReceiveVideo: true
        };
        connection.join(document.getElementById('room-id').value);
    };

  var connection = new RTCMultiConnection();

  connection.socketURL = '/';

  connection.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/';

  connection.socketMessageEvent = 'video-broadcast-demo';
  var user_id = document.getElementById('join-room').value
  connection.extra = {
    user_id:user_id
  };
  connection.session = {
      audio: true,
      video: true,
      oneway: true
  };

  connection.sdpConstraints.mandatory = {
      OfferToReceiveAudio: false,
      OfferToReceiveVideo: false
  };

  connection.iceServers = [{
      'urls': [
          'stun:stun.l.google.com:19302',
          'stun:stun1.l.google.com:19302',
          'stun:stun2.l.google.com:19302',
          'stun:stun.l.google.com:19302?transport=udp',
      ]
  }];

  connection.videosContainer = document.getElementById('videos-container');
  connection.onstream = function(event) {
      var existing = document.getElementById(event.streamid);
      if(existing && existing.parentNode) {
        existing.parentNode.removeChild(existing);
      }

      event.mediaElement.removeAttribute('src');
      event.mediaElement.removeAttribute('srcObject');
      event.mediaElement.muted = true;
      event.mediaElement.volume = 0;

      var video = document.createElement('video');

      try {
          video.setAttributeNode(document.createAttribute('autoplay'));
          video.setAttributeNode(document.createAttribute('playsinline'));
          video.setAttributeNode(document.createAttribute('controls'));
          video.setAttributeNode(document.createAttribute('controlslist'));
          // video.setAttributeNode(document.createAttribute('audio'));
      } catch (e) {
          video.setAttribute('autoplay', true);
          video.setAttribute('playsinline', true);
          video.setAttribute('controls', true);
          video.setAttribute('audio', true);
      }

      if(event.type === 'local') {
        video.volume = 0;
        try {
            video.setAttributeNode(document.createAttribute('muted'));
        } catch (e) {
            video.setAttribute('muted', true);
        }
      }
      video.srcObject = event.stream;


      var width = parseInt(connection.videosContainer.clientWidth / 3) - 20;
      var mediaElement = getHTMLMediaElement(video, {
          title: event.userid,
          buttons: ['full-screen'],
          width: width,
          showOnMouseEnter: false
      });

      connection.videosContainer.appendChild(mediaElement);
      $('.wth_live_btn').attr('style', 'display:inline !important;');
      $('.tlm_img_chat').attr('style', 'display:inline !important;');

      // setTimeout(function() {
      //     mediaElement.media.play();
      // }, 5000);

      mediaElement.id = event.streamid;
  };

  connection.onstreamended = function(event) {
    connection.mediaConstraints.video.optional = [{
        facingMode: 'application'
    }];
      var mediaElement = document.getElementById(event.streamid);
      if (mediaElement) {
          mediaElement.parentNode.removeChild(mediaElement);

          if(event.userid === connection.sessionid && !connection.isInitiator) {
            alert('Broadcast is ended. We will relo1ad this page to clear the cache.');
            location.reload();
          }
      }
  };

  connection.onMediaError = function(e) {
      if (e.message === 'Concurrent mic process limit.') {
          if (DetectRTC.audioInputDevices.length <= 1) {
              alert('Please select external microphone.');
              return;
          }

          var secondaryMic = DetectRTC.audioInputDevices[1].deviceId;
          connection.mediaConstraints.audio = {
              deviceId: secondaryMic
          };

          connection.join(connection.sessionid);
      }
  };

  function disableInputButtons() {
      document.getElementById('room-id').onkeyup();
      document.getElementById('room-id').disabled = true;
  }

  function showRoomURL(roomid) {
      var roomHashURL = '#' + roomid;
      var roomQueryStringURL = '?roomid=' + roomid;

      var html = '<h2>Unique URL for your room:</h2><br>';

      html += 'Hash URL: <a href="' + roomHashURL + '" target="_blank">' + roomHashURL + '</a>';
      html += '<br>';
      html += 'QueryString URL: <a href="' + roomQueryStringURL + '" target="_blank">' + roomQueryStringURL + '</a>';

      // var roomURLsDiv = document.getElementById('room-urls');
      // roomURLsDiv.innerHTML = html;

  }

  (function() {
      var params = {},
          r = /([^&=]+)=?([^&]*)/g;

      function d(s) {
          return decodeURIComponent(s.replace(/\+/g, ' '));
      }
      var match, search = window.location.search;
      while (match = r.exec(search.substring(1)))
          params[d(match[1])] = d(match[2]);
      window.params = params;
  })();

  var roomid = '';
  if (localStorage.getItem(connection.socketMessageEvent)) {
      roomid = localStorage.getItem(connection.socketMessageEvent);
  } else {
      roomid = connection.token();
  }
  // document.getElementById('room-id').value = roomid;
  document.getElementById('room-id').onkeyup = function() {
      localStorage.setItem(connection.socketMessageEvent, document.getElementById('room-id').value);
  };

  var hashString = location.hash.replace('#', '');
  if (hashString.length && hashString.indexOf('comment-') == 0) {
      hashString = '';
  }

  var roomid = params.roomid;
  if (!roomid && hashString.length) {
      roomid = hashString;
  }

  if (roomid && roomid.length) {
      // document.getElementById('room-id').value = roomid;
      localStorage.setItem(connection.socketMessageEvent, roomid);

      // auto-join-room
      (function reCheckRoomPresence() {
          connection.checkPresence(roomid, function(isRoomExist) {
              if (isRoomExist) {
                  connection.join(roomid);
                  return;
              }

              setTimeout(reCheckRoomPresence, 5000);
          });
      })();

      disableInputButtons();
  }

  // detect 2G
  if(navigator.connection &&
    navigator.connection.type === 'cellular' &&
    navigator.connection.downlinkMax <= 0.115) {
    alert('2G is not supported. Please use a better internet service.');
  }
  // $('video').attr('controls',true);
  // function video_controls(){
  //   $("video").prop("controls",true);
  //   $('video').attr('controls',true);
  // }
  // setTimeout(video_controls, 5000);
  // var numberOfUsers = connection.getAllParticipants().length;
    // $('#click').on('click', function(){
    //   var arrayOfUserIds = connection.getAllParticipants();
    //   console.clear();
    //   console.log(arrayOfUserIds);
    // })
    var tlm_streamer_length = '';
    setInterval(function(){
      var arrayOfUserIds = connection.getAllParticipants();
      var user =[];
      connection.getAllParticipants().forEach(function(participantId) {
          user.push(connection.peers[participantId].extra.user_id);
      });
      if( user.length >0 ) {
        var tlm_user_name = $('#tlm_usere').val();
        var tlm_data  = {
            action    : 'tlm_get_total_user',
            user       : user,
            tlm_user_name : tlm_user_name
        }
        $.ajax({
            url: 'ajax.php',
            type: 'POST',
            data: tlm_data,
            beforeSend: function(){
            },
            complete  : function(){
            },
            success: function (response) {
                var data = JSON.parse(response);
                if(data.text){
                    $('#tlm_user').empty();
                    $('#tlm_total_user_display').empty();
                    $('#tlm_user').html(data.text.length);
                    for (var i = 0; i < data.text.length; i++) {
                        $('#tlm_total_user_display').append('<li>'+data.text[i]+'<li>');
                    }
                }
            }
        });
      }else{
        $('#tlm_user').html('0');
      }
        // if( tlm_user_name == 'viewer' ) {
        //     if( arrayOfUserIds && arrayOfUserIds.length == 1 ) {
        //         $('#videos-container').attr('style','display:inline-block !important');
        //     }else{
        //         $('#videos-container').attr('style','display:none !important');
              
        //     }
        // }
    //   $('.str_member').html(arrayOfUserIds.length);
    }, 3000);

    $(document).on('click', 'video', function(){
    });
    $(".col-lg-8").click(function() {
      alert('test');
        var video = $('video').get(0);
        if ( video.paused ) {
        } else {
            $('.wth_live_btn').attr('style','display:none !important;');
        }
        // return false;
    });

    $(document).ready(function(){
        var scrolled = false;
        $(document).on('click','.str_chat_send_btn', function(){
            let msg       = $('#tlm_send_msg').val();
            let model_id  = $(this).data('model_id');
            var tlm_data  = {
                action    : 'tlm_msg_send_action',
                msg       : msg,
                model_id  : model_id,
            }
            if(msg && msg != '' ) {
                $.ajax({
                    url: 'ajax.php',
                    type: 'POST',
                    data: tlm_data,
                    beforeSend: function(){
                    },
                    complete  : function(){
                    },
                    success: function (response) {
                        console.log(response);
                        $('#tlm_send_msg').val('');
                        tlm_get_msg();
                        scrolled = false;
                    }
                });	
            }
        });
        $(document).on('click','.str_privatechat_send_btn2', function(){
            let msg       = $('#tlm_send_privatemsg').val();
            let model_id  = $(this).data('model_id');
            let user_id  = $(this).data('userid');
            var tlm_data  = {
                action    : 'tlm_privatemsg_send_action',
                msg       : msg,
                model_id  : model_id,
                user_id   : user_id
            }
            if(msg && msg != '' ) {
                $.ajax({
                    url: 'ajax.php',
                    type: 'POST',
                    data: tlm_data,
                    beforeSend: function(){
                    },
                    complete  : function(){
                    },
                    success: function (response) {
                        console.log(response);
                        $('#tlm_send_privatemsg').val('');
                        tlm_get_privatemsg();
                        scrolled = false;
                    }
                });	
            }
        });
        // $("#tlm_send_msg").keypress(function(event) { 
        //     if (event.keyCode === 13) { 
        //         $(".str_chat_send_btn").click(); 
        //     } 
        // });
        tlm_get_msg();
        function tlm_get_msg(){
          let model_id = $('.str_chat_send_btn').data('model_id');
            var tlm_data  = {
                action    : 'tlm_msg_get_action',
                key       : model_id,
            }
            if(model_id && model_id != '' ) {
                $.ajax({
                    url: 'ajax.php',
                    type: 'POST',
                    data: tlm_data,
                    beforeSend: function(){
                    },
                    complete  : function(){
                    },
                    success: function (response) {
                      var data = JSON.parse(response);
                      if(data.text){
                        $('#tlm_all_msg').empty();
                          for (var i = 0; i < data.text.length; i++) {
                              $('#tlm_all_msg').append($(data.text[i]));
                          }
                      }
                      if(!scrolled){
                        var messageBody = document.querySelector('.str_chat_list');
                        messageBody.scrollTop = messageBody.scrollHeight - messageBody.clientHeight;
                      }
                      tlm_get_msg();
                    }
                });	
            }
        }
        tlm_get_privatemsg();
        function tlm_get_privatemsg(){
          let model_id    = $('.str_privatechat_send_btn2').data('model_id');
          let user_id    = $('.str_privatechat_send_btn2').data('userid');
            var tlm_data  = {
                action    : 'tlm_privatemsg_get_action',
                key       : model_id,
                user_id   : user_id,
            }
            if(model_id && model_id != '' ) {
                $.ajax({
                    url: 'ajax.php',
                    type: 'POST',
                    data: tlm_data,
                    beforeSend: function(){
                    },
                    complete  : function(){
                    },
                    success: function (response) {
                        var data = JSON.parse(response);
                        if (data.text) {
                            $('#tlm_all_privatemsg').empty();
                            for (var i = 0; i < data.text.length; i++) {
                                $('#tlm_all_privatemsg').append($(data.text[i]));
                            }
                        }
                        if (!scrolled) {
                            var messageBody = document.querySelector('.str_chat_list');
                            messageBody.scrollTop = messageBody.scrollHeight - messageBody.clientHeight;
                        }
                        tlm_get_privatemsg();
                    }
                });	
            }
        }
        $("#tlm_send_msg").keypress(function(event) { 
            if (event.keyCode === 13) { 
                $(".str_chat_send_btn").click(); 
            } 
        }); 
        $("#getCodeModal").modal('show');
        // $(".str_chat_list").on('scroll', function(){
        //     scrolled=true;
        // });
        
        $(document).on('click', '.tlm_chat_top_tab', function(){
            $('.tlm_chat_top_tab').removeClass('active');
            $('.tlm_display_chat').attr('style','display:none;');
            // $('.tlm_chat_top_tab').attr('style','border-bottom: none;');
            // $(this).attr('style','border-bottom: 1px solid red;');
            $('.'+$(this).data('chat')).attr('style','display:block;');
            $(this).addClass('active');
        });
        $(document).on('click', '#cclick', function(){
            connection.replaceTrack({
                video: false,
                oneway: true
            });
        });
        $('[data-toggle="tooltip"]').tooltip(); 
    });
    $(document).on('click', '.btn_send_tip', function(){
        $('.razorpay-payment-button').trigger('click');
    });
})( jQuery );

akashsinghtkd avatar Feb 25 '21 07:02 akashsinghtkd