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