Not recieving remote video stream when accessing by directly modifying url params

596 Views Asked by At

So I've started playing around with the simple mediasoup demo found here: https://github.com/Dirvann/mediasoup-sfu-webrtc-video-rooms

I setup the demo and all is working fine.

The first thing I'm trying to do is add url params to bypass the login screen, which should be easy, right? But for some reason, when you navigate to a room by directly modifying the url params, it does not display the remote streams of other users in the room! And it does display the streams of other users in the room when the user joins a room using the login form.

It baffles me because whether you click the 'join' button on the login form, or your url has the params already present, the exact same js method is being executed!

Here I will demonstrate the execution flow:

Initially we have 1 user sharing webcam in room 123. A second user navigates to the url without relevant params present and as such, they are presented with the login form: enter image description here

Upon checking the details, the user realises the defaults are fine and proceeds to click the join button. This calls a simple function that adds the room and user values to the URL by updating window.location.href (it causes a page refresh)

When the page refresh completes, the necessary params are present, which causes the video room to load and the remote stream to display, as depicted: enter image description here

However the problem occurs when we don't login via the form, and we directly add those necessary params to the url ourselves. As depicted: enter image description here There should be a remote stream here, because it's the same room as in the previous image. I'm clueless as to why this issue is occurring.

Here is my index.js file, my changes are all within the slashes, near the bottom of the file:

if (location.href.substr(0, 5) !== 'https')
  location.href = 'https' + location.href.substr(4, location.href.length - 4)

const socket = io()


let producer = null;

nameInput.value = 'bob' + Math.round(Math.random() * 1000)

socket.request = function request(type, data = {}) {
  return new Promise((resolve, reject) => {
    socket.emit(type, data, (data) => {
      if (data.error) {
        reject(data.error)
      } else {
        resolve(data)
      }
    })
  })
}

let rc = null

function joinRoom(name, room_id) {
  if (rc && rc.isOpen()) {
    console.log('already connected to a room')
  } else {
    rc = new RoomClient(localMedia, remoteVideos, remoteAudios, window.mediasoupClient, socket, room_id, name, roomOpen)

    addListeners()
  }

}



function roomOpen() {
  login.className = 'hidden'
  reveal(startAudioButton)
  hide(stopAudioButton)
  reveal(startVideoButton)
  hide(stopVideoButton)
  reveal(startScreenButton)
  hide(stopScreenButton)
  reveal(exitButton)
  control.className = ''
  reveal(videoMedia)
}

function hide(elem) {
  elem.className = 'hidden'
}

function reveal(elem) {
  elem.className = ''
}


function addListeners() {
  rc.on(RoomClient.EVENTS.startScreen, () => {
    hide(startScreenButton)
    reveal(stopScreenButton)
  })

  rc.on(RoomClient.EVENTS.stopScreen, () => {
    hide(stopScreenButton)
    reveal(startScreenButton)

  })

  rc.on(RoomClient.EVENTS.stopAudio, () => {
    hide(stopAudioButton)
    reveal(startAudioButton)

  })
  rc.on(RoomClient.EVENTS.startAudio, () => {
    hide(startAudioButton)
    reveal(stopAudioButton)
  })

  rc.on(RoomClient.EVENTS.startVideo, () => {
    hide(startVideoButton)
    reveal(stopVideoButton)
  })
  rc.on(RoomClient.EVENTS.stopVideo, () => {
    hide(stopVideoButton)
    reveal(startVideoButton)
  })
  rc.on(RoomClient.EVENTS.exitRoom, () => {
    hide(control)
    reveal(login)
    hide(videoMedia)

    /////////////////////////
    let indexOfQuestionMark = location.href.indexOf("?")
    location.href = location.href.split('').slice(0, indexOfQuestionMark-1).join('')
    /////////////////////////

  })
}

// Load mediaDevice options
navigator.mediaDevices.enumerateDevices().then(devices =>
  devices.forEach(device => {
    let el = null
    if ('audioinput' === device.kind) {
      el = audioSelect
    } else if ('videoinput' === device.kind) {
      el = videoSelect
    }
    if(!el) return

    let option = document.createElement('option')
    option.value = device.deviceId
    option.innerText = device.label
    el.appendChild(option)
  })
)
/////////////////////////
if (window.location.href.includes("?r=") && window.location.href.includes("n=")) {
  let indexOfRoomNumber = location.href.indexOf("?r=")+3
  let array = location.href.split('')
  let room = array.slice(indexOfRoomNumber,indexOfRoomNumber+3).join("")
  let username = array.slice(indexOfRoomNumber+6, array.length).join("")
  joinRoom(username,room)
  console.log(`Welcome to room: ${room}, ${username}`)

}

function addParams(name, room_id) {
  window.location.href = `${location.href}?r=${room_id}+n=${name}`
}
//////////////////////////

The addParams function is directly called by the Join button within index.html, as you can see here:

<html>

<head>
    <script src="socket.io/socket.io.js"></script>
    <script src="modules/mediasoupclient.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/EventEmitter/5.2.8/EventEmitter.min.js"></script>
    <script src="RoomClient.js"></script>
    <style>
        .containers {
            display: grid;
            grid-gap: 5px;
            grid-template-columns: repeat(auto-fit, 1fr);
            grid-template-rows: repeat(auto-fit, 300px);
        }

        .container {
            display: flex;
        }

        .vid {
            flex: 0 1 auto;
            height: 400px;
        }

        .settings {
            background-color: #4CAF50;
            border: none;
            color: white;
            padding: 5px 10px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 14px;
            margin: 2px 2px;
            cursor: pointer;
        }

        .hidden {
            display: none
        }
    </style>
</head>

<body>
    <div id="login">
        Room:   <input id="roomidInput" value="123" type="text" />
        <!--<button id="createRoom" onclick="createRoom(roomid.value)" label="createRoom">Create Room</button>-->
        <br />
        User: <input id='nameInput' value="bob" type="text" />
        <button id='joinButton' onclick="addParams(nameInput.value, roomidInput.value)">Join</button>
    </div>
    <div id="control" class="hidden">
        <button id='exitButton' class='hidden' onclick="rc.exit()">Exit</button>
        <br/>
        audio: <select id="audioSelect">
        </select>
        <br/>
        video: <select id="videoSelect">
        </select>
        <br />
        <button id='startAudioButton' class='hidden' onclick="rc.produce(RoomClient.mediaType.audio, audioSelect.value)">audio</button>
        <button id='stopAudioButton' class='hidden' onclick="rc.closeProducer(RoomClient.mediaType.audio)">close
            audio</button>
        <button id='startVideoButton' class='hidden' onclick="rc.produce(RoomClient.mediaType.video, videoSelect.value)">video</button>
        <button id='stopVideoButton' class='hidden' onclick="rc.closeProducer(RoomClient.mediaType.video)">close
            video</button>
        <button id='startScreenButton' class='hidden' onclick="rc.produce(RoomClient.mediaType.screen)">screen</button>
        <button id='stopScreenButton' class='hidden' onclick="rc.closeProducer(RoomClient.mediaType.screen)">close
            screen</button>
        <br />
    </div>




    <div id='videoMedia' class='hidden'>
        <h2>------local------</h2>
        <div id="localMedia"></div>
        <!--<video id="localVideo" autoplay inline class="vid"></video>-->
        <!--<video id="localScreen" autoplay inline class="vid"></video>-->
        <h2>-----remote-----</h2>
        <div id="remoteVideos" class="container">
        </div>

        <div id="remoteAudios"></div>

    </div>
</body>
<footer>
    <script src="index.js"></script>
</footer>

</html>

Please note: The only files I have modified are those mentioned, above. All other files are the same as those in the github repo for the demo (linked at the top of this article.)

I'd be so grateful if somebody could help me get to the bottom of this issue. If having the url params there is what is causing the rooms to be joined, why does the method of putting the params in the URL seem to be making such a significant difference?

Thank you for your time and any assistance you may offer! :)

1

There are 1 best solutions below

3
On

The only difference is that you don't use user interaction for establishing the connection. There is user interaction needed for certain actions in the browser and this could be the reason why it doesn't work. Autoplay policy changes.

Adding a button to execute joinRoom when you're on the page could solve the issue.