Как закрыть mediastream после подключения нескольких удаленных пиров?

Я создаю несколько одноранговых соединений webrtc и создаю один медиапоток, используя

if (mediaStream == undefined) {
            navigator.mediaDevices.getUserMedia({
                audio: true,
                video: true
            }).then(function (stream) {
                mediaStream = stream;
                mediaStream.getTracks().forEach(function (track) {
                    rtcPeerConns[userName].addTrack(track, mediaStream);
                });
            }).catch(function (err) {
                console.log("get user media " + err.name + ": " + err.message);
            });
        } else {
            console.log("using the existing local stream");
            mediaStream.getTracks().forEach(function (track) {
                rtcPeerConns[userName].addTrack(track, mediaStream);
            });
        }

Все работает отлично, пока последнее одноранговое соединение не будет закрыто, и я хочу закрыть медиапоток.

if (mediaStream != undefined) {
        if (mediaStream.active) {
            mediaStream.getTracks().forEach(function (track) {
                track.stop();
            });
            mediaStream = null;
        }
    }

Если было использовано только одноранговое соединение, все отключается, как запланировано. Если MediaStream использовал более 1 однорангового соединения, то MediaStream становится нулевым, но индикатор камеры в браузере и индикатор камеры остаются включенными.

Что мне не хватает?

1 ответ

Решение

Это что-то вроде предположения, но кажется наиболее вероятной причиной, поэтому наличие большего количества кода поможет...

Если вы введете этот первый блок кода

if (mediaStream == undefined) {
    navigator.mediaDevices.getUserMedia({
      ...

снова перед первым обещанием, возвращенным getUserMedia будет решено, тогда у вас будет на самом деле несколько разных MediaStreams, поступающих с вашего устройства.

Глобальная переменная mediaStream будет представлять только последний MediaStream, полученный от getUserMediaи все предыдущие, пока они недоступны для вашего кода, все равно заблокируют ваше устройство.

Вот MCVE

Другими словами, вам необходимо провести рефакторинг вашего кода.

Вы должны лучше отслеживать, когда был сделан запрос на получение MediaStream, поэтому, чтобы сделать меньше изменений в вашем коде, я могу предложить вам фактически сохранить Обещание, которое возвращается getUserMedia [вместо / вместе с] хранения MediaStream.

Таким образом, следующие звонки будут просто then() это обещание, чтобы получить доступ к тому же MediaStream.

// outer scope
var stream_request = null;
// [...]
function requestStream() {
  if(!stream_request) {
    stream_request =  navigator.mediaDevices.getUserMedia(options);
  }
  return stream_request
       .then(doSomethingWithTheMediaStream);
}

// and to kill it
function kill_stream() {
  return stream_request.then(stream => {
    stream.getTracks().forEach(t => t.stop());
  }
}

живой пример

Другие вопросы по тегам