0

for some reason my publisher initiates twice when I create a new a new session. However the 2nd one, isn't in the div where it's supposed to be. Also if you connect to the session you'll get the same so it only show for yourself.

I'm trying to find out why it's appearing. Here's some snippets:

var getApiAndToken, initializeSession;
​
getApiAndToken = function() {
  var apiKey, customer_id, sessionId, token;
  if (gon) {
    apiKey = gon.api_key;
  }
  if (gon) {
    sessionId = gon.session_id;
  }
  if (gon) {
    token = gon.token;
  }
  if (gon) {
    customer_id = gon.customer_id;
  }
  initializeSession();
};
​
initializeSession = function() {
  var publishStream, session;
  session = OT.initSession(apiKey, sessionId);
  session.connect(token, function(error) {
    if (!error) {
      session.publish(publishStream(true));
      layout();
    } else {
      console.log('There was an error connecting to the session', error.code, error.message);
    }
  });
  $('#audioInputDevices').change(function() {
    publishStream(false);
  });
  $('#videoInputDevices').change(function() {
    publishStream(false);
  });
  return publishStream = function(loadDevices) {
    var publisherOptions;
    publisherOptions = {
      audioSource: $('#audioInputDevices').val() || 0,
      videoSource: $('#videoInputDevices').val() || 0
    };
    OT.initPublisher('publisherContainer', publisherOptions, function(error) {
      if (error) {
        console.log(error);
      } else {
        if (loadDevices) {
          OT.getDevices(function(error, devices) {
            var audioInputDevices, videoInputDevices;
            audioInputDevices = devices.filter(function(element) {
              return element.kind === 'audioInput';
            });
            videoInputDevices = devices.filter(function(element) {
              return element.kind === 'videoInput';
            });
            $.each(audioInputDevices, function() {
              $('#audioInputDevices').append($('<option></option>').val(this['deviceId']).html(this['label']));
            });
            $.each(videoInputDevices, function() {
              $('#videoInputDevices').append($('<option></option>').val(this['deviceId']).html(this['label']));
            });
          });
        }
      }
    });
  };
}; 

it also asks me for device access twice.

1 Answers1

0

I see two general problems in the code you provided:

  1. The variables api_key, session_id, and token inside the getApiAndToken() function are scoped to only that function, and therefore not visible inside initializeSession() where you try to use them.

  2. The goal of the publishStream() function is not clear and its use is not consistent. Each time you invoke it (once the session connects and each time the dropdown value changes) this function creates a new Publisher. It also does not return anything, so when using it in the expression session.publish(publishStream(true)), you are effectively just calling session.publish() which results in a new Publisher being added to the end of the page because there is no element ID specified. That last part is the reason why you said its not in the <div> where its supposed to be.

It sounds like what you want is a Publisher with a dropdown to select which devices its using. I created an example of this for you: https://jsbin.com/sujufog/11/edit?html,js,output.

Briefly, the following is how it works. It first initializes a dummy publisher so that the browser can prompt the user for permission to use the camera and microphone. This is necessary for reading the available devices. Note that if you use a page served over HTTPS, browsers such as Chrome will remember the permissions you allowed on that domain earlier and will not have to prompt the user again. Therefore on Chrome, the dummy publisher doesn't cause any prompt be shown for a user who has already run the application. Next, the dummy publisher is thrown away, and OT.getDevices() is called to read the available devices and populate the dropdown menu. While this is happening, the session would have also connected, and on every change of the selection in either of the dropdowns, the publish() function is called. In that function, if a previous publisher existed, it is first removed, and then a new publisher is created with the devices that are currently selected. Then that new publisher is passed into session.publish().

Ankur
  • 2,792
  • 3
  • 23
  • 26