0

The Problem

I have a simple app with an HTML page with embedded Js served by nodejs. I use it to test Media functionality on the browser (camera).

When I run the app on my local and browse the page on localhost:8000, I can see the camera starting on and the video stream added to the page.

When I host the same app hosted AWS (Windows 2019), I can browse the page and see the markup but have the following error, and therefore no video stream is added on the page.

The error I get is Uncaught TypeError: Cannot read properties of undefined (reading 'getUserMedia') pointing to navigator.mediaDevices.getUserMedia(constraints). I recently deployed a chat app I built on the server but can't get the video to start. I created this simple app to test and used js sample from mozzilla.

Below are the files for my app, haven't included the package.josn as it has 0 dependencies.

The App

HTML

<!DOCTYPE html>
<html>

<head>
    <title>Media Test</title>
</head>

<body>

    <h1>Media Test</h1>
    <p>Testing video and mic of browser.</p>
    <p id="errorMsg"></p>
    <video></video>
    <script>
        'use strict';

        // Put variables in global scope to make them available to the browser console.
        var video = document.querySelector('video');
        var constraints = window.constraints = {
            audio: false,
            video: true
        };
        var errorElement = document.querySelector('#errorMsg');

        navigator.mediaDevices.getUserMedia(constraints)
            .then(function (stream) {
                var videoTracks = stream.getVideoTracks();
                console.log('Got stream with constraints:', constraints);
                console.log('Using video device: ' + videoTracks[0].label);
                stream.onremovetrack = function () {
                    console.log('Stream ended');
                };
                window.stream = stream; // make variable available to browser console
                video.srcObject = stream;
                video.addEventListener('loadedmetadata', () => { video.play() })
            })
            .catch(function (error) {
                if (error.name === 'ConstraintNotSatisfiedError') {
                    errorMsg('The resolution ' + constraints.video.width.exact + 'x' +
                        constraints.video.height.exact + ' px is not supported by your device.');
                } else if (error.name === 'PermissionDeniedError') {
                    errorMsg('Permissions have not been granted to use your camera and ' +
                        'microphone, you need to allow the page access to your devices in ' +
                        'order for the demo to work.');
                }
                errorMsg('getUserMedia error: ' + error.name, error);
            });

        function errorMsg(msg, error) {
            errorElement.innerHTML += '<p>' + msg + '</p>';
            if (typeof error !== 'undefined') {
                console.error(error);
            }
        }
    </script>
</body>

</html>

Node Js

const express = require("express");
const app = express();
const http = require("http");
const server = http.createServer(app);

const PORT = 9000;

app.use(express.static("public"))

app.get("/", (req, res) => {
   res.sendFile(__dirname + "/media-test.html")
})

server.listen(PORT, () => {
   console.log("listening on *:", PORT)
})

I was initially thinking security groups and firewall rules (is a windows machine), but I have added inbound and outbound security rules and groups for TCP and UDP. Also, I can reach the app and the page is served.

Vergil C.
  • 1,046
  • 2
  • 15
  • 28

1 Answers1

0

I found out media devices on remote connections over HTTP are disabled, HTTPS is required.

navigator.mediaDevices is undefined

How to access Camera and Microphone in Chrome without HTTPS?

To test my remotely deployed code accessing it from my machine, I have temporarily added an exception on chrome allowing media devices over the insecure connection for the specific IP address and port. That solved my issue regarding testing the app. A long-term solution would be to install a certificate on my app and have it accessed securely over HTTPS.

Vergil C.
  • 1,046
  • 2
  • 15
  • 28
  • You can, at least for the purpose of demo and test, host your app at heroku or glitch. You'll use their certs, and deployment is quite easy. – O. Jones Jan 14 '22 at 20:44
  • Great idea! I have three apps running on Heroku and never thought of testing it there. Thanks for the advice. – Vergil C. Jan 15 '22 at 15:55