Chrome 可以通过网站控制手机上的摄像头灯光吗?

fdx2calv  于 2023-08-01  发布在  Go
关注(0)|答案(5)|浏览(91)

是否可以通过网站在手机上控制相机的闪光灯?通过Chrome或Firefox。我知道使用Android或iOS应用程序是可能的,这是由所有手电筒应用程序实现的。而且我知道人们可以通过getUserMedia系列功能来控制相机。如果没有,有谁知道什么时候可以使用?

mwecs4sa

mwecs4sa1#

下面是一个网站的小“ Torch 应用程序”:

**编辑1:**我还做了一个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
  
  
}

个字符
代码的灵感来自于repositorywebseriesblog-post

**编辑2:**这只适用于Chrome(可能还有Opera)。它在iOS上的Chrome中不起作用,because Chrome cannot access the camera。目前还不能在Android上测试。我创建了一个新的jsfiddle,有一个输出。如果你有一个Android手机,它不适合你,它可能会告诉你为什么:https://jsfiddle.net/jpa1vwed/

请随意调试、评论和编辑。

q0qdq0h2

q0qdq0h22#

您可以通过从 VideoStreamTrack 创建 ImageCapture 并将选项 “fillLightMode” 设置为 “flash”“torch” 来使用MediaStream Image Capture API。范例:

<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>

字符串

注:

  • 在撰写本文时,API仍在开发中,将来可能会发生变化。
  • 要在Chrome中启用 ImageCapture,必须将标记 “chrome://flags/#enable-experimental-web-platform-features” 设置为 “true”
  • 要在Firefox中启用 ImageCapture,必须将 “about:config” 中的标记 “dom.imagecapture.enabled” 设置为 “true”但是 “setOptions” 在撰写本文时不受支持!

参见:

fcwjkofz

fcwjkofz3#

我修复了丹尼尔的答案,现在按钮在Android手机上正常工作. iOS仍然不支持。
https://jsfiddle.net/nzw5tv1q/

//have a console on mobile
const consoleOutput = document.getElementById("console");
const log = function (msg) {
  consoleOutput.innerText = `${consoleOutput.innerText}\n${msg}`;
  console.log(msg);
}

//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) {
      log('No camera found on this device.');
    }
    // Create stream and get video track
    navigator.mediaDevices.getUserMedia({
      video: {
        facingMode: 'environment',
      }
    }).then(stream => {
      const track = stream.getVideoTracks()[0];

      //Create image capture object and get camera capabilities
      const imageCapture = new ImageCapture(track)
      imageCapture.getPhotoCapabilities().then(capabilities => {
        //let there be light!
        const btn = document.querySelector('.switch');
        const torchSupported = !!capabilities.torch || (
          'fillLightMode' in capabilities &&
          capabilities.fillLightMode.length != 0 &&
          capabilities.fillLightMode != 'none'
        );

        if (torchSupported) {
          let torch = false;
          btn.addEventListener('click', function (e) {
            try {
              track.applyConstraints({
                advanced: [{
                  torch: (torch = !torch)
                }]
              });
            } catch (err) {
              log(err);
            }
          });
        } else {
          log("No torch found");
        }
      }).catch(log);
    }).catch(log);
  }).catch(log);

  //The light will be on as long the track exists
}

个字符

hpxqektj

hpxqektj4#

在这里,它是一个处理手电筒的静态类。您可以在窗口加载时调用flashlightHandler.accessFlashlight()。然后使用flashlightHandler.setFlashlightStatus()方法,根据需要传递truefalse

class flashlightHandler {

    static track; //the video track which is used to turn on/off the flashlight

    static accessFlashlight() {
        //Test browser support
        if (!('mediaDevices' in window.navigator)) {
            alert("Media Devices not available. Use HTTPS!");
            return;
        };

        //Get the environment camera (usually the second one)
        window.navigator.mediaDevices.enumerateDevices().then((devices) => {

            const cameras = devices.filter((device) => device.kind === 'videoinput');
            if (cameras.length === 0) {
                alert("No camera found. If your device has camera available, check permissions.");
                return;
            };
            
            const camera = cameras[cameras.length - 1];
            
            window.navigator.mediaDevices.getUserMedia({
                video: {
                    deviceId: camera.deviceId
                }
            }).then((stream) => {
                this.track = stream.getVideoTracks()[0];
                
                if (!(this.track.getCapabilities().torch)) {
                    alert("No torch available.");
                }; 
            });
        });
    }

    static setFlashlightStatus(status) {
        this.track.applyConstraints({
            advanced: [{
                torch: status
            }]
        });
    }
}

字符串

w46czmvw

w46czmvw5#

我必须在工作中实现一个类似的功能,这些答案对我帮助很大,事情是我需要在React Js Web应用程序中实现它,所以我使用了旧答案中提供的一些代码来制作一个react hook来处理设备的torch的使用(如果它在设备中可用)。我把它做成了一个简单的react项目,放在代码沙箱里,万一将来有人需要类似的东西,这可能会很有用
https://codesandbox.io/s/dazzling-blackburn-yj5dyy

相关问题