-1

I want to get the last deviceId.

Please try the following code on a smartphone. https://www.ofima.ch/file1.html

Inside the function "getConnectedDevices" the variable deviceId ok. But outside is returned a promise and not the variable deviceId. How can I get the variable deviceId ?

Thanks Miche

mrezzonico
  • 21
  • 3

1 Answers1

0

Explanation:

You need to wrap your alert in an async function and use await. Also to take the value from the promise you needed .then(). Hope the below helps.

Original code:

   async function getConnectedDevices() {
  var index;
  const devices = await navigator.mediaDevices.enumerateDevices();

  for (var i=0; i<devices.length; i++) {
     if (devices[i].kind == "videoinput") {
        index = i;
     }
  }

  var deviceId = devices[index].deviceId;
  alert('deviceId is ok: ' + deviceId);
   
  return (deviceId);
   }

   const deviceId = getConnectedDevices();

   alert('deviceId is not defined, why ?: ' + deviceId);

New code:

async function getConnectedDevices() {
  let index;
  const devices = await navigator.mediaDevices.enumerateDevices();

  for (let i=0; i < devices.length; i++) {
    console.debug(devices[i]);
    if (devices[i].kind == "videoinput") {
      index = i;
    }
  }

  console.log('deviceId is ok: ',  devices[index]);
  return devices[index].deviceId;
}


(async() => {
  const deviceId = await getConnectedDevices().then();
  alert(`deviceId: ${deviceId}`);
})();

And a quick hack for storing the deviceId in the window

console.log('globalDeviceId should be undefined', window.globalDeviceObj);

async function getConnectedDevices() {
  let index;
  const devices = await navigator.mediaDevices.enumerateDevices();

  for (let i = 0; i < devices.length; i++) {
    console.debug(devices[i]);
    if (devices[i].kind == "videoinput") {
      index = i;
    }
  }

  console.log('deviceId is ok', devices[index]);
  return devices[index];
}


function getDeviceId() {
  (async() => {
    window.globalDeviceObj = await getConnectedDevices().then();
    console.log(`globalDeviceId set: ${JSON.stringify(window.globalDeviceObj)}`);
  })();
}

function tick() {
  if(typeof window.globalDeviceObj === 'undefined'){
    requestAnimationFrame(tick);
  }else {
    alert(`globalDeviceId get: ${JSON.stringify(window.globalDeviceObj)}, with deviceId: ${(window.globalDeviceObj.deviceId)}`)
  }
}

function init() {
  tick();
  getDeviceId();
}

init();
Marcus
  • 1,880
  • 20
  • 27
  • Hi Marcus, thanks a lot for your help. What I am doing is a mobile web application. My problem is to have a global variable with the deviceId of the camera. If I understand correctly the variable deviceId is accessible only "inside" the "async()" function. But how to access the variable after the "async()" function ? The only solution that I have found is to save the value with "localStorage.setItem" and then read the value with "localstorage.getItem". Regards Miche – mrezzonico Jul 01 '20 at 07:50
  • Understood, I have a few Web AR apps on the market which are mobile first. The way I tackled this was using redux in react (fire actions to change views on deviceId) or subscribe to an observable Rxjs (in a service) in angular and managing the app flow with the global state. I.e. Do not progress to view y until deviceId is in state, go back to view x and get deviceId. Are you using a framework? I could potentially knock up a demo next week which shows how to do this. – Marcus Jul 01 '20 at 09:43
  • As a quick hack In the (async() => { window.deviceId = await getConnectedDevices().then(); ... })(); You should be able to see it globally without using localstorage. Its a hack but was quite common back in the day to store global vars here. However to read this value you will need to some requestAnimFrame loop which checks this value, it will be undefined and post the async call defined. Once this value is defined you can continue with your app flow. – Marcus Jul 01 '20 at 09:46