The functionality of getUserMedia on iOS13 is experiencing issues specifically on Chrome and Edge browsers

My friend and I are currently working on an app that requires camera access. However, we have encountered some issues with getting the camera to work on iOS (specifically iOS 13).

After testing, we found that Safari freezes right after obtaining the camera content, while Chrome and Edge do not acquire camera access at all. Here is a snippet of our code:

let windowWidth = window.innerWidth;
let windowHeight = window.innerHeight;

function isMobile() {
    const isAndroid = /Android/i.test(navigator.userAgent);
    const isiOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
    return isAndroid || isiOS;
}

async function setupCamera() {
    video = document.getElementById('video');
    console.log("a");

    video.setAttribute('autoplay', '');
    video.setAttribute('muted', '');
    video.setAttribute('playsinline', '');

    const stream = await navigator.mediaDevices.getUserMedia({
        'audio': false,
        'video': {
            facingMode: 'user',
            width: mobile ? undefined : windowWidth,
            height: mobile ? undefined : windowHeight
        },
    });
    console.log("b");
    video.srcObject = stream;

    return new Promise((resolve) => {
        video.onloadedmetadata = () => {
            resolve(video);
        };
    });
}

Despite 'a' always being printed in the console, 'b' never appears. Any insights or suggestions on what might be causing this issue would be greatly appreciated!

Answer №1

Latest Update - 19/11/2020

Exciting news for iOS 14.3 beta 1 users: WKWebView now supports getUserMedia!

Browser Compatibility Information

After years of monitoring this issue through various channels (such as NotReadableError: Could not start source), it is important to note that access to getUserMedia is currently only available in Safari standalone view or the iOS Safari app.

Please be aware that browsers other than Safari on iOS do not have support for getUserMedia due to their use of WKWebView technology.

A bug report has been submitted regarding this limitation with WKWebView. Unfortunately, there is no timeline for resolution yet. View the bug ticket here

Updates have shown progress towards gaining getUserMedia access in standalone mode with iOS 13.4 Read more about it here

Safari Performance Tip

If your browser is freezing when attempting to capture video using constraints like window width and height, consider using standard camera resolutions such as 640x480 or 1280x720. The use of atypical resolutions may cause issues like frozen or distorted camera feed according to WebRTC specifications.

For capturing front camera feeds in fullscreen mode, refer to this guide: Learn how to implement getUserMedia Full Screen feature here

In some cases, async/await methods might encounter challenges. Below is a sample code snippet that should work fine, but keep in mind that security permissions may impact its functionality on certain platforms (e.g. Stack Overflow). Feel free to reach out if you need further assistance.

function isMobile() {
  const isAndroid = /Android/i.test(navigator.userAgent);
  const isiOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
  return isAndroid || isiOS;
}

async function setupCamera() {
  const isPortrait = true; // Add your logic here

  let video = document.getElementById('video');

  console.log("Getting video");

  video.setAttribute('autoplay', '');
  video.setAttribute('muted', '');
  video.setAttribute('playsinline', '');

  console.log("Calling getUserMedia");

  return new Promise((resolve) => {
    (async() => {
      await navigator.mediaDevices.getUserMedia({
          'audio': false,
          'video': {
            facingMode: 'user',
            width: isPortrait ? 480 : 640,
            height: isPortrait ? 640 : 480,
          },
        })
        .then((stream) => {
          console.log("Got getUserMedia stream");
          video.srcObject = stream;
          video.play();
          resolve(true);
        })
        .catch((err) => {
          console.log("Encountered getUserMedia error", err);
          resolve(false);
        });
    })();
  });

}

(async() => {
  const ret = await setupCamera();
  console.log(`Initialised camera: ${ret}`)
})();
html,
body {
  height: 100%;
  margin: 0;
}

div {
  position: relative;
  min-height: 100%;
  min-width: 100%;
  overflow: hidden;
  object-fit: cover;
}

video {
  width: 480px;
  height: 640px;
  background-color: black;
}
<div><video id="video"></video></div>

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

sketch a portion of a picture on a canvas

My challenge involves a canvas with dimensions of 400 by 400, and an image sized at 3392 by 232. I am looking to crop the first 400 pixels of this image and display them within the canvas. How can I achieve this task? $(document).ready(function () { v ...

Exploring the vertices of a single face of a cube using three.js

My current project involves manipulating the x position of all coordinates on a single face of a cube. Here is my current method: var wDepth = 200; var hDepth = 200; var geo = new THREE.CubeGeometry( 20, 40, 40, 20, wDepth, hDepth); for ( var i = ...

Unlocking the key to retrieving request headers in the express.static method

Utilizing express.static middleware allows me to avoid manually listing each asset in the routes. All my routing is managed through index.html due to my use of Vue JS. However, a feature necessitates me to extract specific information from the request hea ...

Does vite handle module imports differently during development versus production?

I am currently working on incorporating the jointjs library into a Vue application. It is being declared as a global property in Vue and then modified accordingly. Below is a basic example of what I am trying to achieve: import Vue from 'vue'; im ...

Avoiding memory leaks in Reactjs when canceling a subscription in an async promise

My React component features an async request that dispatches an action to the Redux store from within the useEffect hook: const fetchData = async () => { setIsLoading(true); try { await dispatch(dataActions.fetchData(use ...

Do you know the term for when JavaScript is utilized to display specific sections of a png image?

Imagine you have an image file in the format of a PNG which includes various icons intended for use on a website. How can JavaScript be utilized to choose and showcase a specific icon from that image? It's a technique I've observed in practice, b ...

Issue with web form layout and heading malfunction

I'm experimenting with creating a form and dynamically setting the pattern and title fields using JavaScript. I am facing an issue with the current code as it is preventing me from entering anything into the form field, and displaying an error message ...

How to Use Discord.js v13 to Make an Announcement in a Specific Channel

Looking for a Solution I am trying to create a command that allows an admin user to send a specific message to a designated channel. The Issue at Hand My current approach involves sending a response back to the user who triggered the command with the ent ...

Tips on how to dynamically allocate an id value to a jQuery function that retrieves the backgroundImage URL

I have a div with a background image and I am using a jQuery function to retrieve the URL of the background image. var name=image; var url=$("#"+name+"").css("background-image"); console.log(url); <script src="https://cdnjs.cloudflare.com/aj ...

Utilizing onmouseover and onmouseoff events with images to dynamically alter text content

I have 6 images and I want to dynamically change the text next to them based on which image is being hovered over with the mouse. Even though I attempted to achieve this using JavaScript with the onmouseover and onmouseout events, my code doesn't see ...

My bootstrap collapse navbar isn't functioning properly. Despite pressing the icon on a smaller screen, the menu fails to open. Can anyone provide a solution to this issue?

The hamburger menu is not working properly. I am facing an issue where the navigation does not appear when I press on the hamburger icon on a small screen. Can someone please guide me on how to resolve this problem? :/ <nav class="navbar bg-d ...

Displaying queries using ajax in Rails

Can someone assist me in dealing with a particular issue? I am using ajax to refresh queries from the database dynamically each time there is a change in a search form. The main objective is to load N number of records based on the parameters selected in ...

Ways to soften a section of a canvas component?

What is the simplest way to apply a blur effect to a specific portion of my canvas element? I am utilizing the JavaScript 3D Library known as three.js. This library simplifies the use of WebGL. While they offer examples of blur and depth of field effects, ...

Lottie-web experiences a memory leak

Currently implementing lottie web on my front-end, but encountering persistent memory leaks. The JavaScript VM instance remains below 10MB when lottie is removed altogether. However, upon enabling lottie, the memory usage escalates rapidly whenever the pa ...

Going through each file individually and addressing any issues

I have a folder with hundreds of files that I need to read. Currently, my method reads all the files at once and returns the content as an array. However, I want to optimize this process by reading one file at a time and sending it to the client before mov ...

a reactjs beforeunload event listener was added but not properly removed

I am working on a React component that looks like this: import React, { PropTypes, Component } from 'react' class MyComponent extends Component { componentDidMount() { window.addEventListener("beforeunload", function (event) { ...

In what way can the MobileIron Docs@Work app be initiated from a different iOS application?

Can anyone help me find the correct URL name for MobileIron Docsb@Work so I can launch it from another app? Usually, you can simply type "appname://" to initiate the application ...

The file that is currently being downloaded has the .pptx extension, but it is being

Take a look at this code snippet: const generateDownload = ({ link, data, title, settings })=> { const newLink = document.createElement('a'); const blobUrl = link || URL.createObjectURL(new Blob([data], settings)); newLink.setAt ...

find all occurrences except for the last of a pattern in javascript

When considering the patterns below: "profile[foreclosure_defenses_attributes][0][some_text]" "something[something_else_attributes][0][hello_attributes][0][other_stuff]" It is possible to extract the last part by utilizing non-capturing groups: var rege ...

Test fails in Jest - component creation test result is undefined

I am currently working on writing a Jest test to verify the creation of a component in Angular. However, when I execute the test, it returns undefined with the following message: OrderDetailsDeliveryTabComponent › should create expect(received).toBeTru ...