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

Я создаю несколько одноранговых соединений 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;
        }
    }

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

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


person Croftie    schedule 22.11.2018    source источник
comment
отредактировал код и теперь, как ни странно, он работает. В полном коде было 2 места, где можно было вызвать медиапоток в зависимости от того, был ли клиент оферентом или получателем оферты. Один из них вызывал новый медиапоток, и в этом была проблема. Спасибо Кайидо за настойчивость   -  person Croftie    schedule 25.11.2018


Ответы (1)


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

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

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

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

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

Вот MCVE

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

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

Таким образом, следующие вызовы должны будут просто then() это Promise, чтобы получить доступ к тому же 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());
  }
}

живой пример

person Kaiido    schedule 23.11.2018
comment
Я попытался сначала настроить медиапоток, а затем добавить его в peerConnections. Невозможно создать более одного mediaStream. Похоже, что именно добавление медиапотока к нескольким одноранговым узлам является проблемой, которая разрывает связь между ссылкой на медиапоток и медиа. - person Croftie; 23.11.2018
comment
@Croftie, как я сказал в своем ответе, чтобы быть на 100% уверенным в том, что происходит, нам понадобятся дополнительные сведения о вашей настройке, которые вы должны добавить в качестве редактирования в свой исходный вопрос. Но опять же, это наиболее правдоподобная причина. Что бы вы ни делали с этим MediaStream впоследствии, это не должно иметь никакого отношения к его следам и к тому, как они блокируют устройство. На этапе отладки вы можете записывать в журнал треки mediaStream id при их получении и остановке. Если они отличаются, у вас есть несколько потоков с одного устройства. - person Kaiido; 24.11.2018