Remote Video stream not showing up at all





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







3















I have been trying to get the remote video stream to show up using .ontrack which is under the peer connection function in my code. Until now the .ontrack only fires on the caller side while on the callee it does not even when the function is called.



The log that checks if .ontrack fires would state "Got Remote Stream" but only on the caller side which might be the problem here but I'm not sure why would the other party not go into the IF statement that holds the .ontrack when it does not have the event.stream[0] which the statement is checking for.



I have added the console logs from both Caller and Callee below. Not shown in the images is that after a while the candidates would show null but both users are still connected.



main.js



'use strict';

var isInitiator;
var configuration = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
var pc = new RTCPeerConnection(configuration);

// Define action buttons.
const callButton = document.getElementById('callButton');
const hangupButton = document.getElementById('hangupButton');

/////////////////////////////////////////////

window.room = prompt('Enter room name:');

var socket = io.connect();

if (room !== '') {
console.log('Message from client: Asking to join room ' + room);
socket.emit('create or join', room);
}

socket.on('created', function(room) {
console.log('Created room ' + room);
isInitiator = true;
startVideo();
});

socket.on('full', function(room) {
console.log('Message from client: Room ' + room + ' is full :^(');
});

socket.on('joined', function(room) {
console.log('joined: ' + room);
startVideo();
callButton.disabled = true;
});

socket.on('log', function(array) {
console.log.apply(console, array);
});

////////////////////////////////////////////////

async function sendMessage(message) {
console.log('Client sending message: ', message);
await socket.emit('message', message);
}

// This client receives a message
socket.on('message', async function(message) {
try {
if (message.type === 'offer') {
await pc.setRemoteDescription(new RTCSessionDescription(message));
await pc
.setLocalDescription(await pc.createAnswer())
.then(function() {
sendMessage(pc.localDescription);
})
.catch(function(err) {
console.log(err.name + ': ' + err.message);
});
createPeerConnection();
} else if (message.type === 'answer') {
await pc.setRemoteDescription(new RTCSessionDescription(message));
} else if (message.type === 'candidate') {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
});

////////////////////////////////////////////////////

const localVideo = document.querySelector('#localVideo');
const remoteVideo = document.querySelector('#remoteVideo');

// Set up initial action buttons status: disable call and hangup.
callButton.disabled = true;
hangupButton.disabled = true;

// Add click event handlers for buttons.
callButton.addEventListener('click', callStart);
hangupButton.addEventListener('click', hangupCall);

function startVideo() {
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true
})
.then(function(stream) {
localVideo.srcObject = stream;
stream.getTracks().forEach(track => pc.addTrack(track, stream));
})
.catch(function(err) {
console.log('getUserMedia() error: ' + err.name);
});
callButton.disabled = false;
}

async function callStart() {
createPeerConnection();
callButton.disabled = true;
hangupButton.disabled = false;
if (isInitiator) {
console.log('Sending offer to peer');
await pc
.setLocalDescription(await pc.createOffer())
.then(function() {
sendMessage(pc.localDescription);
})
.catch(function(err) {
console.log(err.name + ': ' + err.message);
});
}
}

/////////////////////////////////////////////////////////

function createPeerConnection() {
try {
pc.ontrack = event => {
if (remoteVideo.srcObject !== event.streams[0]) {
remoteVideo.srcObject = event.streams[0];
console.log('Got remote stream');
}
};
pc.onicecandidate = ({ candidate }) => sendMessage({ candidate });
console.log('Created RTCPeerConnnection');
} catch (e) {
console.log('Failed to create PeerConnection, exception: ' + e.message);
alert('Cannot create RTCPeerConnection object.');
return;
}
}

function hangupCall() {
pc.close();
pc = null;
callButton.disabled = false;
hangupButton.disabled = true;
console.log('Call Ended');
}


index.js



'use strict';

var express = require('express');
var app = (module.exports.app = express());
var path = require('path');

var server = require('http').createServer(app);
var io = require('socket.io')(server);
const PORT_NO = process.env.APP_PORT || 3000;
server.listen(PORT_NO);

app.get('/', function(request, response) {
response.sendFile(path.resolve('./index.html'));
});

app.use(express.static('.'));
io.on('connection', socket => {
function log() {
const array = ['Message from server:'];
for (let i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}

socket.on('message', message => {
log('Got message:', message);
socket.broadcast.emit('message', message);
});

socket.on('create or join', room => {
var clientsInRoom = io.sockets.adapter.rooms[room];
var numClients = clientsInRoom
? Object.keys(clientsInRoom.sockets).length
: 0;

// max two clients
if (numClients === 2) {
socket.emit('full', room);
return;
}

log('Room ' + room + ' now has ' + (numClients + 1) + ' client(s)');

if (numClients === 0) {
socket.join(room);
log('Client ID ' + socket.id + ' created room ' + room);
socket.emit('created', room, socket.id);
} else {
log('Client ID ' + socket.id + ' joined room ' + room);
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room, socket.id);
io.sockets.in(room).emit('ready');
}
});
});


Callee side (in Safari)



Caller side (in Firefox)










share|improve this question































    3















    I have been trying to get the remote video stream to show up using .ontrack which is under the peer connection function in my code. Until now the .ontrack only fires on the caller side while on the callee it does not even when the function is called.



    The log that checks if .ontrack fires would state "Got Remote Stream" but only on the caller side which might be the problem here but I'm not sure why would the other party not go into the IF statement that holds the .ontrack when it does not have the event.stream[0] which the statement is checking for.



    I have added the console logs from both Caller and Callee below. Not shown in the images is that after a while the candidates would show null but both users are still connected.



    main.js



    'use strict';

    var isInitiator;
    var configuration = {
    iceServers: [
    {
    urls: 'stun:stun.l.google.com:19302'
    }
    ]
    };
    var pc = new RTCPeerConnection(configuration);

    // Define action buttons.
    const callButton = document.getElementById('callButton');
    const hangupButton = document.getElementById('hangupButton');

    /////////////////////////////////////////////

    window.room = prompt('Enter room name:');

    var socket = io.connect();

    if (room !== '') {
    console.log('Message from client: Asking to join room ' + room);
    socket.emit('create or join', room);
    }

    socket.on('created', function(room) {
    console.log('Created room ' + room);
    isInitiator = true;
    startVideo();
    });

    socket.on('full', function(room) {
    console.log('Message from client: Room ' + room + ' is full :^(');
    });

    socket.on('joined', function(room) {
    console.log('joined: ' + room);
    startVideo();
    callButton.disabled = true;
    });

    socket.on('log', function(array) {
    console.log.apply(console, array);
    });

    ////////////////////////////////////////////////

    async function sendMessage(message) {
    console.log('Client sending message: ', message);
    await socket.emit('message', message);
    }

    // This client receives a message
    socket.on('message', async function(message) {
    try {
    if (message.type === 'offer') {
    await pc.setRemoteDescription(new RTCSessionDescription(message));
    await pc
    .setLocalDescription(await pc.createAnswer())
    .then(function() {
    sendMessage(pc.localDescription);
    })
    .catch(function(err) {
    console.log(err.name + ': ' + err.message);
    });
    createPeerConnection();
    } else if (message.type === 'answer') {
    await pc.setRemoteDescription(new RTCSessionDescription(message));
    } else if (message.type === 'candidate') {
    await pc.addIceCandidate(candidate);
    }
    } catch (err) {
    console.error(err);
    }
    });

    ////////////////////////////////////////////////////

    const localVideo = document.querySelector('#localVideo');
    const remoteVideo = document.querySelector('#remoteVideo');

    // Set up initial action buttons status: disable call and hangup.
    callButton.disabled = true;
    hangupButton.disabled = true;

    // Add click event handlers for buttons.
    callButton.addEventListener('click', callStart);
    hangupButton.addEventListener('click', hangupCall);

    function startVideo() {
    navigator.mediaDevices
    .getUserMedia({
    audio: true,
    video: true
    })
    .then(function(stream) {
    localVideo.srcObject = stream;
    stream.getTracks().forEach(track => pc.addTrack(track, stream));
    })
    .catch(function(err) {
    console.log('getUserMedia() error: ' + err.name);
    });
    callButton.disabled = false;
    }

    async function callStart() {
    createPeerConnection();
    callButton.disabled = true;
    hangupButton.disabled = false;
    if (isInitiator) {
    console.log('Sending offer to peer');
    await pc
    .setLocalDescription(await pc.createOffer())
    .then(function() {
    sendMessage(pc.localDescription);
    })
    .catch(function(err) {
    console.log(err.name + ': ' + err.message);
    });
    }
    }

    /////////////////////////////////////////////////////////

    function createPeerConnection() {
    try {
    pc.ontrack = event => {
    if (remoteVideo.srcObject !== event.streams[0]) {
    remoteVideo.srcObject = event.streams[0];
    console.log('Got remote stream');
    }
    };
    pc.onicecandidate = ({ candidate }) => sendMessage({ candidate });
    console.log('Created RTCPeerConnnection');
    } catch (e) {
    console.log('Failed to create PeerConnection, exception: ' + e.message);
    alert('Cannot create RTCPeerConnection object.');
    return;
    }
    }

    function hangupCall() {
    pc.close();
    pc = null;
    callButton.disabled = false;
    hangupButton.disabled = true;
    console.log('Call Ended');
    }


    index.js



    'use strict';

    var express = require('express');
    var app = (module.exports.app = express());
    var path = require('path');

    var server = require('http').createServer(app);
    var io = require('socket.io')(server);
    const PORT_NO = process.env.APP_PORT || 3000;
    server.listen(PORT_NO);

    app.get('/', function(request, response) {
    response.sendFile(path.resolve('./index.html'));
    });

    app.use(express.static('.'));
    io.on('connection', socket => {
    function log() {
    const array = ['Message from server:'];
    for (let i = 0; i < arguments.length; i++) {
    array.push(arguments[i]);
    }
    socket.emit('log', array);
    }

    socket.on('message', message => {
    log('Got message:', message);
    socket.broadcast.emit('message', message);
    });

    socket.on('create or join', room => {
    var clientsInRoom = io.sockets.adapter.rooms[room];
    var numClients = clientsInRoom
    ? Object.keys(clientsInRoom.sockets).length
    : 0;

    // max two clients
    if (numClients === 2) {
    socket.emit('full', room);
    return;
    }

    log('Room ' + room + ' now has ' + (numClients + 1) + ' client(s)');

    if (numClients === 0) {
    socket.join(room);
    log('Client ID ' + socket.id + ' created room ' + room);
    socket.emit('created', room, socket.id);
    } else {
    log('Client ID ' + socket.id + ' joined room ' + room);
    io.sockets.in(room).emit('join', room);
    socket.join(room);
    socket.emit('joined', room, socket.id);
    io.sockets.in(room).emit('ready');
    }
    });
    });


    Callee side (in Safari)



    Caller side (in Firefox)










    share|improve this question



























      3












      3








      3








      I have been trying to get the remote video stream to show up using .ontrack which is under the peer connection function in my code. Until now the .ontrack only fires on the caller side while on the callee it does not even when the function is called.



      The log that checks if .ontrack fires would state "Got Remote Stream" but only on the caller side which might be the problem here but I'm not sure why would the other party not go into the IF statement that holds the .ontrack when it does not have the event.stream[0] which the statement is checking for.



      I have added the console logs from both Caller and Callee below. Not shown in the images is that after a while the candidates would show null but both users are still connected.



      main.js



      'use strict';

      var isInitiator;
      var configuration = {
      iceServers: [
      {
      urls: 'stun:stun.l.google.com:19302'
      }
      ]
      };
      var pc = new RTCPeerConnection(configuration);

      // Define action buttons.
      const callButton = document.getElementById('callButton');
      const hangupButton = document.getElementById('hangupButton');

      /////////////////////////////////////////////

      window.room = prompt('Enter room name:');

      var socket = io.connect();

      if (room !== '') {
      console.log('Message from client: Asking to join room ' + room);
      socket.emit('create or join', room);
      }

      socket.on('created', function(room) {
      console.log('Created room ' + room);
      isInitiator = true;
      startVideo();
      });

      socket.on('full', function(room) {
      console.log('Message from client: Room ' + room + ' is full :^(');
      });

      socket.on('joined', function(room) {
      console.log('joined: ' + room);
      startVideo();
      callButton.disabled = true;
      });

      socket.on('log', function(array) {
      console.log.apply(console, array);
      });

      ////////////////////////////////////////////////

      async function sendMessage(message) {
      console.log('Client sending message: ', message);
      await socket.emit('message', message);
      }

      // This client receives a message
      socket.on('message', async function(message) {
      try {
      if (message.type === 'offer') {
      await pc.setRemoteDescription(new RTCSessionDescription(message));
      await pc
      .setLocalDescription(await pc.createAnswer())
      .then(function() {
      sendMessage(pc.localDescription);
      })
      .catch(function(err) {
      console.log(err.name + ': ' + err.message);
      });
      createPeerConnection();
      } else if (message.type === 'answer') {
      await pc.setRemoteDescription(new RTCSessionDescription(message));
      } else if (message.type === 'candidate') {
      await pc.addIceCandidate(candidate);
      }
      } catch (err) {
      console.error(err);
      }
      });

      ////////////////////////////////////////////////////

      const localVideo = document.querySelector('#localVideo');
      const remoteVideo = document.querySelector('#remoteVideo');

      // Set up initial action buttons status: disable call and hangup.
      callButton.disabled = true;
      hangupButton.disabled = true;

      // Add click event handlers for buttons.
      callButton.addEventListener('click', callStart);
      hangupButton.addEventListener('click', hangupCall);

      function startVideo() {
      navigator.mediaDevices
      .getUserMedia({
      audio: true,
      video: true
      })
      .then(function(stream) {
      localVideo.srcObject = stream;
      stream.getTracks().forEach(track => pc.addTrack(track, stream));
      })
      .catch(function(err) {
      console.log('getUserMedia() error: ' + err.name);
      });
      callButton.disabled = false;
      }

      async function callStart() {
      createPeerConnection();
      callButton.disabled = true;
      hangupButton.disabled = false;
      if (isInitiator) {
      console.log('Sending offer to peer');
      await pc
      .setLocalDescription(await pc.createOffer())
      .then(function() {
      sendMessage(pc.localDescription);
      })
      .catch(function(err) {
      console.log(err.name + ': ' + err.message);
      });
      }
      }

      /////////////////////////////////////////////////////////

      function createPeerConnection() {
      try {
      pc.ontrack = event => {
      if (remoteVideo.srcObject !== event.streams[0]) {
      remoteVideo.srcObject = event.streams[0];
      console.log('Got remote stream');
      }
      };
      pc.onicecandidate = ({ candidate }) => sendMessage({ candidate });
      console.log('Created RTCPeerConnnection');
      } catch (e) {
      console.log('Failed to create PeerConnection, exception: ' + e.message);
      alert('Cannot create RTCPeerConnection object.');
      return;
      }
      }

      function hangupCall() {
      pc.close();
      pc = null;
      callButton.disabled = false;
      hangupButton.disabled = true;
      console.log('Call Ended');
      }


      index.js



      'use strict';

      var express = require('express');
      var app = (module.exports.app = express());
      var path = require('path');

      var server = require('http').createServer(app);
      var io = require('socket.io')(server);
      const PORT_NO = process.env.APP_PORT || 3000;
      server.listen(PORT_NO);

      app.get('/', function(request, response) {
      response.sendFile(path.resolve('./index.html'));
      });

      app.use(express.static('.'));
      io.on('connection', socket => {
      function log() {
      const array = ['Message from server:'];
      for (let i = 0; i < arguments.length; i++) {
      array.push(arguments[i]);
      }
      socket.emit('log', array);
      }

      socket.on('message', message => {
      log('Got message:', message);
      socket.broadcast.emit('message', message);
      });

      socket.on('create or join', room => {
      var clientsInRoom = io.sockets.adapter.rooms[room];
      var numClients = clientsInRoom
      ? Object.keys(clientsInRoom.sockets).length
      : 0;

      // max two clients
      if (numClients === 2) {
      socket.emit('full', room);
      return;
      }

      log('Room ' + room + ' now has ' + (numClients + 1) + ' client(s)');

      if (numClients === 0) {
      socket.join(room);
      log('Client ID ' + socket.id + ' created room ' + room);
      socket.emit('created', room, socket.id);
      } else {
      log('Client ID ' + socket.id + ' joined room ' + room);
      io.sockets.in(room).emit('join', room);
      socket.join(room);
      socket.emit('joined', room, socket.id);
      io.sockets.in(room).emit('ready');
      }
      });
      });


      Callee side (in Safari)



      Caller side (in Firefox)










      share|improve this question
















      I have been trying to get the remote video stream to show up using .ontrack which is under the peer connection function in my code. Until now the .ontrack only fires on the caller side while on the callee it does not even when the function is called.



      The log that checks if .ontrack fires would state "Got Remote Stream" but only on the caller side which might be the problem here but I'm not sure why would the other party not go into the IF statement that holds the .ontrack when it does not have the event.stream[0] which the statement is checking for.



      I have added the console logs from both Caller and Callee below. Not shown in the images is that after a while the candidates would show null but both users are still connected.



      main.js



      'use strict';

      var isInitiator;
      var configuration = {
      iceServers: [
      {
      urls: 'stun:stun.l.google.com:19302'
      }
      ]
      };
      var pc = new RTCPeerConnection(configuration);

      // Define action buttons.
      const callButton = document.getElementById('callButton');
      const hangupButton = document.getElementById('hangupButton');

      /////////////////////////////////////////////

      window.room = prompt('Enter room name:');

      var socket = io.connect();

      if (room !== '') {
      console.log('Message from client: Asking to join room ' + room);
      socket.emit('create or join', room);
      }

      socket.on('created', function(room) {
      console.log('Created room ' + room);
      isInitiator = true;
      startVideo();
      });

      socket.on('full', function(room) {
      console.log('Message from client: Room ' + room + ' is full :^(');
      });

      socket.on('joined', function(room) {
      console.log('joined: ' + room);
      startVideo();
      callButton.disabled = true;
      });

      socket.on('log', function(array) {
      console.log.apply(console, array);
      });

      ////////////////////////////////////////////////

      async function sendMessage(message) {
      console.log('Client sending message: ', message);
      await socket.emit('message', message);
      }

      // This client receives a message
      socket.on('message', async function(message) {
      try {
      if (message.type === 'offer') {
      await pc.setRemoteDescription(new RTCSessionDescription(message));
      await pc
      .setLocalDescription(await pc.createAnswer())
      .then(function() {
      sendMessage(pc.localDescription);
      })
      .catch(function(err) {
      console.log(err.name + ': ' + err.message);
      });
      createPeerConnection();
      } else if (message.type === 'answer') {
      await pc.setRemoteDescription(new RTCSessionDescription(message));
      } else if (message.type === 'candidate') {
      await pc.addIceCandidate(candidate);
      }
      } catch (err) {
      console.error(err);
      }
      });

      ////////////////////////////////////////////////////

      const localVideo = document.querySelector('#localVideo');
      const remoteVideo = document.querySelector('#remoteVideo');

      // Set up initial action buttons status: disable call and hangup.
      callButton.disabled = true;
      hangupButton.disabled = true;

      // Add click event handlers for buttons.
      callButton.addEventListener('click', callStart);
      hangupButton.addEventListener('click', hangupCall);

      function startVideo() {
      navigator.mediaDevices
      .getUserMedia({
      audio: true,
      video: true
      })
      .then(function(stream) {
      localVideo.srcObject = stream;
      stream.getTracks().forEach(track => pc.addTrack(track, stream));
      })
      .catch(function(err) {
      console.log('getUserMedia() error: ' + err.name);
      });
      callButton.disabled = false;
      }

      async function callStart() {
      createPeerConnection();
      callButton.disabled = true;
      hangupButton.disabled = false;
      if (isInitiator) {
      console.log('Sending offer to peer');
      await pc
      .setLocalDescription(await pc.createOffer())
      .then(function() {
      sendMessage(pc.localDescription);
      })
      .catch(function(err) {
      console.log(err.name + ': ' + err.message);
      });
      }
      }

      /////////////////////////////////////////////////////////

      function createPeerConnection() {
      try {
      pc.ontrack = event => {
      if (remoteVideo.srcObject !== event.streams[0]) {
      remoteVideo.srcObject = event.streams[0];
      console.log('Got remote stream');
      }
      };
      pc.onicecandidate = ({ candidate }) => sendMessage({ candidate });
      console.log('Created RTCPeerConnnection');
      } catch (e) {
      console.log('Failed to create PeerConnection, exception: ' + e.message);
      alert('Cannot create RTCPeerConnection object.');
      return;
      }
      }

      function hangupCall() {
      pc.close();
      pc = null;
      callButton.disabled = false;
      hangupButton.disabled = true;
      console.log('Call Ended');
      }


      index.js



      'use strict';

      var express = require('express');
      var app = (module.exports.app = express());
      var path = require('path');

      var server = require('http').createServer(app);
      var io = require('socket.io')(server);
      const PORT_NO = process.env.APP_PORT || 3000;
      server.listen(PORT_NO);

      app.get('/', function(request, response) {
      response.sendFile(path.resolve('./index.html'));
      });

      app.use(express.static('.'));
      io.on('connection', socket => {
      function log() {
      const array = ['Message from server:'];
      for (let i = 0; i < arguments.length; i++) {
      array.push(arguments[i]);
      }
      socket.emit('log', array);
      }

      socket.on('message', message => {
      log('Got message:', message);
      socket.broadcast.emit('message', message);
      });

      socket.on('create or join', room => {
      var clientsInRoom = io.sockets.adapter.rooms[room];
      var numClients = clientsInRoom
      ? Object.keys(clientsInRoom.sockets).length
      : 0;

      // max two clients
      if (numClients === 2) {
      socket.emit('full', room);
      return;
      }

      log('Room ' + room + ' now has ' + (numClients + 1) + ' client(s)');

      if (numClients === 0) {
      socket.join(room);
      log('Client ID ' + socket.id + ' created room ' + room);
      socket.emit('created', room, socket.id);
      } else {
      log('Client ID ' + socket.id + ' joined room ' + room);
      io.sockets.in(room).emit('join', room);
      socket.join(room);
      socket.emit('joined', room, socket.id);
      io.sockets.in(room).emit('ready');
      }
      });
      });


      Callee side (in Safari)



      Caller side (in Firefox)







      javascript socket.io webrtc






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 3 at 7:02







      Rj Tng

















      asked Dec 2 '18 at 17:50









      Rj TngRj Tng

      518




      518
























          2 Answers
          2






          active

          oldest

          votes


















          0














          Let the joiner be the initiator.



          I'm guessing 'created' happens before 'joined'? I.e. one party creates the room before the second party joins it?



          Since your startVideo() does more than start the local video—it actually begins connection negotiation—I suspect you begin negotiating before the second party is ready, a race. Instead try:



          socket.on('created', function(room) {
          console.log('Created room ' + room);
          startVideo();
          });

          socket.on('joined', function(room) {
          console.log('joined: ' + room);
          isInitiator = true; // <-- begin negotiating once 2nd party arrives.
          startVideo();
          });





          share|improve this answer
























          • startVideo() doesn't do the negotiation isn't it? I have the callStart() function which creates the offer to the peer. You are correct that created happens before joined but by changing the isInitiator to the peer that joins, the creator is now unable to press the call button as it would not trigger the createOffer. I am attaching an image for you to take a look which is what comes out from the createOffer imgur.com/a/Tgxyu7M.

            – Rj Tng
            Dec 3 '18 at 1:41











          • @RjTng Ah right. I'm used to people using onnegotiationneeded.

            – jib
            Dec 3 '18 at 2:27



















          0














          You're missing a call to createPeerConnection() on the answerer side, which means the answerer isn't properly set up to signal ICE candidates or fire the track event.



          You only call it from startCall(), so this would only work if you hit the call button on both ends at almost exactly the same time.



          createPeerConnection() is a misnomer. Instead, just initialize the pc with its ontrack and onicecandidate callbacks on page load.



          Still not working?



          The rest of your WebRTC-related code you're showing us looks fine—except you're calling getUserMedia twice on the answerer side, which is redundant, but shouldn't be a problem.



          I suspect a bug in your server logic. E.g. you're not showing us how emitting 'create or join' turns into either a 'created' or 'joined' socket message. You're also trying to predetermine which side is which in the offer/answer exchange, which is fine, except this means you have a non-working Call button on the answerer side. Most demos just let whoever pushes the button first be the offerer, though that might create glare. Just FYI.



          This is a two-way call. In which direction is remoteVideo not working?



          Also, you have a two-way call here, sending video in both directions, yet you've not mentioned which remoteVideo you're not seeing.



          For a working example, check out my two-way tab demo. Open it in two adjacent windows in the same browser, and click the Call button in one of them to connect. You should see (the same) video being sent both ways. It relies on a localSocket hack using localStorage.






          share|improve this answer


























          • Sorry I don't quite get what u are saying. pc has already been configured at the start with var pc = new RTCPeerConnection(configuration); but I did try to add another createPeerConnection() where the offer message is received but it does not create the remote video stream.

            – Rj Tng
            Dec 3 '18 at 6:51













          • @RjTng That's what I meant.

            – jib
            Dec 3 '18 at 17:16













          • Both sides of the remote video isn't working. I went to try to start the room on a phone, the local video would be able to be displayed but after pressing the call button it immediately shuts off. This was after adding the PeerConnection to the offer case and commenting out the redundant getUserMedia. Been trying to do it on localhost too and comparing my code with yours it seems like its correct.

            – Rj Tng
            Dec 4 '18 at 4:16











          • for the socket.io signalling, I would think its correct as its from the codelabs if (numClients === 0) { socket.join(room); log('Client ID ' + socket.id + ' created room ' + room); socket.emit('created', room, socket.id); } else if (numClients === 1) { log('Client ID ' + socket.id + ' joined room ' + room); io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready', room); } else { // max two clients socket.emit('full', room); }

            – Rj Tng
            Dec 4 '18 at 4:18











          • Codelabs? Hah. I've shown you a working version, so hopefully you'll be able to find out how your code differs, and get it working. Good luck!

            – jib
            Dec 4 '18 at 6:58












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53582983%2fremote-video-stream-not-showing-up-at-all%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          Let the joiner be the initiator.



          I'm guessing 'created' happens before 'joined'? I.e. one party creates the room before the second party joins it?



          Since your startVideo() does more than start the local video—it actually begins connection negotiation—I suspect you begin negotiating before the second party is ready, a race. Instead try:



          socket.on('created', function(room) {
          console.log('Created room ' + room);
          startVideo();
          });

          socket.on('joined', function(room) {
          console.log('joined: ' + room);
          isInitiator = true; // <-- begin negotiating once 2nd party arrives.
          startVideo();
          });





          share|improve this answer
























          • startVideo() doesn't do the negotiation isn't it? I have the callStart() function which creates the offer to the peer. You are correct that created happens before joined but by changing the isInitiator to the peer that joins, the creator is now unable to press the call button as it would not trigger the createOffer. I am attaching an image for you to take a look which is what comes out from the createOffer imgur.com/a/Tgxyu7M.

            – Rj Tng
            Dec 3 '18 at 1:41











          • @RjTng Ah right. I'm used to people using onnegotiationneeded.

            – jib
            Dec 3 '18 at 2:27
















          0














          Let the joiner be the initiator.



          I'm guessing 'created' happens before 'joined'? I.e. one party creates the room before the second party joins it?



          Since your startVideo() does more than start the local video—it actually begins connection negotiation—I suspect you begin negotiating before the second party is ready, a race. Instead try:



          socket.on('created', function(room) {
          console.log('Created room ' + room);
          startVideo();
          });

          socket.on('joined', function(room) {
          console.log('joined: ' + room);
          isInitiator = true; // <-- begin negotiating once 2nd party arrives.
          startVideo();
          });





          share|improve this answer
























          • startVideo() doesn't do the negotiation isn't it? I have the callStart() function which creates the offer to the peer. You are correct that created happens before joined but by changing the isInitiator to the peer that joins, the creator is now unable to press the call button as it would not trigger the createOffer. I am attaching an image for you to take a look which is what comes out from the createOffer imgur.com/a/Tgxyu7M.

            – Rj Tng
            Dec 3 '18 at 1:41











          • @RjTng Ah right. I'm used to people using onnegotiationneeded.

            – jib
            Dec 3 '18 at 2:27














          0












          0








          0







          Let the joiner be the initiator.



          I'm guessing 'created' happens before 'joined'? I.e. one party creates the room before the second party joins it?



          Since your startVideo() does more than start the local video—it actually begins connection negotiation—I suspect you begin negotiating before the second party is ready, a race. Instead try:



          socket.on('created', function(room) {
          console.log('Created room ' + room);
          startVideo();
          });

          socket.on('joined', function(room) {
          console.log('joined: ' + room);
          isInitiator = true; // <-- begin negotiating once 2nd party arrives.
          startVideo();
          });





          share|improve this answer













          Let the joiner be the initiator.



          I'm guessing 'created' happens before 'joined'? I.e. one party creates the room before the second party joins it?



          Since your startVideo() does more than start the local video—it actually begins connection negotiation—I suspect you begin negotiating before the second party is ready, a race. Instead try:



          socket.on('created', function(room) {
          console.log('Created room ' + room);
          startVideo();
          });

          socket.on('joined', function(room) {
          console.log('joined: ' + room);
          isInitiator = true; // <-- begin negotiating once 2nd party arrives.
          startVideo();
          });






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 2 '18 at 22:40









          jibjib

          21.9k64694




          21.9k64694













          • startVideo() doesn't do the negotiation isn't it? I have the callStart() function which creates the offer to the peer. You are correct that created happens before joined but by changing the isInitiator to the peer that joins, the creator is now unable to press the call button as it would not trigger the createOffer. I am attaching an image for you to take a look which is what comes out from the createOffer imgur.com/a/Tgxyu7M.

            – Rj Tng
            Dec 3 '18 at 1:41











          • @RjTng Ah right. I'm used to people using onnegotiationneeded.

            – jib
            Dec 3 '18 at 2:27



















          • startVideo() doesn't do the negotiation isn't it? I have the callStart() function which creates the offer to the peer. You are correct that created happens before joined but by changing the isInitiator to the peer that joins, the creator is now unable to press the call button as it would not trigger the createOffer. I am attaching an image for you to take a look which is what comes out from the createOffer imgur.com/a/Tgxyu7M.

            – Rj Tng
            Dec 3 '18 at 1:41











          • @RjTng Ah right. I'm used to people using onnegotiationneeded.

            – jib
            Dec 3 '18 at 2:27

















          startVideo() doesn't do the negotiation isn't it? I have the callStart() function which creates the offer to the peer. You are correct that created happens before joined but by changing the isInitiator to the peer that joins, the creator is now unable to press the call button as it would not trigger the createOffer. I am attaching an image for you to take a look which is what comes out from the createOffer imgur.com/a/Tgxyu7M.

          – Rj Tng
          Dec 3 '18 at 1:41





          startVideo() doesn't do the negotiation isn't it? I have the callStart() function which creates the offer to the peer. You are correct that created happens before joined but by changing the isInitiator to the peer that joins, the creator is now unable to press the call button as it would not trigger the createOffer. I am attaching an image for you to take a look which is what comes out from the createOffer imgur.com/a/Tgxyu7M.

          – Rj Tng
          Dec 3 '18 at 1:41













          @RjTng Ah right. I'm used to people using onnegotiationneeded.

          – jib
          Dec 3 '18 at 2:27





          @RjTng Ah right. I'm used to people using onnegotiationneeded.

          – jib
          Dec 3 '18 at 2:27













          0














          You're missing a call to createPeerConnection() on the answerer side, which means the answerer isn't properly set up to signal ICE candidates or fire the track event.



          You only call it from startCall(), so this would only work if you hit the call button on both ends at almost exactly the same time.



          createPeerConnection() is a misnomer. Instead, just initialize the pc with its ontrack and onicecandidate callbacks on page load.



          Still not working?



          The rest of your WebRTC-related code you're showing us looks fine—except you're calling getUserMedia twice on the answerer side, which is redundant, but shouldn't be a problem.



          I suspect a bug in your server logic. E.g. you're not showing us how emitting 'create or join' turns into either a 'created' or 'joined' socket message. You're also trying to predetermine which side is which in the offer/answer exchange, which is fine, except this means you have a non-working Call button on the answerer side. Most demos just let whoever pushes the button first be the offerer, though that might create glare. Just FYI.



          This is a two-way call. In which direction is remoteVideo not working?



          Also, you have a two-way call here, sending video in both directions, yet you've not mentioned which remoteVideo you're not seeing.



          For a working example, check out my two-way tab demo. Open it in two adjacent windows in the same browser, and click the Call button in one of them to connect. You should see (the same) video being sent both ways. It relies on a localSocket hack using localStorage.






          share|improve this answer


























          • Sorry I don't quite get what u are saying. pc has already been configured at the start with var pc = new RTCPeerConnection(configuration); but I did try to add another createPeerConnection() where the offer message is received but it does not create the remote video stream.

            – Rj Tng
            Dec 3 '18 at 6:51













          • @RjTng That's what I meant.

            – jib
            Dec 3 '18 at 17:16













          • Both sides of the remote video isn't working. I went to try to start the room on a phone, the local video would be able to be displayed but after pressing the call button it immediately shuts off. This was after adding the PeerConnection to the offer case and commenting out the redundant getUserMedia. Been trying to do it on localhost too and comparing my code with yours it seems like its correct.

            – Rj Tng
            Dec 4 '18 at 4:16











          • for the socket.io signalling, I would think its correct as its from the codelabs if (numClients === 0) { socket.join(room); log('Client ID ' + socket.id + ' created room ' + room); socket.emit('created', room, socket.id); } else if (numClients === 1) { log('Client ID ' + socket.id + ' joined room ' + room); io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready', room); } else { // max two clients socket.emit('full', room); }

            – Rj Tng
            Dec 4 '18 at 4:18











          • Codelabs? Hah. I've shown you a working version, so hopefully you'll be able to find out how your code differs, and get it working. Good luck!

            – jib
            Dec 4 '18 at 6:58
















          0














          You're missing a call to createPeerConnection() on the answerer side, which means the answerer isn't properly set up to signal ICE candidates or fire the track event.



          You only call it from startCall(), so this would only work if you hit the call button on both ends at almost exactly the same time.



          createPeerConnection() is a misnomer. Instead, just initialize the pc with its ontrack and onicecandidate callbacks on page load.



          Still not working?



          The rest of your WebRTC-related code you're showing us looks fine—except you're calling getUserMedia twice on the answerer side, which is redundant, but shouldn't be a problem.



          I suspect a bug in your server logic. E.g. you're not showing us how emitting 'create or join' turns into either a 'created' or 'joined' socket message. You're also trying to predetermine which side is which in the offer/answer exchange, which is fine, except this means you have a non-working Call button on the answerer side. Most demos just let whoever pushes the button first be the offerer, though that might create glare. Just FYI.



          This is a two-way call. In which direction is remoteVideo not working?



          Also, you have a two-way call here, sending video in both directions, yet you've not mentioned which remoteVideo you're not seeing.



          For a working example, check out my two-way tab demo. Open it in two adjacent windows in the same browser, and click the Call button in one of them to connect. You should see (the same) video being sent both ways. It relies on a localSocket hack using localStorage.






          share|improve this answer


























          • Sorry I don't quite get what u are saying. pc has already been configured at the start with var pc = new RTCPeerConnection(configuration); but I did try to add another createPeerConnection() where the offer message is received but it does not create the remote video stream.

            – Rj Tng
            Dec 3 '18 at 6:51













          • @RjTng That's what I meant.

            – jib
            Dec 3 '18 at 17:16













          • Both sides of the remote video isn't working. I went to try to start the room on a phone, the local video would be able to be displayed but after pressing the call button it immediately shuts off. This was after adding the PeerConnection to the offer case and commenting out the redundant getUserMedia. Been trying to do it on localhost too and comparing my code with yours it seems like its correct.

            – Rj Tng
            Dec 4 '18 at 4:16











          • for the socket.io signalling, I would think its correct as its from the codelabs if (numClients === 0) { socket.join(room); log('Client ID ' + socket.id + ' created room ' + room); socket.emit('created', room, socket.id); } else if (numClients === 1) { log('Client ID ' + socket.id + ' joined room ' + room); io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready', room); } else { // max two clients socket.emit('full', room); }

            – Rj Tng
            Dec 4 '18 at 4:18











          • Codelabs? Hah. I've shown you a working version, so hopefully you'll be able to find out how your code differs, and get it working. Good luck!

            – jib
            Dec 4 '18 at 6:58














          0












          0








          0







          You're missing a call to createPeerConnection() on the answerer side, which means the answerer isn't properly set up to signal ICE candidates or fire the track event.



          You only call it from startCall(), so this would only work if you hit the call button on both ends at almost exactly the same time.



          createPeerConnection() is a misnomer. Instead, just initialize the pc with its ontrack and onicecandidate callbacks on page load.



          Still not working?



          The rest of your WebRTC-related code you're showing us looks fine—except you're calling getUserMedia twice on the answerer side, which is redundant, but shouldn't be a problem.



          I suspect a bug in your server logic. E.g. you're not showing us how emitting 'create or join' turns into either a 'created' or 'joined' socket message. You're also trying to predetermine which side is which in the offer/answer exchange, which is fine, except this means you have a non-working Call button on the answerer side. Most demos just let whoever pushes the button first be the offerer, though that might create glare. Just FYI.



          This is a two-way call. In which direction is remoteVideo not working?



          Also, you have a two-way call here, sending video in both directions, yet you've not mentioned which remoteVideo you're not seeing.



          For a working example, check out my two-way tab demo. Open it in two adjacent windows in the same browser, and click the Call button in one of them to connect. You should see (the same) video being sent both ways. It relies on a localSocket hack using localStorage.






          share|improve this answer















          You're missing a call to createPeerConnection() on the answerer side, which means the answerer isn't properly set up to signal ICE candidates or fire the track event.



          You only call it from startCall(), so this would only work if you hit the call button on both ends at almost exactly the same time.



          createPeerConnection() is a misnomer. Instead, just initialize the pc with its ontrack and onicecandidate callbacks on page load.



          Still not working?



          The rest of your WebRTC-related code you're showing us looks fine—except you're calling getUserMedia twice on the answerer side, which is redundant, but shouldn't be a problem.



          I suspect a bug in your server logic. E.g. you're not showing us how emitting 'create or join' turns into either a 'created' or 'joined' socket message. You're also trying to predetermine which side is which in the offer/answer exchange, which is fine, except this means you have a non-working Call button on the answerer side. Most demos just let whoever pushes the button first be the offerer, though that might create glare. Just FYI.



          This is a two-way call. In which direction is remoteVideo not working?



          Also, you have a two-way call here, sending video in both directions, yet you've not mentioned which remoteVideo you're not seeing.



          For a working example, check out my two-way tab demo. Open it in two adjacent windows in the same browser, and click the Call button in one of them to connect. You should see (the same) video being sent both ways. It relies on a localSocket hack using localStorage.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 3 '18 at 17:36

























          answered Dec 3 '18 at 2:36









          jibjib

          21.9k64694




          21.9k64694













          • Sorry I don't quite get what u are saying. pc has already been configured at the start with var pc = new RTCPeerConnection(configuration); but I did try to add another createPeerConnection() where the offer message is received but it does not create the remote video stream.

            – Rj Tng
            Dec 3 '18 at 6:51













          • @RjTng That's what I meant.

            – jib
            Dec 3 '18 at 17:16













          • Both sides of the remote video isn't working. I went to try to start the room on a phone, the local video would be able to be displayed but after pressing the call button it immediately shuts off. This was after adding the PeerConnection to the offer case and commenting out the redundant getUserMedia. Been trying to do it on localhost too and comparing my code with yours it seems like its correct.

            – Rj Tng
            Dec 4 '18 at 4:16











          • for the socket.io signalling, I would think its correct as its from the codelabs if (numClients === 0) { socket.join(room); log('Client ID ' + socket.id + ' created room ' + room); socket.emit('created', room, socket.id); } else if (numClients === 1) { log('Client ID ' + socket.id + ' joined room ' + room); io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready', room); } else { // max two clients socket.emit('full', room); }

            – Rj Tng
            Dec 4 '18 at 4:18











          • Codelabs? Hah. I've shown you a working version, so hopefully you'll be able to find out how your code differs, and get it working. Good luck!

            – jib
            Dec 4 '18 at 6:58



















          • Sorry I don't quite get what u are saying. pc has already been configured at the start with var pc = new RTCPeerConnection(configuration); but I did try to add another createPeerConnection() where the offer message is received but it does not create the remote video stream.

            – Rj Tng
            Dec 3 '18 at 6:51













          • @RjTng That's what I meant.

            – jib
            Dec 3 '18 at 17:16













          • Both sides of the remote video isn't working. I went to try to start the room on a phone, the local video would be able to be displayed but after pressing the call button it immediately shuts off. This was after adding the PeerConnection to the offer case and commenting out the redundant getUserMedia. Been trying to do it on localhost too and comparing my code with yours it seems like its correct.

            – Rj Tng
            Dec 4 '18 at 4:16











          • for the socket.io signalling, I would think its correct as its from the codelabs if (numClients === 0) { socket.join(room); log('Client ID ' + socket.id + ' created room ' + room); socket.emit('created', room, socket.id); } else if (numClients === 1) { log('Client ID ' + socket.id + ' joined room ' + room); io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready', room); } else { // max two clients socket.emit('full', room); }

            – Rj Tng
            Dec 4 '18 at 4:18











          • Codelabs? Hah. I've shown you a working version, so hopefully you'll be able to find out how your code differs, and get it working. Good luck!

            – jib
            Dec 4 '18 at 6:58

















          Sorry I don't quite get what u are saying. pc has already been configured at the start with var pc = new RTCPeerConnection(configuration); but I did try to add another createPeerConnection() where the offer message is received but it does not create the remote video stream.

          – Rj Tng
          Dec 3 '18 at 6:51







          Sorry I don't quite get what u are saying. pc has already been configured at the start with var pc = new RTCPeerConnection(configuration); but I did try to add another createPeerConnection() where the offer message is received but it does not create the remote video stream.

          – Rj Tng
          Dec 3 '18 at 6:51















          @RjTng That's what I meant.

          – jib
          Dec 3 '18 at 17:16







          @RjTng That's what I meant.

          – jib
          Dec 3 '18 at 17:16















          Both sides of the remote video isn't working. I went to try to start the room on a phone, the local video would be able to be displayed but after pressing the call button it immediately shuts off. This was after adding the PeerConnection to the offer case and commenting out the redundant getUserMedia. Been trying to do it on localhost too and comparing my code with yours it seems like its correct.

          – Rj Tng
          Dec 4 '18 at 4:16





          Both sides of the remote video isn't working. I went to try to start the room on a phone, the local video would be able to be displayed but after pressing the call button it immediately shuts off. This was after adding the PeerConnection to the offer case and commenting out the redundant getUserMedia. Been trying to do it on localhost too and comparing my code with yours it seems like its correct.

          – Rj Tng
          Dec 4 '18 at 4:16













          for the socket.io signalling, I would think its correct as its from the codelabs if (numClients === 0) { socket.join(room); log('Client ID ' + socket.id + ' created room ' + room); socket.emit('created', room, socket.id); } else if (numClients === 1) { log('Client ID ' + socket.id + ' joined room ' + room); io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready', room); } else { // max two clients socket.emit('full', room); }

          – Rj Tng
          Dec 4 '18 at 4:18





          for the socket.io signalling, I would think its correct as its from the codelabs if (numClients === 0) { socket.join(room); log('Client ID ' + socket.id + ' created room ' + room); socket.emit('created', room, socket.id); } else if (numClients === 1) { log('Client ID ' + socket.id + ' joined room ' + room); io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready', room); } else { // max two clients socket.emit('full', room); }

          – Rj Tng
          Dec 4 '18 at 4:18













          Codelabs? Hah. I've shown you a working version, so hopefully you'll be able to find out how your code differs, and get it working. Good luck!

          – jib
          Dec 4 '18 at 6:58





          Codelabs? Hah. I've shown you a working version, so hopefully you'll be able to find out how your code differs, and get it working. Good luck!

          – jib
          Dec 4 '18 at 6:58


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53582983%2fremote-video-stream-not-showing-up-at-all%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          MongoDB - Not Authorized To Execute Command

          How to fix TextFormField cause rebuild widget in Flutter

          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith