What's the Deal with VueJS and WebRTC: Troubleshooting Remote Video Playback Issues

For a sample application I am developing, I need to incorporate two video elements and a "Call" button. The first video element (#localVideo) will display the local media stream output. Upon clicking the call button, the remote video element should play the remote media stream. Initially, I created this application in raw JavaScript, where everything was functioning correctly.

In VueJS, I am working on a WebRTC component to access user media and assign the stream to the local video element. When users click the call button, I create two RTCPeerConnection objects, send offers, set local descriptions, send answers, and so on.

Here is the template code for the component -

<template>
  <div class="webRTC">
    <video id = "localVideo" playsinline autoplay muted></video>
    <button id = "call" v-on:click='call'> Call </button>
    <video id = "remoteVideo" playsinline autoplay controls></video>
  </div>
</template>

<script src="./webRTC.js"></script>

And here is the script section of the component -

export default {
  name: 'webRTC',
  sockets: {
    connect: function () {
      console.log('Socket IO connected!')
    },

    TestConnection: function () {
      console.log('Test connection successful!')
    }
  },

  data: function () {
    return {
      localStream: null,
      remoteStream: null,
      pc1: null,
      pc2: null
    }
  },

  methods: {
    // Methods included here...
  },

  created: function () {
    console.log('webRTC is created!')
    let prom = navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(this.gotDevices).catch(this.handleMediaError)
  }
}

The issue I'm encountering is that upon clicking the Call button, the remote video does not display anything. Instead, there's just a loading circle shown. There are no errors displayed in the console either.

I have checked the srcObject of both the local and remote videos, and they seem to be the same - https://i.sstatic.net/Cgxlj.png. Can someone please guide me on what might be wrong? Additionally, is there another way to debug this?

Note:

You can download the project/source code from here: https://drive.google.com/open?id=1e7C0ojZ0jT7EXFNtCKcWpJBpKd_mWi_s

Answer №1

To utilize promises without the need for async/await, it is essential to manually handle error propagation and check them accordingly.

Incorporate a catch statement, as shown below, to monitor errors:

this.pc1.createOffer({offerToReceiveAudio: 1, offerToReceiveVideo: 1})
  .then(this.gotDescription)
  .catch(e => console.log(e)); // <-- here

If you observe that this is undefined within the gotDescription() function, this is due to passing a member function as a callback to the then function, resulting in its invocation without a proper this. To address this, consider using this.gotDescription.bind(this) or elegant arrow functions like so:

this.pc1.createOffer({offerToReceiveAudio: 1, offerToReceiveVideo: 1})
  .then(offer => this.gotDescription(offer)) // arrow function invoking on this
  .catch(e => console.log(e));

Moreover, ensure that you return all promises to establish a unified chain for capturing all errors.

There are several ignored promise returns shown below:

/* const unusedPromise1 = */ this.pc1.setLocalDescription(description)
/* const unusedPromise2 = */ this.pc2.setRemoteDescription(description)
/* const unusedPromise3 = */ this.pc2.createAnswer().then(this.gotDescription2)

While RTCPeerConnection automatically queues operations performed on it, successful execution may not always guarantee correct error handling, particularly depending on the browser.

To efficiently manage errors, follow the approach outlined below:

this.pc1.setLocalDescription(description)
.then(() => this.pc2.setRemoteDescription(description))
.then(() => this.pc2.createAnswer())
.then(answer => this.gotDescription2(answer))
.catch(e => console.log(e))

Alternatively, leverage the more concise async/await syntax for accurate error propagation:

gotDescription: async function (description) {
  console.log('Got description 1')
  await this.pc1.setLocalDescription(description)
  await this.pc2.setRemoteDescription(description)
  await this.gotDescription2(await this.pc2.createAnswer());
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

FusionMaps XT integration with VueJs: Troubleshooting connectorClick events issue

I am experiencing some issues with events connectorClick on my VueJS processed map. When I click on the connector line in the example below, the alert function does not seem to work as expected. Vue.use(VueFusionCharts, FusionCharts); let grphMap = new ...

The Google Drive API in Node.js is notifying the deletion of files

I encountered an issue with the Google Drive API in my application. Even after deleting files from Google Drive, the listfiles function still returns those deleted files. Is there a solution to prevent this from happening? Below is the function of my API: ...

Triggering a d3.js event when two radio buttons are both selected

I am currently working with a sample code that displays data based on the selected radio button: http://bl.ocks.org/juan-cb/1984c7f2b446fffeedde To enhance this functionality, I decided to add two sets of radio buttons instead of one by including the fol ...

Creating Interactive Lookup Field with JQuery and PHP

Recently, I followed a guide on how to develop a lookup field that dynamically searches a MySQL database table - the main objective is to facilitate contact search by postcode. While I managed to get the search functionality working and display the value o ...

Why isn't my textarea in jQUERY updating as I type?

On my website, I have a comment script that is not functioning correctly in some parts of the jQuery/JavaScript code. Instead of posting an edited comment to PHP, I created a notification window to test if the value passed through is actually changing. W ...

Script for tracking user activity on Facebook and Google platforms

I currently have Google tracking conversion set up, but now I also need to implement Facebook pixel tracking. My existing Google Head Script code is as follows: <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||fu ...

The drag functionality can only be used once when applied to two separate div elements

Recently, I came across an issue where I have both an Image and a custom text element placed between them using an input box. My goal is to make both the text and the image draggable on the page. However, I noticed that while the image can be dragged and d ...

Trouble with activating dropdown toggle feature in Bootstrap 5

I recently upgraded to Bootstrap 5 and now my code is not functioning properly. <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria- controls="navbarCollaps ...

Unexpected error encountered with node.js when attempting to run: npm run dev. A TypeError was thrown stating that require(...) is not

Working on my initial project, I have set up a database and am in the process of creating a login page. However, when trying to run it using 'npm run dev', an error is encountered (see below). I am unsure of what is causing this issue and how to ...

Unable to forward with POST request in Node.js

I have a button on the front end that allows users to update their profile photo using the Cloudinary API. When the button is clicked, a Node.js POST request is sent with the user's data to query the database and update the profile photo URL. The func ...

The Google calendar is displaying an invalid JSON file

We're in the process of developing a website using AngularJS and we need to integrate Google Calendar events. I've attempted to retrieve the data from a Google Calendar. You can locate the JSON file here: http://www.google.com/calendar/feeds/[em ...

What is the maximum size allowed for creating a Set in JavaScript?

I am currently developing a tool to remove geometry from a 3D model within a web browser. During a specific stage of the removal process, I take an array containing indexes and convert it into a Set to eliminate any duplicate indexes. function TransformAr ...

Unable to see the array values in jquery autocomplete

Hey there, I'm currently using jQuery autocomplete with CodeIgniter. My result array is fetched from the database and I am sending it back as JSON-encoded data. However, I am facing an issue where the values in the search results are not being display ...

Is it possible to encode JavaScript with masked binary values?

This segment of code produces the output D. The real question is - HOW? alert([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![] ...

Unable to display 3D model using three.js THREE.FBXLoader

Having trouble integrating a THREE.FBXLoader 3D model into my three js project, getting an error message THREE.FBXLoader: External library Inflate.min.js required, obtain or import from https://github.com/imaya/zlib.js Check out the screenshot for more in ...

Why are new lines being added to my package.json file, and what is their purpose?

I am the maintainer of an npm package and I've noticed that there are entries being added to package.json with underscore characters. These entries include information like the package's raw URL, specifications, and locations. "_args": [ [ ...

Triggering blur event manually in Ionic 3

Is there a way to manually trigger the blur event on an ion-input element? The ideal scenario would be with an ionic-native method, but any javascript-based workaround will suffice. My current configuration: Ionic: ionic (Ionic CLI) : 4.0.1 (/User ...

What is the most effective way to retrieve the default value of ng model?

When working with php and angular, I am trying to set a value in ng model from a php expression. However, when I try to read the ng model value from the controller, it is showing up as null. <input ng-model="id" ng-init="id= '<?php echo $userID ...

Converting a blob to base64 and then back to a blob in Node.js may result in varying sizes between the two

I am currently implementing this code in a Node.js application. I have a blob that I am converting to a base64 string and then back to a blob using the following method: // Converting Blob to base64 string via Buffer const buffer = Buffer.from(await myBlob ...