使用相机手电筒不允许更改面对模式 - Navigator.mediaDevices

Posted

技术标签:

【中文标题】使用相机手电筒不允许更改面对模式 - Navigator.mediaDevices【英文标题】:Using camera flashlight not allowing to change facingmode - Navigator.mediaDevices 【发布时间】:2021-12-08 05:08:59 【问题描述】:

我正在尝试构建一个网络应用程序,该应用程序根据设备使用网络摄像头或移动相机拍照。我已经制作了一个按钮来更改约束。面对模式,如果设备支持,用户可以使用两个相机(“环境”,“用户”)。问题是,当我也启用手电筒支持时,通过创建一个按钮并将其设置为手电筒切换器,如下所示:

const SUPPORTS_MEDIA_DEVICES = 'mediaDevices' in navigator;
        if (SUPPORTS_MEDIA_DEVICES) 
            const track = stream.getVideoTracks()[0];
            const imageCapture = new ImageCapture(track);
            const photoCapabilities = imageCapture.getPhotoCapabilities().then(() => 
                const btn = document.querySelector('.toggleCameraTorch');
                btn.style.visibility = 'visible';
                btn.addEventListener('click', function () 
                    try 
                        track.applyConstraints(
                            advanced: [ torch: !wheelsfs.videoConstraint.torchState ]
                        );
                        wheelsfs.videoConstraint.torchState = !wheelsfs.videoConstraint.torchState;
                    
                    catch(e) 
                        alert(e.message);
                    
                );
            );
        

之后,手电筒工作正常,但我不再可以选择更换相机(面向模式)。当我尝试更换相机时,出现错误“无法启动视频源”。就像相机已经被什么东西使用了一样。

这就是我改变相机的方式 - 面对模式:

 wheelsfs.videoConstraint.facingMode.exact = wheelsfs.videoConstraint.facingMode.exact == "environment" ? "user" : "environment";  
    var cameraInput = wheelsfs.videoConstraint.facingMode.exact;

    wheelsfs.videoTrue.srcObject && wheelsfs.videoTrue.srcObject.getTracks().forEach(t => t.stop());

    wheelsfs.videoConstraint = 
        video: 
            width:  ideal: trueWidth ,
            height:  ideal: trueHeight ,
            facingMode:  ideal: "environment" 
        ,
        facingMode:  exact: cameraInput 
    ;

    navigator.mediaDevices.getUserMedia( video: wheelsfs.videoConstraint ).then(function (stream) 
        wheelsfs.videoTrue.srcObject = stream;
        wheelsfs.videoTrue.play();
        const SUPPORTS_MEDIA_DEVICES = 'mediaDevices' in navigator;
        if (SUPPORTS_MEDIA_DEVICES) 
            const track = stream.getVideoTracks()[0];
            const imageCapture = new ImageCapture(track);
            const photoCapabilities = imageCapture.getPhotoCapabilities().then(() => 
                const btn = document.querySelector('.toggleCameraTorch');
                btn.style.visibility = 'visible';
                btn.addEventListener('click', function () 
                    try 
                        track.applyConstraints(
                            advanced: [ torch: !wheelsfs.videoConstraint.torchState ]
                        );
                        wheelsfs.videoConstraint.torchState = !wheelsfs.videoConstraint.torchState;
                    
                    catch (e) 
                        alert(e.message);
                    
                );
            );
        
    ).catch((e) =>  console.log(e.message); 
                    

【问题讨论】:

【参考方案1】:

通过将 stream.getVideoTracks()[0] 存储到一个变量中,然后在更改相机(面向模式)之前对其调用 stop() 来解决此问题。

所以当我这样做时:

if (SUPPORTS_MEDIA_DEVICES) 
            wheelsfs.track = stream.getVideoTracks()[0];
            const imageCapture = new ImageCapture(wheelsfs.track);
            const photoCapabilities = imageCapture.getPhotoCapabilities().then(() => 
                const btn = document.querySelector('.toggleCameraTorch');
                btn.style.visibility = 'visible';
                btn.addEventListener('click', function () 
                    try 
                        wheelsfs.track.applyConstraints(
                            advanced: [ torch: !wheelsfs.videoConstraint.torchState ]
                        );
                        wheelsfs.videoConstraint.torchState = !wheelsfs.videoConstraint.torchState;
                    
                    catch (e) 
                        alert(e.message);
                    
                );
            );
        

在第二行中,我将轨道保存在公共变量中,然后当调用更改正在使用的相机的函数时,我确保我运行 “wheelsfs.track.stop();”就在 navigator.mediaDevices.getUserMedia 调用之前。

【讨论】:

以上是关于使用相机手电筒不允许更改面对模式 - Navigator.mediaDevices的主要内容,如果未能解决你的问题,请参考以下文章

使用相机闪光灯作为手电筒的应用程序使用 Eclipse 不工作

如何在不破坏相机应用程序的情况下在Android手机上打开手电筒[重复]

Android 相机(手电筒)API 太慢

使用相机时如何打开/关闭手电筒?

我需要啥权限才能在相机预览中使用相机闪光灯?

如何使用qt打开相机闪光灯或手电筒?