RTCMultiConnection icon indicating copy to clipboard operation
RTCMultiConnection copied to clipboard

echo problem

Open Nitrick opened this issue 9 years ago • 9 comments

Hello,

I am having issue on echo problem and it occurs when I connect second camera at that time the echo starts but it is not permanent it's the main issue Pl. Solve this problem muaz Khan.

Thanks & Regards Aditya shrivastava

Nitrick avatar Jun 25 '16 18:06 Nitrick

Hello muaz Khan plz help on this problem

Nitrick avatar Jul 03 '16 11:07 Nitrick

Please make sure to place both cameras away from each other.

Actually we need to make sure that Speakers doesn't distorts voice captured by microphones. Both devices must have a clear distance.

  • http://www.slideshare.net/MuazKhan/echo-in-webrtc-why

muaz-khan avatar Jul 03 '16 11:07 muaz-khan

Both side we are using head phones and the problem is occurring when I attach second camera to show when connection is on only at that time echo is coming and that is also not consistent so which type of code or volume of speakers 🔊 I should use.

Please make sure to place both cameras away from each other.

Actually we need to make sure that Speakers doesn't distorts voice captured by microphones. Both devices must have a clear distance.

  • http://www.slideshare.net/MuazKhan/echo-in-webrtc-why

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/muaz-khan/RTCMultiConnection/issues/190#issuecomment-230147784, or mute the thread https://github.com/notifications/unsubscribe/AQ41vix9x_jgYyOkk1tTjGCeol-KfmGrks5qR5gigaJpZM4I-Zbc .

Nitrick avatar Jul 03 '16 11:07 Nitrick

Are you using connection.onstream => event.mediaElement or you are creating mediaElement yourself?

E.g.

connection.onstream = function(event) {
    // event.mediaElement.pause();
    // delete event.mediaElement

    var video = document.createElement('video');
    video.src = URL.createObjectURL(event.stream);
};

muaz-khan avatar Jul 03 '16 11:07 muaz-khan

I am using this code: document.getElementById('btnAddCamera').onclick = function () { conn.DetectRTC.load(function () { $('#submenu').find('li').remove(); var i = 0; //var kl = new Array(); //connection.mediaConstraints.video.optional = []; conn.DetectRTC.MediaDevices.forEach(function (device) {

                    if (device.kind.indexOf('video') !== -1) {
                        if (device.kind == 'videoinput') {
                            if (!document.getElementById(device.id)) {
                                var list = document.createElement('li');
                                list.className = "kd"
                                videoSelect = document.createElement('a');
                                videoSelect.id = device.id;
                                i = i + 1
                                videoSelect.innerHTML = device.label + ' (' + i + ')' || device.id;
                                videoSelect.value = device.id;
                                videoSelect.href = "#";
                                //kl = device.id;
                                videoSelect.onclick = function (e) {


                                    var kl = this.id;
                                    var videoSourceId = kl;
                                    if (connection.mediaConstraints.video.optional.length && connection.attachStreams.length) {
                                        connection.mediaConstraints.video.optional[0].sourceId = videoSourceId;
                                        var stream = event.stream
                                        connection.removeStream({ audio: true });
                                        connection.addStream({ audio: true, video: true })
                                        videoId = this.id;
                                        scaleVideos();
                                    }
                                    else {
                                        connection.mediaConstraints.video.optional = [{
                                            sourceId: videoSourceId
                                        }];
                                        connection.removeStream({ audio: true });
                                        connection.addStream({ audio: true, video: true });
                                        scaleVideos();
                                    }
                                };


                                videoSelect.className = "btn btn-default1";
                                list.appendChild(videoSelect)
                                camera.appendChild(list);

                                if (conn.mediaConstraints.video.optional.length && conn.mediaConstraints.video.optional[0].sourceId === device.id) {
                                    videoSelect.selected = true;
                                }
                            }
                        }
                    }
                });
            });

And back side i use the connection.onaddstream

setRemoteDescription: function (sessionDescription, onSdpSuccess) {

            if (!sessionDescription) throw 'Remote session description should NOT be NULL.';

            if (!this.connection) return;

            log('setting remote description', sessionDescription.type, sessionDescription.sdp);
            this.connection.onaddstream = function (e) {

                log('onaddstream', isPluginRTC ? e.stream : toStr(e.stream));

                //if(e.streamid==this.)
                setTimeout(function () {

                    self.onaddstream(e.stream, self.session);
                }, 1000);
                //else



            };

            var self = this;
            this.connection.setRemoteDescription(new RTCSessionDescription(sessionDescription), onSdpSuccess || this.onSdpSuccess,

                function (error) {

                    //if (error.search(/STATE_SENTINITIATE|STATE_INPROGRESS/gi) == -1) {
                    self.onSdpError(error);
                    //}
                }
            );
        },

this two thinks help me to attach another camera in both the side when connection is on

Nitrick avatar Jul 03 '16 11:07 Nitrick

Could you please help, I am unable to send Back Camera Stream, it is always send front camera Stream

const select = document.getElementById('select');

                navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);
                
                //navigator.mediaDevices.getUserMedia({video: {deviceId: c amera.deviceId}}).then(function(stream) {
                
                //}

                document.getElementById("select").style.display = "";

                document.getElementById("select").addEventListener("change", changeCamDown);

                function changeCamDown() {

                    debugger;
                /*    var innerDataHtml = document.getElementById('videos-container').querySelector('.media-box').childNodes[0].innerHTML;
                    //var existing = document.querySelector('#videos-container').querySelector('.media-container');

                    //if (typeof streamLocal !== 'undefined') {
                    //    stopMediaTracks(streamLocal);
                    //}
                    const videoConstraints = {};

                    if (select.value == '') {
                        videoConstraints.facingMode = 'environment';
                    } else {
                        videoConstraints.deviceId = { exact: select.value };
                    }
                    const constraints = {
                        video: videoConstraints,
                        audio: true,
                        data: true,
                        oneway: true
                    };

                   
                    //if (existing && existing.parentNode) {
                    //    existing.parentNode.removeChild(existing);
                    //}

                    //var video = document.createElement('video');

                    //try {
                    //    video.setAttributeNode(document.createAttribute('autoplay'));
                    //    video.setAttributeNode(document.createAttribute('playsinline'));
                    //} catch (e) {
                    //    video.setAttribute('autoplay', true);
                    //    video.setAttribute('playsinline', true);
                    //}

                    //if (event.type === 'local') {

                    //    video.volume = 0;
                    //    try {
                    //        video.setAttributeNode(document.createAttribute('muted'));
                    //    } catch (e) {
                    //        video.setAttribute('muted', true);
                    //    }
                    //}


                    navigator.mediaDevices
                      .getUserMedia(constraints)
                      .then(stream => {
                          streamLocal = stream;
                          videos.srcObject = stream;
                          return navigator.mediaDevices.enumerateDevices();
                      })
                      .then(gotDevices)
                      .catch(error => {
                          console.error(error);
                      });

                       */

                    //if (select.value != '') {
                    //    connection.mediaConstraints.video.optional = [{
                    //        sourceId: select.value
                    //    }];
                    //}

                    if (connection.mediaConstraints.video.optional.length && connection.attachStreams.length) {
                        connection.mediaConstraints.video.optional[0].sourceId = select.value;
                        connection.removeStream({ audio: true });
                        connection.addStream({ audio: true, video: true })
                    }
                    else {
                        connection.mediaConstraints.video.optional = [{
                            sourceId: select.value
                        }];
                        connection.removeStream({ audio: true });
                        connection.addStream({ audio: true, video: true });
                    }

                    event.streamid = streamLocal.streamid;

                    //connection.videosContainer = document.getElementById('videos-container');

                    //var width = parseInt(connection.videosContainer.clientWidth / 2) - 20;
                    //var mediaElement = getHTMLMediaElement(video, {
                    //    title: 'Back Camera',
                    //    buttons: ['full-screen'],
                    //    width: width,
                    //    showOnMouseEnter: false
                    //});


                    //connection.session = constraints;

                 //   connection.videosContainer.appendChild(mediaElement);

                    // document.getElementById('videos-container').querySelector('.media-box').childNodes[0].innerHTML = innerDataHtml;

                    // mediaElement.media.play();

                    //setTimeout(function () {
                    //    mediaElement.media.play();
                    //}, 500);

                    //mediaElement.id = event.streamid;

                    //setTimeout(function () {
                    //    connection.addStream(constraints);
                    //}, 300);

                  

                }

  function gotDevices(mediaDevices) {
        debugger;
        select.innerHTML = '';
        select.appendChild(document.createElement('option'));
        let count = 1;
        mediaDevices.forEach(mediaDevice => {
            if (mediaDevice.kind === 'videoinput') {
                const option = document.createElement('option');
                option.value = mediaDevice.deviceId;
                const label = mediaDevice.label || `Camera ${count  }`;
                const textNode = document.createTextNode(label);
                option.appendChild(textNode);
                select.appendChild(option);
            }
        });
    }

    function stopMediaTracks(stream) {
        stream.getTracks().forEach(track => {
            track.stop();
        });

        connection.attachStreams.forEach(function (stream) {
            stream.stop();
        });
    }

IndranilSarkar87 avatar Aug 25 '18 15:08 IndranilSarkar87

@IndranilSarkar87 Use this to change between front & back camera.

function openOrJOinRoom(roomid) {
    connection.mediaConstraints = {
        audio: true,
        video: {
            facingMode: 'application'
        }
    };

    connection.openOrJoin(roomid);
}

function selectFrontCameraDuringActiveSession() {
    // we need to stop previous video tracks because
    // mobile device may not allow us capture
    // both front and back camera streams
    // at the same time
    connection.attachStreams.forEach(function(stream) {
        // stop only video tracks
        // so that we can recapture video track
        stream.getVideoTracks().forEach(function(track) {
            track.stop();
        });
    });

    var mediaConstraints = {
        audio: false, // NO need to capture audio again
        video: {
            facingMode: 'user'
        }
    };

    navigator.mediaDevices.getUserMedia(mediaConstraints).then(function(frontCamera) {
        var frontCameraTrack = frontCamera.getVideoTracks()[0];
        connection.getAllParticipants().forEach(function(pid) {
            connection.peers[pid].peer.getSenders().forEach(function(sender) {
                if (sender.track.kind == 'video') {
                    sender.replaceTrack(frontCameraTrack);
                }
            });
        });
    });
}

function selectBackCameraDuringActiveSession() {
    // we need to stop previous video tracks because
    // mobile device may not allow us capture
    // both front and back camera streams
    // at the same time
    connection.attachStreams.forEach(function(stream) {
        // stop only video tracks
        // so that we can recapture video track
        stream.getVideoTracks().forEach(function(track) {
            track.stop();
        });
    });

    var mediaConstraints = {
        audio: false, // NO need to capture audio again
        video: {
            facingMode: 'application'
        }
    };

    navigator.mediaDevices.getUserMedia(mediaConstraints).then(function(frontCamera) {
        var frontCameraTrack = frontCamera.getVideoTracks()[0];
        connection.getAllParticipants().forEach(function(pid) {
            connection.peers[pid].peer.getSenders().forEach(function(sender) {
                if (sender.track.kind == 'video') {
                    sender.replaceTrack(frontCameraTrack);
                }
            });
        });
    });
}

muaz-khan avatar Aug 29 '18 05:08 muaz-khan

@muaz-khan sir , I have been facing switch-camera issue for a long time. Finally I saw this solution. I can on back camera with this solution but when I tried to start front camera again then I got this error "NotReadableError: Could not start video source". I have printed stream inside connection.attachStreams event, it didn't stop the videoTrack(I think). Also when back camera is started connection.attachStreams reamain same. It doesn't update. Here is my code:

`switchCamera(){// switch Camera action

// we need to stop previous video tracks because
// mobile device may not allow us capture
// both front and back camera streams
// at the same time

this.connection.attachStreams.forEach(function(stream) {

  console.log("Camera stream details");
  console.log(stream);
    // stop only video tracks
    // so that we can recapture video track
  stream.getVideoTracks().forEach(function(track) {
      track.stop();
  });

});

this.connection.DetectRTC.load(function() {

  var mediaConstraints;

  if(!this.frontOrRear){ // start back camera

    console.log("Back camera started");

    mediaConstraints = {
      audio: false,
      video: {
          deviceId: this.connection.DetectRTC.videoInputDevices[1].deviceId
      }
    };

  }
  else {

    console.log("Front camera started");

    mediaConstraints = {
      audio: false,
      video: {
          deviceId: this.connection.DetectRTC.videoInputDevices[0].deviceId
      }
    };
  }

  navigator.mediaDevices.getUserMedia(mediaConstraints).then(function(frontCamera) {
    var frontCameraTrack = frontCamera.getVideoTracks()[0];
    this.connection.getAllParticipants().forEach(function(pid) {
        this.connection.peers[pid].peer.getSenders().forEach(function(sender) {
            if (sender.track.kind == 'video') {
                sender.replaceTrack(frontCameraTrack);
            }
        });
    });
  });

  // localThis.connectionProvider.connection.captureUserMedia(() => {
  //
  //   localThis.connectionProvider.connection.renegotiate(); // share with all existing users
  //
  // });

  this.frontOrRear = !this.frontOrRear;

});

}`

Your RTCMulticonnection helped me a lot and you are a great instructor I've ever seen. Thanks in advance.

shahnawaz-pabon avatar Dec 25 '18 09:12 shahnawaz-pabon

It worked Finally. I stored stream from "navigator.mediaDevices.getUserMedia" into a global variable and then before call "navigator.mediaDevices.getUserMedia" again I did this:

stopLocalStream.getTracks().forEach(function(track) { track.stop(); });

Inside "navigator.mediaDevices.getUserMedia", I wroted

stopLocalStream = cameraStream; // store current camera stream

But in some devices I got this error:

"TypeError: sender.replaceTrack is not a function"

I don't know why? How can I get rid of this error? I'll be glad if you help me @muaz-khan sir.

shahnawaz-pabon avatar Dec 26 '18 13:12 shahnawaz-pabon