如何在本地主机Web服务器上配置权限等,以允许PHP程序访问连接的USB摄像头

时间:2019-05-07 05:47:55

标签: php camera sandbox

我最初是在不同地询问上问这个问题的,但是管理员说这对于该组来说“太宽泛了”,我应该在这里提出。

我正在尝试创建一个PHP程序,该程序将在localhost上运行,并且需要从连接的USB摄像头设备(我正在开发的摄像头阵列外围设备)拍摄快照。

我正在在 MacBook Pro 上运行的 Mac OS X Mojave 上进行开发。我最终将部署到具有运行Mac OS X的嵌入式Mac Mini或运行Linux的嵌入式Raspberry Pi的信息亭。我正在开发的自定义相机阵列硬件也嵌入在此信息亭中。

我目前在Mac上使用 imagesnap ,并计划在Linux上使用 fswebcam 进行编程拍照。

我已经设置了我作为 localhost 访问的本地Apache Web服务器。我还安装了 PHP 7.1.23

我已经编写了一个PHP程序(请参见下文),该程序应列出使用 imagesnap -l <​​/ em>连接到计算机的可用摄像机,然后它应使用 imagesnap对列出的每个摄像机拍摄图像。 -d

如果我以自己的用户ID在终端下以CLI模式运行此PHP程序,它将列出相机并拍摄并保存图像。

但是,我打算的部署将在自助服务终端中,该终端具有一个网页界面,该界面在拍摄图像时会调用此PHP程序。

不幸的是,这是一个问题。症状很明显:

当PHP程序以我的用户ID在CLI模式下运行时,它会很好地处理图像并将其写入Web目录的相应子目录中。

% php ../imagesnaptest.php
imagesnap -l  RETURNS 'Video Devices:
<AVCaptureDALDevice: 0x7fda89438500 [FaceTime HD Camera][DJH6095K5ZEG1HPBB]>
' 
FaceTime HD Camera is a valid camera. 
camerasArray = 
array(1) {
  [0]=>
  string(18) "FaceTime HD Camera"
}

imagesnap -d 'FaceTime HD Camera' /Users/myiuserid/Sites/sonascan/scans/img5cd115d73d2b5.jpg  RETURNS 'Capturing image from device "<AVCaptureDALDevice: 0x7fb27b32dbb0 [FaceTime HD Camera][DJH6095K5ZEG1HPBB]>"...'

Captured 1 images from  cameras.
IMAGING COMPLETE.

但是当通过浏览器的HTTP调用调用该php程序时,它以 _www 身份运行,并且似乎无法访问摄像机,并且没有图像保存到Web目录。但是没有错误消息解释为什么imagesnap失败(甚至承认它已经失败了)。

% imagesnap -l RETURNS '' 
camerasArray = 
array(0) { } 
No valid cameras were found!

我已经开放了我的Web目录的所有人的权限 rwx ,并且这种行为上的差异保持不变。

有人建议我,我的问题是权限配置错误,因为通常 _www 网络服务器用户无法访问连接的USB设备(如相机)。但是,没有人建议我可以改变它。

在探索迄今为止我提出的建议时,我尝试制作了 _www 甚至 root 和< em>甚至在程序上设置了setuid位。这不能解决问题。相反,它引入了一个新错误,该错误生成了错误消息:

*2019-05-06 19:56:44.081 imagesnap[60072:14580598] The application with bundle ID (null) is running setugid(), which is not allowed*

评论员 @nohillside 写道:

  

”这可能是一个简单的访问权限问题,可能是Apache   配置错误,这可能是SIP(系统完整性保护),沙箱或   完整的磁盘访问权限,这可能是其他事情。没有更多   有关设置的详细信息以及您需要进行的一些挖掘(例如,如果您   用仅记录自身的shell脚本替换imagesnap   工作),任何答案都只能是猜测。”

按照 @nohillside 的建议,我将 imagesnap 替换为无法访问相机的程序(“ / usr / local / bin / python3 -h ”,并且在更改程序时没有错误。因此,我认为这与 imagesnap 所需的相机访问有关。

在我看来,这可能与 SIP 沙箱有关,但我不知道如何更改和测试替代SIP或沙箱配置。如果您了解如何配置这些配置,并有建议供我测试,请更精确地描述如何更改此配置。

我如何才能了解有关如何配置Web服务器以使其以这种方式访问​​我的相机的更多信息?在哪里可以了解有关SIP和沙箱安全性通常如何工作以及如何运行的更多信息。我应该针对刚刚描述的情况进行调整。

<?php

if (php_sapi_name() == "cli") { $nl= PHP_EOL; }  //PHP is running in command line
else {  $nl= "<br />"; } // PHP is running in browser }

function getListOfCameras() 
{
    global $nl;

    $imagesnaplist = shell_exec("/usr/local/bin/imagesnap -l");
    echo "imagesnap -l  RETURNS '" . $imagesnaplist ."' $nl"; 

    $cameraDeviceArray = explode(PHP_EOL,$imagesnaplist );
    unset ($cameraDeviceArray[0]); // Throw away "Video Devices:" line in element [0]
    $cameraDeviceArray = array_values($cameraDeviceArray); // Reassign elements in array to start at [0] again

    $matchedCameras = 0;
    $camerasArray  =array();
    foreach ($cameraDeviceArray as $key => $value)
    {
            preg_match("/\[(.*?)\]/", $value, $matches);
            if ($matches[1] != "") 
            {
                $camerasArray[$matchedCameras] = $matches[1];
                echo $camerasArray[$matchedCameras]. " is a valid camera. $nl";
                $matchedCameras++;
        }
    }
    return $camerasArray;
}


function takeAPhoto($camera, $filename) 
{
    global $nl;
    $status = shell_exec("/usr/local/bin/imagesnap -d '$camera' $filename ");
    echo "imagesnap -d '$camera' $filename  RETURNS '" . $status . "'$nl"; 
    return $status;     
}


function takeAllPhotos($camerasArray) 
{
    global $nl;
    $numberTaken = 0;
    if (count($camerasArray) > 0)
    {
        foreach ($camerasArray as $camera)
        {
            $cameraNumber = $numberTaken;
            $filename = "/Users/myiuserid/Sites/sonascan/scans/img" . uniqid() . ".jpg";
            $status = takeAPhoto($camera, $filename); 
            $numberTaken++;      
        }
        return $numberTaken;
    } else 
    {
        die("No valid cameras were found!$nl");
    }
}

$camerasArray =  getListOfCameras();
echo "camerasArray = $nl";
var_dump($camerasArray);
echo "$nl";

$numberTaken = takeAllPhotos($camerasArray);
echo "$nl" . "Captured $numberTaken images from $numberOfCameras cameras.$nl";
echo "IMAGING COMPLETE.$nl";

?>

0 个答案:

没有答案