3
votes

I want to use the microphone to record voice from salesperson, on development environment such us localhost:9090/#/chatroom navigator.mediaDevices works fine. But on production's environment, navigator doesn't has the mediaDevices object, it is undefined.Could any one tell me why?

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36

let stream = null;
const constraints = {
  audio: true,
};

try {
  stream = await navigator.mediaDevices.getUserMedia(constraints);
  /* use the stream */
  this.beginRecord(stream);
  this.recorder.mediaStream = stream;
} catch (err) {
  /* handle the error */
  // console.error(err);
}

navigator.mediadevices.getusermedia is not a function

4
Are you sure you're testing on the same browser for both situtations? check here for compatibilityRenan Souza
your try /catch are inside an async function right ?Abdelillah Aissani
@RenanSouza Absolutely same browser.The compatibility list cannot help me.My Chrome version 75.0.3770.90 is much bigger then the full-support smallest number 47.Maybe the doc needs some update.frankkai
@Dadboz Yes, this style works fine.frankkai

4 Answers

6
votes

You must use HTTPS. localhost is an exception to this requirement.

Note the SecureContext attribute on the interface at https://w3c.github.io/mediacapture-main/#navigator-interface-extensions.

See: Can't find serviceWorker in navigator anymore.

1
votes

TLDR: Use ngrok to create an https tunnel to your machine.

--

As some have noted, the browser only allows https connections to access the mediaDevices API, one exception to this is the http://localhost or http://127.0.0.1

When developing, you want to test in other devices the code that is running in your development machine, and this can be really annoying, to solve this you can use ngrok to create a secure https tunnel to your application!

Download ngrok, unzip the binary, and then follow these two steps:

# Authenticate with ngrok (you only need to do this once per machine)
./ngrok authtoken

# Start a tunnel to your local machine
# (replace "8000" with the port number of your local development web server)
./ngrok http 8000

You will see something like this:

ngrok by @inconshreveable

Session Status                online
Account                       Your Account Name (Plan: Free)
Update                        update available (version 2.3.35, Ctrl-U to update)
Version                       2.2.8
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://somerandomstuff.ngrok.io -> localhost:8000
Forwarding                    https://somerandomstuff.ngrok.io -> localhost:8000

Then, just access the url on the Forwarding field on any other device and thats it!

For the example above, it would be this one: https://somerandomstuff.ngrok.io

--

Credits: Got the idea from this post:

https://www.daily.co/blog/setting-up-a-local-webrtc-development-environment

0
votes

I have this challenges but everything works fine when I access my site via https

http://example.com - console.log(navigator.mediaDevices) returns undefined

while

https://example.com - console.log(navigator.mediaDevices) returns a valid object

0
votes

I found this official post, it kills what i am confused.

If you are a developer that needs to keep testing a site using a Powerful Feature but you only have a non-secure test server, you have several options:

Secure the server with a publicly-trusted certificate. If the server is reachable from the Internet, several public CAs offer free, automatically-renewed server certificates.

http://localhost is treated as a secure origin, so if you're able to run your server from localhost, you should be able to test the feature on that server.

You can run chrome with the --unsafely-treat-insecure-origin-as-secure="http://example.com" flag (replacing "example.com" with the origin you actually want to test), which will treat that origin as secure for this session. Note that on Android and ChromeOS this requires having a device with root access/dev mode. (This flag is broken in Chrome 63 but fixed in Chrome 64 and later. Prior to Chrome 62, you must also include the --user-data-dir=/test/only/profile/dir to create a fresh testing profile for the flag to work.)

Create a self-signed certificate for temporary testing. Direct use of such a certificate requires clicking through an invalid certificate interstitial, which is otherwise not recommended. Note that because of this interstitial click-through (which also prevents HTTPS-response caching), we recommend options (1) and (2) instead, but they are difficult to do on mobile. See this post on setting up a self-signed certificate for a server for more information on how to do this.

An alternative approach is to generate a self-signed root certificate which you place into the trust store of the developer PC/devices, and then issue one or more certificates for the test servers. Trusting the root certificate means that Chrome will treat the site as secure and load it without interstitials or impacting caching. One easy way of setting up and using a custom root certificate is to use the open source mkcert tool.

On a local network, you can test on your Android device using port forwarding to access a remote host as localhost.

https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins