mebjas / html5-qrcode

A cross platform HTML5 QR code reader. See end to end implementation at: https://scanapp.org
https://qrcode.minhazav.dev
Apache License 2.0
5.1k stars 981 forks source link

[Feature Request] facingMode constraint is essential for this library to work #65

Open dennmtr opened 4 years ago

dennmtr commented 4 years ago

Very nice and clean module but... is useless without facingMode constraint, device label can be in any language making the camera choice impossible

Example:

{id: "AFB981283186FBA62F2947AA63940A4482BF80C3", label: "Πίσω κάμερα"}

Alternative, selecting between 4 options (devices), where only one option is essential its not the best user experience

mebjas commented 4 years ago

@dennmtr That makes sense, the reason that it's not so is I don't know how to get exactly the front and back camera in single query, or how to determine that from the list that we retrieve from APIs. I'll look further into this.

dennmtr commented 4 years ago

Thanks @mebjas, great work

mebjas commented 4 years ago

I can possibly exposure arguments to getCameras so you can request camera of choice and build your user interface on top of it.

You can call it like

Html5Qrcode.getCameras({ facingMode: "user" })
  .then(devices => {
    // handle the returned devices
});

or

Html5Qrcode.getCameras({ facingMode: { exact: "environment" } })
  .then(devices => {
    // handle the returned devices
});

Similar to video part of web api syntax - https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

@dennmtr WDYT?

mebjas commented 4 years ago

@dennmtr Any updates?

dennmtr commented 4 years ago

@mebjas Sooner or later... I am not dealing with this project at the moment but that seems to work!

nivthetool commented 4 years ago

strongly agree. any progress.

pradeepngupta commented 4 years ago

This feature is strongly needed. Any dates you are planning for V1.3.0?

mebjas commented 4 years ago

@pradeepngupta @nivthetool @dennmtr @max2ti @peterA1

I had a few questions to understand this better. The original feature request was raised to add the support for Html5Qrcode class. And as I suggested in the comment adding a config in getCameras makes sense.

However, I don't have concrete thoughts on adding this to Html5QrcodeScanner. My questions are

mebjas commented 4 years ago

Update

On further digging I realised that the navigator.mediaDevices.enumerateDevices() doesn't support constraints. So the support shall be added to Html5Qrcode#start() method. Earlier it could be called only with exact cameraId

Now you can call it in following ways

const html5QrCode = new Html5Qrcode("#reader");
const qrCodeSuccessCallback = message => { /* handle success */ }
const config = { fps: 10, qrbox: 250 };

// Current approach
Html5Qrcode.getCameras().then(cameras => {
  // assuming at least one camera exists 
  html5QrCode.start(cameras[0].deviceId, config, qrCodeSuccessCallback);
});

// .... new alternatives for mobile devices

// If you want to prefer front camera
html5QrCode.start({ facingMode: "user" }, config, qrCodeSuccessCallback);

// If you want to prefer back camera
html5QrCode.start({ facingMode: "environment" }, config, qrCodeSuccessCallback);

// front camera or fail
html5QrCode.start({ facingMode: { exact: "user"} }, config, qrCodeSuccessCallback);

// back camera or fail
html5QrCode.start({ facingMode: { exact: "environment"} }, config, qrCodeSuccessCallback);
pradeepngupta commented 4 years ago

@mebjas That's very quick. Thanks for your commit and plan. Let me take the latest library js and test it out as per your explanation.

mebjas commented 4 years ago

Updated the support in Html5Qrcode#start()

max2ti commented 4 years ago

Thanks for your work @mebjas I have a question about the new update. Is it required to call Html5Qrcode#getCameras() (even if I don't use the output) before Html5Qrcode#start()? I've done a quick test and without Html5Qrcode#getCameras() the video does not appear (but the camera led turns on), no errors in the console.

mebjas commented 4 years ago

@max2ti -

Ideally no, getCameras() is only required to get exact camera ids - so you can use it if you want users to provide users an option to change camera. Otherwise you can use the

html5QrCode.start({ facingMode: "user" }, config, qrCodeSuccessCallback);

Approach to prefer front camera for example, else choose any camera.

I've done a quick test and without Html5Qrcode#getCameras() the video does not appear (but the camera led turns on), no errors in the console.

If this is happening, it's a bug - let me try to repro and fix if this is happening, just FMI - which browser / OS?

max2ti commented 4 years ago

Windows 10 on chrome

mebjas commented 4 years ago

@max2ti I was not able to reproduce this issue - I have published an example at https://blog.minhazav.dev/research/h5q-direct

This example doesn't use getCameras() api, Can you see if this works for you.

Windows 10 on chrome

I was able to test on Chrome/Mac and Chrome/Android. I don't have a windows system at the moment to validate - however, this seems like something that shouldn't be OS dependent but html5 api dependent.

mebjas commented 4 years ago

@max2ti

I just verified it to work for Windows/Chrome

max2ti commented 4 years ago

@mebjas

I've done some more tests and found that the problem appears only if the div used by html5qrcode is managed by Vue.js. I've swapped the call to Html5Qrcode#getCameras() with a call to a generic awaitable (an async/await wrapper of setTimeout) and it worked, so it's not what Html5Qrcode#getCameras() does, any "time waster" works.

There's probably nothing wrong with html5-qrcode, I must be doing something wrong with Vue (I'm integrating html5-qrcode in a big pre-existing vue app).

EDIT: I was calling Html5Qrcode#getCameras() before the component was fully mounted, moved it to the mounted event, now it works as expected. Sorry for having wasted some of your time.

mebjas commented 4 years ago

I see, thanks for update.

There seems to be many folks who would like to use this feature - that too with Html5QrcodeScanner class. Please use this issue to add your requirements.

TecoHub commented 2 years ago

using Html5QrcodeScanner class and I would like to be able to use facing mode back camera by default. any solution guys? thanks