es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

el problema cuando se crea por segunda vez una conexión de igual a igual (peer-to-peer) WebRTC (ya existe un remitente para la pista), ¿tienes alguna idea de cómo debería manejarlo?

Estoy usando React, socket.io y WebRTC. La primera conexión funciona bien, pero la próxima vez que intento conectarme, creo que hay un problema con SDP que no se actualiza. Ya llamé close() en la conexión entre los pares.

Código de error:

InvalidAccessError: Failed to execute ‘addTrack’ on ‘RTCPeerConnection’: A sender already exists for the track.

Mi función initCall se llamó en useEffect.

let configRTC = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] };

let localConnection = new RTCPeerConnection(configRTC);
let remoteConnection = new RTCPeerConnection(configRTC);
const initCall = (stream, loca) => {
socket.on('other-users', (socketId) => {
    console.log('other user');
    conn = localConnection;
    stream.getTracks().forEach((track) => localConnection.addTrack(track, stream));
    localConnection.onicecandidate = ({ candidate }) => {
      candidate && socket.emit('candidate', { socketId, candidate });
    };

// Recibir stream del cliente remoto y agregar al área de video remota
    localConnection.ontrack = ({ streams: [stream] }) => {
      if (!remoteVideo.current) return;
      remoteVideo.current.srcObject = stream;
    };

  localConnection
    .createOffer({ offerToReceiveAudio: 1, offerToReceiveVideo: 1, iceRestart: true })
    .then((offer) => localConnection.setLocalDescription(offer))
    .then(() => {
      socket.emit('offer', { socketId, description: localConnection.localDescription});
    });
});

socket.on('offer', (data) => {
    // Ininit peer connection
    console.log('offer', data.socketId);
    console.log('des', data.description);
    conn = remoteConnection;
    console.log('remote', remoteConnection.signalingState);
    console.log('remoteTRICKLE', remoteConnection.iceGatheringState);
    remoteConnection.onnegotiationneeded = (event) => {
      try {
        console.log(remoteConnection.signalingState);
        console.log(this.remoteConnection.signalingState);
      } catch (e) {
        console.log(e);
      }
    };

conn = remoteConnection;
remoteConnection.restartIce();

stream.getTracks().forEach((track) => remoteConnection.addTrack(track, stream));

remoteConnection.onicecandidate = ({ candidate }) => {
  candidate && socket.emit('candidate', { socketId: data.socketId, candidate });
};

// Receive stream from remote client and add to remote video area
remoteConnection.ontrack = ({ streams: [stream] }) => {
  remoteVideo.current.srcObject = stream;
};
  remoteConnection
    .setRemoteDescription(data.description)
    .then(async () => await remoteConnection.createAnswer())
    .then(async (answer) => await remoteConnection.setLocalDescription(answer))

    .then(() => {
      console.log('answer', data.socketId);
      console.log('answerDes', remoteConnection.localDescription);

      socket.emit('answer', { socketId: data.socketId, description: remoteConnection.localDescription });
    });

});

socket.on('answer', (data) => {
      let description = new RTCSessionDescription(data.description);
      localConnection.setRemoteDescription(description);
  });

socket.on('candidate', (candidate) => {
    let can = new RTCIceCandidate(candidate);
    conn.addIceCandidate(can);
  });
  return;
};
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que el error se produce al tener remitentes existentes para una pista, lo que impide agregar otro mediante el método addTrack de RTCPeerConnection. Esto podría estar sucediendo porque el protocolo de descripción de sesión (SDP, por sus siglas en inglés) no se actualiza correctamente después de llamar a close() en la conexión entre pares.

    Para solucionar este problema, puedes intentar los siguientes pasos:

    1. Asegúrate de cerrar tanto las conexiones de pares locales como remotas cuando se termina o se desconecta la llamada. Puedes hacerlo llamando al método close() en ambas instancias.
    2. En lugar de llamar a createOffer() y setLocalDescription() por separado, puedes combinarlos en una sola llamada usando el método createOffer() con el método setLocalDescription() como devolución de llamada. Esto puede asegurar que el SDP se actualice correctamente.

    3. También puedes intentar llamar al método restartIce() en la conexión de pares remotas al recibir una oferta del otro usuario. Esto puede forzar un nuevo proceso de recopilación de ICE y actualizar el SDP.

    localConnection.createOffer({ offerToReceiveAudio: 1, offerToReceiveVideo: 1, iceRestart: true })
    .then((offer) => {
      localConnection.setLocalDescription(offer, () => {
        socket.emit('offer', { socketId, description: localConnection.localDescription });
      });
    });
    
    // ...
    
    socket.on('offer', (data) => {
      // Limpiar los remitentes existentes para las pistas
      remoteConnection.getSenders().forEach(sender => {
        remoteConnection.removeTrack(sender);
      });
    
      // Reiniciar ICE y agregar pistas a la conexión remota
      remoteConnection.restartIce();
    
      stream.getTracks().forEach((track) => {
        remoteConnection.addTrack(track, stream);
      });
    
      // Establecer la descripción remota y crear respuesta
      remoteConnection.setRemoteDescription(data.description)
      .then(() => {
        return remoteConnection.createAnswer();
      })
      .then((answer) => {
        return remoteConnection.setLocalDescription(answer);
      })
      .then(() => {
        console.log('answer', data.socketId);
        console.log('answerDes', remoteConnection.localDescription);
    
        socket.emit('answer', { socketId: data.socketId, description: remoteConnection.localDescription });
      });
    });
    

    Siguiendo estos pasos, deberías poder actualizar el SDP y evitar el mensaje de error al agregar pistas a la conexión entre pares.

Comments are closed.