@@ -24,6 +24,46 @@ class Camera {
2424  } 
2525} 
2626
27+ const  narrowDownFacingMode  =  async  camera  =>  { 
28+   // Modern phones often have multipe front/rear cameras. 
29+   // Sometimes special purpose cameras like the wide-angle camera are picked 
30+   // by default. Those are not optimal for scanning QR codes but standard 
31+   // media constraints don't allow us to specify which camera we want exactly. 
32+   // However, explicitly picking the first entry in the list of all videoinput 
33+   // devices for as the default front camera and the last entry as the default 
34+   // rear camera seems to be a workaround. 
35+   const  devices  =  ( await  navigator . mediaDevices . enumerateDevices ( ) ) . filter ( 
36+     ( {  kind } )  =>  kind  ===  "videoinput" 
37+   ) ; 
38+ 
39+   if  ( devices . length  >  2 )  { 
40+     const  frontCamera  =  devices [ 0 ] ; 
41+     const  rearCamera  =  devices [ devices . length  -  1 ] ; 
42+ 
43+     switch  ( camera )  { 
44+       case  "auto" :
45+         return  {  deviceId : {  exact : rearCamera . deviceId  }  } ; 
46+       case  "rear" :
47+         return  {  deviceId : {  exact : rearCamera . deviceId  }  } ; 
48+       case  "front" :
49+         return  {  deviceId : {  exact : frontCamera . deviceId  }  } ; 
50+       default :
51+         return  undefined ; 
52+     } 
53+   }  else  { 
54+     switch  ( camera )  { 
55+       case  "auto" :
56+         return  {  facingMode : {  ideal : "environment"  }  } ; 
57+       case  "rear" :
58+         return  {  facingMode : {  exact : "environment"  }  } ; 
59+       case  "front" :
60+         return  {  facingMode : {  exact : "user"  }  } ; 
61+       default :
62+         return  undefined ; 
63+     } 
64+   } 
65+ } ; 
66+ 
2767const  INSECURE_CONTEXT  =  window . isSecureContext  !==  true ; 
2868
2969const  STREAM_API_NOT_SUPPORTED  =  ! ( 
@@ -34,13 +74,13 @@ const STREAM_API_NOT_SUPPORTED = !(
3474
3575let  streamApiShimApplied  =  false ; 
3676
37- export  default  async  function ( constraints ,   videoEl ,   advancedConstraints )  { 
77+ export  default  async  function ( videoEl ,   {  camera ,  torch  } )  { 
3878  // At least in Chrome `navigator.mediaDevices` is undefined when the page is 
3979  // loaded using HTTP rather than HTTPS. Thus `STREAM_API_NOT_SUPPORTED` is 
4080  // initialized with `false` although the API might actually be supported. 
41-   // So although `getUserMedia` already should have a build -in mechanism to 
81+   // So although `getUserMedia` already should have a built -in mechanism to 
4282  // detect insecure context (by throwing `NotAllowedError`), we have to do a 
43-   // manual check before even calling `getUserMedia`. 
83+   // manual check before even calling `getUserMedia`. 
4484  if  ( INSECURE_CONTEXT )  { 
4585    throw  new  InsecureContextError ( ) ; 
4686  } 
@@ -49,11 +89,22 @@ export default async function(constraints, videoEl, advancedConstraints) {
4989    throw  new  StreamApiNotSupportedError ( ) ; 
5090  } 
5191
92+   // This is a brower API only shim. It patches the global window object which 
93+   // is not available during SSR. So we lazily apply this shim at runtime. 
5294  if  ( streamApiShimApplied  ===  false )  { 
5395    adapterFactory ( {  window } ) ; 
5496    streamApiShimApplied  =  true ; 
5597  } 
5698
99+   const  constraints  =  { 
100+     audio : false , 
101+     video : { 
102+       width : {  min : 360 ,  ideal : 640 ,  max : 1920  } , 
103+       height : {  min : 240 ,  ideal : 480 ,  max : 1080  } , 
104+       ...( await  narrowDownFacingMode ( camera ) ) 
105+     } 
106+   } ; 
107+ 
57108  const  stream  =  await  navigator . mediaDevices . getUserMedia ( constraints ) ; 
58109
59110  if  ( videoEl . srcObject  !==  undefined )  { 
@@ -70,7 +121,7 @@ export default async function(constraints, videoEl, advancedConstraints) {
70121
71122  await  eventOn ( videoEl ,  "loadeddata" ) ; 
72123
73-   if  ( advancedConstraints . torch )  { 
124+   if  ( torch )  { 
74125    const  [ track ]  =  stream . getVideoTracks ( ) ; 
75126
76127    try  { 
0 commit comments