cordova-rtc / cordova-plugin-iosrtc

Cordova iOS plugin exposing the WebRTC W3C API
MIT License
688 stars 340 forks source link

On more time; Using Twillio and 6.0.15 no videos remote videos are showing at ALL #592

Closed samgabriel closed 3 years ago

samgabriel commented 3 years ago

Please read first!

Please use Public Google Group (mailing list) for general technical discussions and questions.

Note: If the checkboxes above are not checked (which you do after the issue is posted), the issue will be closed, removing this checkbox will result in automatic closed issue.

Versions affected

Description

After upgrading the tester to use the latest 6.0.15 now no videos are showing from the remote user at all and local videos are not showing on the remote.


<!DOCTYPE HTML>
<html>
<head>
    <title>
        Twilio Video Room
    </title>
    <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta http-equiv="Content-Security-Policy"
          content="default-src 'self' data: gap: wss://* https://* 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; media-src *">
    <script type="text/javascript" src="cordova.js"></script>
</head>
<body>
<br><br><br>
<div id="local-media" style="border: red 1px solid;"></div>
<div id="remote-media"></div>
<button onclick="toggleVideo()">Toggle video</button>
<button onclick="leaveMeeting()">Leave meeting</button>
<button onclick="startMeeting()">Start meeting</button>
<button onclick="switchCamera()">Switch camera</button>
<script type="text/javascript">

const token = '';
const roomName = 'test';
const scriptUrls = [];
let videoTrack = null;
let audioTrack = null;
let room = null;
let facing = true;

function loadScript(scriptUrl) {

  if (scriptUrls[scriptUrl]) {
    return Promise.resolve(scriptUrl);
  }

  return new Promise(function (resolve, reject) {
    // load adapter.js
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = scriptUrl;
    script.async = false;
    document.getElementsByTagName("head")[0].appendChild(script);
    script.onload = function () {
      scriptUrls[scriptUrl] = true;
      console.debug('loadScript.loaded', script.src);
      resolve(scriptUrl);
    };
  });
}

async function startMeeting() {

  videoTrack = await getVideoTrack();
  audioTrack = await Twilio.Video.createLocalAudioTrack();
  const localMediaContainer = document.getElementById('local-media');
  localMediaContainer.appendChild(videoTrack.attach());
  localMediaContainer.appendChild(audioTrack.attach());
  console.log(videoTrack, audioTrack);

  Twilio.Video.connect(token, {
    tracks: [videoTrack, audioTrack],
    name: roomName,
    sdpSemantics: 'plan-b',
    bundlePolicy: 'max-compat'
  }).then(_room => {
    room = _room;
    console.log(`Successfully joined a Room: ${room}`);

    // Attach the Tracks of the Room's Participants.
    room.participants.forEach(function (participant) {
      console.log("Already in Room: '" + participant.identity + "'");
      participantConnected(participant);
    });

    room.on('participantConnected', participant => {
      console.log(`A remote Participant connected: ${participant}`);
      participantConnected(participant);
    });

    room.on('participantDisconnected', participant => {
      console.log(`A remote Participant connected: ${participant}`);
      participantDisconnected(participant);
    });

  }, error => {
    console.error(`Unable to connect to Room: ${error.message}`);
  });

  function participantConnected(participant) {
    console.log('Participant "%s" connected', participant.identity);
    const div = document.createElement('div');
    div.id = participant.sid;
    participant.tracks.forEach((publication) => {
      console.log('subbing to existing publication', publication);
      trackSubscribed(div, publication);
    });

    participant.on('trackPublished', (publication) => {
      trackSubscribed(div, publication)
    });
    participant.on('trackUnpublished', trackUnsubscribed);

    document.getElementById('remote-media').appendChild(div);
  }

  function participantDisconnected(participant) {
    console.log('Participant "%s" disconnected', participant.identity);

    var div = document.getElementById(participant.sid);
    if (div) {
      div.remove();
    }
  }

  function trackSubscribed(div, publication) {
    console.log('sub publication', publication);
    if(publication.track){
      attachTrack(div, publication.track);
    }
    publication.on('subscribed', track => attachTrack(div, track));
    publication.on('unsubscribed', track => detachTrack(track));
  }

  function attachTrack(div, track){
    console.log('attachTrack', track);
    div.appendChild(track.attach());
  }

  function trackUnsubscribed(publication) {
    console.log('unsub publication', publication);
    if(publication.track){
      detachTrack(publication.track);
    }
  }
}

function detachTrack(track) {
  console.log('detachTrack', track);
  track.detach().forEach(element => element.remove());
}

function toggleVideo() {
  console.log(videoTrack, room);
  if (videoTrack.isEnabled) {
    videoTrack.disable();
    // room.localParticipant.unpublishTrack(videoTrack);
    console.log('disable');
  } else {
    videoTrack.enable();
    // room.localParticipant.publishTrack(videoTrack);
    console.log('enable');
  }
}

async function switchCamera(){
  facing = !facing;
  // Get new track
  const newTrack = await getVideoTrack();

  // Stop old track
  videoTrack.stop();
  detachTrack(videoTrack);

  // Unpublish previous track
  room.localParticipant.unpublishTrack(videoTrack);

  // Publish new track
  room.localParticipant.publishTrack(newTrack);
}

function getVideoTrack(){
  return Twilio.Video.createLocalVideoTrack({facingMode: facing ? 'user' : {exact: 'environment'}});
}

function leaveMeeting() {
  room.disconnect();
  videoTrack.stop();
  audioTrack.stop();
  detachTrack(videoTrack);
  detachTrack(audioTrack);
}

async function ready() {
  // Note: This allow this sample to run on any Browser
  var cordova = window.cordova;
  if (cordova && cordova.plugins && cordova.plugins.iosrtc) {

    // Expose WebRTC and GetUserMedia SHIM as Globals (Optional)
    // Alternatively WebRTC API will be inside cordova.plugins.iosrtc namespace
    cordova.plugins.iosrtc.registerGlobals();

    // Enable iosrtc debug (Optional)
    cordova.plugins.iosrtc.debug.enable('*', true);
  }
  console.log('loading Twilio');

  await loadScript('https://media.twiliocdn.com/sdk/js/video/releases/2.7.2/twilio-video.js');
  console.log('loaded');
}

if(!window.cordova){
  ready();
}

document.addEventListener('deviceready', ready, false);
</script>
</body>
</html>

Steps to reproduce

Create a cordova project with the attached code and Clicking on Start Meeting then connect to the same room with another twilio client from the desktop.

Expected results

Videos are displayed from remote and local

Actual results

Black video is displayed for the local and no remote videos are showing

Attached is the log file that we got after connecting. We removed the getStats logging to avoid polution

video test.log

samgabriel commented 3 years ago

@hthetiot Regarding the Local Stream not showing while debugging I noticed that twilio calls clone which works as expected but then MediaStreamTrack_setListener is called twice for the original MediaStreamTrack and the cloned one. Not sure if this is the issue but that is what I have found so far.

hthetiot commented 3 years ago

@hthetiot Regarding the Local Stream not showing while debugging I noticed that twilio calls clone which works as expected but then MediaStreamTrack_setListener is called twice for the original MediaStreamTrack and the cloned one. Not sure if this is the issue but that is what I have found so far.

Ok thank you for debug, i will investigate and let you know when the PR is updated.

samgabriel commented 3 years ago

@hthetiot I was able to find the root cause for the cloned local tracks not being visible on the other side. Can you please checkout the code in https://github.com/cordova-rtc/cordova-plugin-iosrtc/pull/605 and let me know if anything else that needs to be done.

Thanks Sam

hthetiot commented 3 years ago

@samgabriel congratulation and thank you. I have reviewed the PR and I'm fine with your changes. I will test your PR and if all goes well i will merge on master.

Thank you for your contribution, I'm glad you taken the time and understand what was the issue and assist yourself.

hthetiot commented 3 years ago

Merged #605 on master

Related #576

hthetiot commented 3 years ago

@samgabriel can you test master, i will myself make some test with Cordova-plugin-iosrtc-sample and extras/*-tests.js

Then I will ask other menber of the community to test master or even RC before making changelogs and publish.

We can then release 6.0.16

hthetiot commented 3 years ago

Feel free to make PR and add your company name or project here , last goes top. https://github.com/cordova-rtc/cordova-plugin-iosrtc/blob/master/WHO_USES_IT.md @samgabriel

hthetiot commented 3 years ago

@samgabriel can you test master and close the issue if fixe is confirmed. Also make sure to make PR with 'npm run build' result to update www/ build in the future, i did updated on master the www/ build already and prepared CHANGELOGS.

samgabriel commented 3 years ago

@hthetiot I will check tomorrow

samgabriel commented 3 years ago

@hthetiot i confirm it is working

samgabriel commented 3 years ago

@hthetiot it looks like https://github.com/cordova-rtc/cordova-plugin-iosrtc/commit/62b81de77ec67ae84d0f8ca4c7317462e10c950d was not included in 6.0.16 would you be able to add that commit please. This is a real issue that breaks the project

hthetiot commented 3 years ago

@samgabriel arf, can you confirm master if so I will release 6.0.17

samgabriel commented 3 years ago

@hthetiot it is not on master i don't know how that happened. You can search for "inactive"

samgabriel commented 3 years ago

@hthetiot nvm i removed that check for some reason on Nov 19th https://github.com/cordova-rtc/cordova-plugin-iosrtc/commit/c16dd97477a48c92538228c364093e56d12fedca#diff-1a65abd52bd140a16020d66ef172e1ba833c7ce0eb3fff54136c75fa62c31ae0

hthetiot commented 3 years ago

Ok @samgabriel i will check next week

samgabriel commented 3 years ago

@hthetiot oh no need to check I made a mistake. All Good