RTCMultiConnection
RTCMultiConnection copied to clipboard
Android + Chrome - How to use Back-Camera?
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!
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 = [];
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.
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 );