Is AngularJS Experiencing Bugs with the Webcam getUserMedia API?

I recently created a webcam directive in AngularJS that utilizes a service. For reference, I followed this example:

Surprisingly, the example works perfectly on my tablet, but when I integrate the code into my tablet's Google Chrome browser, it encounters a few bugs.

Bug #1: The rear camera fails to function.

Bug #2: Upon starting the camera directive, only the first frame of the stream is displayed and then it freezes. Strangely, switching to the non-functional rear camera and back causes the stream to appear.

Could someone point out where I might be going wrong? I've attempted several solutions without success.

This is the code for the webcam directive:

link: function postLink($scope, element) {

    var videoSources = [];

    MediaStreamTrack.getSources(function(mediaSources) {

      for (var i = 0; i < mediaSources.length; i++)
      {
        if (mediaSources[i].kind == 'video')
        {
          videoSources.push(mediaSources[i].id);
        }
      }

      if (videoSources.length > 1){ $scope.$emit('multipleVideoSources'); }

      initCamera(0);

    });

    // Elements
    var videoElement = element.find('video')[0];

    // Stream
    function streaming(stream) {
      $scope.$apply(function(){
        videoElement.src = stream;
        videoElement.play();
      });
    }

    // Check ready state
    function checkReadyState(){
      if (videoElement.readyState == 4)
      {
        $interval.cancel(interval);
        $scope.$emit('videoStreaming');
      }
    }
    var interval = $interval(checkReadyState, 1000);

    // Init
    $scope.$on('init', function(event, stream){
      streaming(stream);
    });

    // Switch camera
    $scope.$on('switchCamera', function(event, cameraIndex){
      initCamera(cameraIndex);
    });

    // Init via Service
    function initCamera(cameraIndex)
    {
      var constraints = {
        audio: false,
        video: {
          optional: [{ sourceId: videoSources[cameraIndex] }]
        }
      };

      camera.setup(constraints, camera.onSuccess, camera.onError);
    }

  }

Here is the code for the Camera service:

.service('camera', function($rootScope) {

    // Setup of stream
    this.init = false;

    this.onError = function(error){
        console.log(error);
        alert('Camera error');
    };

    this.onSuccess = function(stream){
        window.stream = stream;
        stream = window.URL.createObjectURL(stream);

        $rootScope.$broadcast('init', stream); 
    };

    this.setup = function(constraint){
        navigator.getMedia(constraint, this.onSuccess, this.onError);
        this.init = true;
    };

It works flawlessly on my laptop, though testing with multiple video sources is not possible due to having just one.

Answer №1

Issue #2 has been resolved by delaying the execution of videoStream.play() until it reaches a readyState of 4.

Problem #1 fixed by relocating window into the directive and discontinuing the use of the service. The following code is now called within the initCamera function:

if (!!window.stream) {
   videoElement.src = null;
   window.stream.stop();
}

Answer №2

To address Bug #1, simply utilize the back camera by specifying it within a constraint object when invoking getUserMedia

navigator.mediaDevices.getUserMedia({ 
    audio: true, 
    video: { 
        facingMode: { exact: "environment" }
    }
})

More information can be found here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

Look for "rear camera"

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

tips for setting the value of a checkbox to true in React Material-UI with the help of React Hooks

<FormControlLabel onChange={handleCurrentProjectChange} value="end" control={<Checkbox style={{ color: "#C8102E" }} />} label={ <Typography style={{ fontSize: 15 }}> C ...

Remove the dropdown menu in real time, ensuring that only the most recent one is

Although the example may seem unusual, I am deliberately recreating a real problem to find a solution. When I click on a button, it generates 3 dynamic dropdowns based on a list of animals. My issue is that I want to delete a selected item, but it always ...

The "405 method not supported" exception pops up exclusively for Angular/HTML/JSP resources within a Spring Boot application

My Spring Boot and AngularJS application is encountering an issue when trying to access a REST service with a POST method. Interestingly, I am able to successfully hit the service wherever POST is configured for request mapping. However, when attempting t ...

The Ajax/jQuery output is not showing up in the iframe, but is instead appearing on a separate page

I've scoured various forums and websites, attempting to troubleshoot the issue described below without success. This problem persists in both IE 11 and Firefox 10.0.2. My goal is to submit a form (POST) to a website () and showcase the resulting bri ...

I've declared the Android permission, but it still doesn't seem to be functioning correctly

Having an issue trying to implement code for sending SMS from an Android app. However, whenever attempting to send the SMS, I encounter the following error: 09-17 18:37:29.974 12847-12847/**.**.****E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: **.** ...

Browserify - combine external modules into a single bundle

I am a complete beginner in the world of browserify. I recently discovered this interesting module called peer-file, which allows for file transfer between two browsers. After reading the Usage section in its readme, I realized I needed to include the scri ...

There was an issue with the Google Maps embed API that resulted in an error with interpolation

My goal is to utilize the Google Maps API in order to showcase a map using data from a JSON file. However, whenever I attempt to incorporate the JSON data, an error message 'Error: [$interpolate:noconcat] Error while interpolating' pops up. < ...

JS Function created to supply elements to React component is failing to return correctly

Trying to validate a dataset by checking for specific prefixes or suffixes in a string, and then breaking the string into <span> elements. The current function correctly identifies the relevant morphemes in the data set, but fails to return the split ...

What are the steps for building an AngularJS application where all views are consolidated in a single file?

Is there a way to create an AngularJS app that is self-contained in one file, similar to jQuery Mobile's multi-page template? I'm looking to define multiple divs with ng-controller for different controllers and templates. However, angular-ui-rout ...

Discovering ways to fetch an array of objects using object and arrays in JavaScript

When comparing an array of objects with a single object and listing the arrays in JavaScript, specific conditions need to be met to retrieve the array of objects: If the itemvalue and idvalue are the same, check if the arrobj cid has the same codevalue ...

Conducting an AngularJS AJAX call within a Symfony2 environment and utilizing Doctrine to generate a JSON

Currently, I am working on a project involving Symfony2, Doctrine, and AngularJS. While Symfony2 and Doctrine are not causing any issues, I am facing difficulties when using an ajax request with AngularJS. The problem lies in either the data not loading pr ...

Grunt is designed to generate a single file, instead of producing multiple files

I have a simple Gruntfile that is designed to read a plain text file line by line and create an html file of the same name for each line. However, it seems to only work with one line in the file at a time, not multiple lines. Here is the console output wh ...

Utilizing NodeSize to Optimize the Spacing Among Nodes in the D3 Tree Arr

Currently, I am trying to adjust the positioning of my rectangle nodes because they are overlapping, as illustrated in the image below: In my research, I discovered that D3 provides a nodeSize and separation method. However, I encountered difficulties imp ...

Why can't I capture the text within this particular div using .text?

Trying to extract specific text from a website in Chrome's developer console. For example, here is the code snippet: <div class="someClass">This is some text!</div> Expected it to work with this command, but it returns 'undefined&a ...

creating folding effect using javascript and css with divs

I've been searching high and low on the internet for a solution like this, but so far I haven't had any luck. It seems like there might be a JavaScript script out there that dynamically changes the css -webkit-transform: rotateY(deg) property. ...

Clarifying the confusion surrounding AngularJS $q, promises, and assignments

Curious about a particular behavior I'm witnessing. Unsure if there's a misunderstanding on my part regarding promises, JavaScript, or Angular. Here's what's happening (I've prepared a plnkr to demonstrate - http://plnkr.co/edit/ZK ...

What purpose does generating a JSON file serve when invoking getStaticProps in Next.js?

Just diving into the world of Next.js. I've been going through the Next.js documentation and stumbled upon this: Next.js creates a JSON file that contains the outcome of executing getStaticProps. This JSON file is used in client-side routing via nex ...

RequireJS - Enabling the loading of multiple module instances

I am working on a custom RequireJS plugin that needs to create a new object instance every time it is called. For illustration purposes, consider the following: define("loader", { load: function(name, req, onload, config) { var instance = GlobalGet ...

Angular library for creating stacked bar and line charts

Is there a specific AngularJS library that is able to create a chart with stacked bars and lines, similar to the one shown here: https://i.sstatic.net/V0WtM.png I am in search of a library that can handle this requirement using Angular directives. I came ...

Updating information dynamically in a controller based on an ng-repeat from a different controller in AngularJS

To enhance comprehension, I've created a straightforward example. For this scenario, ng-repeat is used to call a template that has its own controller. However, the controller of the template requires injected data from a service for each ng-repeat it ...