是否可以通过网站控制手机上的摄像头灯?

Posted

技术标签:

【中文标题】是否可以通过网站控制手机上的摄像头灯?【英文标题】:Is it possible to control the camera light on a phone via a website? 【发布时间】:2016-10-17 08:08:47 【问题描述】:

通过 Chrome 或 Firefox 说。我知道可以使用 androidios 应用程序,那里有许多手电筒应用程序。而且我知道可以通过 getUserMedia 系列功能控制摄像机。如果没有,有谁知道什么时候可以使用?

【问题讨论】:

你有没有想过你是否可以做到这一点,如果可以,怎么做? 【参考方案1】:

这是一个用于网站的小“火炬应用”:

编辑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
  
  
<button class="switch">On / Off</button>

代码深受repository、webseries 和blog-post 的启发

编辑 2: 这仅适用于 Chrome(也许还有 Opera)。它不适用于 iOS 上的 Chrome,because Chrome cannot access the camera。 我现在无法在 android 上测试它。我创建了一个带有输出的新 jsfiddle。如果你有一部安卓手机,但它不适合你,它可能会告诉你原因: https://jsfiddle.net/jpa1vwed/

随意调试、评论和编辑。

【讨论】:

这适用于 iOS 吗?我有一个工作应用程序在 iOS 上的 Safari 11 中使用 getUserMedia 访问相机,但截图对我不起作用。有人测试过吗? 它只能在 Chrome 中工作,因为 ImageCapture 目前只在 Chrome 和 Opera 中支持(我没有安装 Opera,所以我无法测试它)。它不再适用于 Iphone 上的 chrome,我目前正在研究它。 Chrome 无法访问 iphone 上的摄像头 (***.com/questions/51501642/…),所以这也行不通...我将在 android 上的 chrome 中测试它,我需要先找到一个 android 手机。 有人可以更新这个来为手电筒添加切换功能吗?就像一旦打开手电筒,就无法关闭它 @DanielBudick Chrome 可以并且确实可以访问 iPhone 上的两个摄像头,您需要使用正确的 html5 输入标签<input type="file" accept="image/*" capture="environment">“环境”用于背面,“用户”用于正面。【参考方案2】:

您可以通过从 VideoStreamTrack 创建 ImageCapture 并将选项 "fillLightMode" 设置为 " 来使用 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" 必须设置为 “真” 为了在 Firefox 中启用 ImageCapture"about:config" 中的标志 "dom.imagecapture.enabled" 必须设置为 “真”。 但在撰写本文时,不支持 “setOptions”

另见:

Mediastream Image Capture 在 GitHub 上 NPM 模块ImageCapture polyfill

【讨论】:

四年过去了,已经是2021年了,这个功能好像没了。可以理解。 ImageCapture 支持比底层轨道更多的操作,例如在没有再次请求许可的情况下关闭和打开手电筒。也许根本不可能支持所有设备,所以他们不得不修剪它。【参考方案3】:

我修复了 Daniel 的答案,现在按钮可以在 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
<button class="switch">On / Off</button>
<h2>
Console output
</h2>
<div id="console">

</div>

【讨论】:

以上是关于是否可以通过网站控制手机上的摄像头灯?的主要内容,如果未能解决你的问题,请参考以下文章

苹果电脑摄像头黑屏应该怎么处理?

和家亲摄像头一直闪篮灯怎样连接云服务器

opencv 物体运动检测,摄像头灯亮,却没有画面黑屏

Phonegap 摄像头控制

如何控制用Delphi摄像头

为啥摄像头不能用了,而且那个灯都不亮,连webcam打开了也不行