Как настроить разрешения и т. Д. На локальном веб-сервере, чтобы разрешить программам PHP доступ к подключенной USB-камере - PullRequest
0 голосов
/ 07 мая 2019

Первоначально я задавал этот вопрос на Спросите по-другому , но администратор сказал, что он был "слишком широким" для этой группы, и что я должен задать его здесь.

Я пытаюсь создать программу PHP, которая будет работать на локальном хосте и должна делать снимки с подключенных USB-устройств камеры (периферийное устройство массива камер, которое я разрабатываю).

Я занимаюсь разработкой для Mac OS X Mojave , работающей на MacBook Pro .В конечном счете, я буду использовать киоски со встроенным Mac Mini под Mac OS X или со встроенным Raspberry Pi под Linux.Массив пользовательских камер HW, который я разрабатываю, также встроен в этот киоск.

В настоящее время я использую imagesnap на Mac и планирую нам fswebcam на Linux, чтобы взятьизображения программно.

Я настроил локальный веб-сервер Apache , к которому я получаю доступ как localhost .У меня также установлен PHP 7.1.23 .

Я написал программу PHP (см. Ниже), которая должна перечислять доступные камеры, подключенные к компьютеру, используя imagesnap -l и затем он должен получить изображение с каждой из перечисленных камер, используя imagesnap -d .

Если я запускаю эту программу PHP в режиме CLI из терминала под своим собственным идентификатором пользователя, он перечисляеткамера и взяла и сохранила изображение просто отлично.

Однако мое предполагаемое развертывание будет в киоске с интерфейсом веб-страницы, который вызывает эту программу PHP, когда изображения должны быть сделаны.

К сожалению, есть проблема.Симптомы очевидны:

Когда программа PHP работает в режиме CLI с моим userID, она хорошо воспринимает изображения и записывает их в соответствующий подкаталог веб-каталога.

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

Но когда эта php-программа вызывается с помощью HTTP-вызова из браузера, она запускается как _www и не может получить доступ к камерам, и изображения не сохраняются ввеб-каталог.Но сообщения об ошибке, объясняющего, почему произошел сбой imagesnap (или даже подтверждающего его наличие), нет.

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

Я открыл разрешения для моего веб-каталога на rwx для всех и эта разница в поведении осталась неизменной.

Мне было предложено, чтобы моя проблема была в неправильной конфигурации разрешений, потому что обычно пользователь веб-сервера _www не имеет доступа к подключенным USB-устройствам, таким каккамеры.Однако никто не предложил, как я могу это изменить.

Изучая предложения, которые мне были даны на сегодняшний день, я экспериментировал с созданием imagesnap , принадлежащим _www , илидаже root и даже установка бита setuid в программе. Это не решило проблему.Вместо этого была введена новая ошибка, которая вызвала сообщение об ошибке:

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

commenter @ nohillside wrote:

"ThisЭто может быть проблема с простым разрешением доступа, это может быть неправильная конфигурация Apache, это может быть проблема, связанная с SIP (защита целостности системы), песочницей или полными правами доступа к диску, это может быть что-то другое. Без подробностей о настройке и некоторыхкопание с вашей стороны (например, если вы замените imagesnap сценарием оболочки, который просто регистрирует себя, работает ли он), любой ответ может быть только догадкой. "

Отслеживание @ nohillside Я заменил imagesnap на программу, которая не имеет доступа к камере (" / usr / local / bin / python3 -h ", и при работе программы не возникает ошибкаЯ думаю, что это как-то связано с доступом к камере , которое imagesnap необходимо.

Для меня имеет смысл, что это может иметь какое-то отношение к SIP или песочнице , но я понятия не имею, как изменить и протестировать альтернативные конфигурации SIP или песочницы.Если у вас есть знания о том, как их настроить, и у вас есть предложения для меня протестировать, пожалуйста, опишите более точно, как изменить эту конфигурацию.

Как я могу узнать больше о том, как настроить мой веб-сервер таким образом, чтобы он мог таким образом получать доступ к моей камере? И где я могу узнать больше о том, как обычно работают 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";

?>
...