web-dev-qa-db-fra.com

Est-il possible de contrôler la lumière de la caméra sur un téléphone via un site Web?

Est-il possible de contrôler la lumière de la caméra sur un téléphone via un site Web? Dites à travers Chrome ou Firefox. Je sais que c'est possible en utilisant une Android ou une application iOS, qui contient les nombreuses applications de lampe de poche. Et je sais que l'on peut contrôler la caméras via la famille de fonctions getUserMedia. Sinon, quelqu'un sait-il quand il sera disponible?

21

Voici un petit "torch-app" pour un site web:

Edit 1: J'ai aussi fait un jsfiddle

//Test browser support
const SUPPORTS_MEDIA_DEVICES = 'mediaDevices' in navigator;

if (SUPPORTS_MEDIA_DEVICES) {
  //Get the environment camera (usually the second one)
  navigator.mediaDevices.enumerateDevices().then(devices => {
  
    const cameras = devices.filter((device) => device.kind === 'videoinput');

    if (cameras.length === 0) {
      throw 'No camera found on this device.';
    }
    const camera = cameras[cameras.length - 1];

    // Create stream and get video track
    navigator.mediaDevices.getUserMedia({
      video: {
        deviceId: camera.deviceId,
        facingMode: ['user', 'environment'],
        height: {ideal: 1080},
        width: {ideal: 1920}
      }
    }).then(stream => {
      const track = stream.getVideoTracks()[0];

      //Create image capture object and get camera capabilities
      const imageCapture = new ImageCapture(track)
      const photoCapabilities = imageCapture.getPhotoCapabilities().then(() => {

        //todo: check if camera has a torch

        //let there be light!
        const btn = document.querySelector('.switch');
        btn.addEventListener('click', function(){
          track.applyConstraints({
            advanced: [{torch: true}]
          });
        });
      });
    });
  });
  
  //The light will be on as long the track exists
  
  
}
<button class="switch">On / Off</button>

Le code est fortement inspiré par ceci référentiel , ce webseries et ce blog-post

Edit 2: Cela ne fonctionne que dans Chrome (et peut-être Opera). Il ne fonctionne pas dans Chrome sur iOS, car Chrome ne peut pas accéder à la caméra . Je ne peux pas le tester sur Android pour l'instant . J'ai créé un nouveau jsfiddle, avec une sortie. Si vous avez un téléphone Android et que cela ne fonctionne pas pour vous, il vous dira peut-être pourquoi: https: // jsfiddle. net/jpa1vwed /

N'hésitez pas à déboguer, commenter et modifier.

21
Daniel Budick

Vous pouvez utiliser MediaStream Image Capture API en créant un ImageCapture à partir d'un VideoStreamTrack et en définissant l'option "fillLightMode " à " flash " ou " torche ". Exemple:

<video autoplay="true"></video>
<img />
<button onclick="takePhoto()">Take Photo</button>
<script type="text/javascript">
    var imageCapture = null;
    var deviceConfig = {
        video: {
            width: 480,
            height: 640,
            facingMode: "environment", /* may not work, see https://bugs.chromium.org/p/chromium/issues/detail?id=290161 */
            deviceId: null
        }
    };

    var imageCaptureConfig = {
        fillLightMode: "torch", /* or "flash" */
        focusMode: "continuous"
    };

    // get the available video input devices and choose the one that represents the backside camera
    navigator.mediaDevices.enumerateDevices()
            /* replacement for not working "facingMode: 'environment'": use filter to get the backside camera with the flash light */
            .then(mediaDeviceInfos => mediaDeviceInfos.filter(mediaDeviceInfo => ((mediaDeviceInfo.kind === 'videoinput')/* && mediaDeviceInfo.label.includes("back")*/)))
            .then(mediaDeviceInfos => {
                console.log("mediaDeviceInfos[0].label: " + mediaDeviceInfos[0].label);

                // get the device ID of the backside camera and use it for media stream initialization
                deviceConfig.video.deviceId = mediaDeviceInfos[0].deviceId;
                navigator.mediaDevices.getUserMedia(deviceConfig)
                        .then(_gotMedia)
                        .catch(err => console.error('getUserMedia() failed: ', err));
            });

    function takePhoto () {
        imageCapture.takePhoto()
                .then(blob => {
                    console.log('Photo taken: ' + blob.type + ', ' + blob.size + 'B');

                    // get URL for blob data and use as source for the image element
                    const image = document.querySelector('img');
                    image.src = URL.createObjectURL(blob);
                })
                .catch(err => console.error('takePhoto() failed: ', err));
    }

    function _gotMedia (mediastream) {
        // use the media stream as source for the video element
        const video = document.querySelector('video');
        video.srcObject = mediastream;

        // create an ImageCapture from the first video track
        const track = mediastream.getVideoTracks()[0];
        imageCapture = new ImageCapture(track);

        // set the image capture options (e.g. flash light, autofocus, ...)
        imageCapture.setOptions(imageCaptureConfig)
                .catch(err => console.error('setOptions(' + JSON.stringify(imageCaptureConfig) + ') failed: ', err));
    }
</script>

Remarque:

  • A ce jour, l'API est toujours en cours de développement et pourrait changer à l'avenir.
  • Pour activer ImageCapture in Chrome the flag "chrome: // flags/# enable-experimental-web-platform-features" doit être réglé sur "true"
  • Pour activer ImageCapture dans Firefox, le drapeau "dom.imagecapture.enabled" in "about: config" doit être mis à "true". Mais "setOptions" n'est pas pris en charge à ce jour!

Voir également:

5
ltlBeBoy