Вчера ко мне в голову пришла «мысля» о том, что… ну нехорошо как-то получается: на смартфонах в беззвучном режиме о наличии уведомлений с помощью LED-индикатора узнать можно, а на компьютере — нет.
Представим себе ситуацию, что вы забыли отключить от ноутбука наушники. Тут вам в фоне написали, скажем, в ВК, а узнать вы об этом, если уведомления в браузере не включены, никак не сможете. Нужно это исправить!
Заинтересовало? Добро пожаловать под кат!
После примерно получаса дум, я пришёл к… dll-файлу, упрощающему жизнь, а заодно и разработку моей будущей программы. DLL'ник сей именуется «escapi».
Т.к. с C++ я знаком не шибко, решил разработать
Перейдём, наконец, к делу.
Скачав вышеуказанную библиотеку, сразу же полез в папку «Examples». Обнаружил там несколько скомпилированных примеров, а так же их исходники. На самый простой и подходящий мне пример взгляд мой упал сразу же. Логично, ведь он называется «simplest.exe». Вот его исходник:
/* "simplest", example of simply enumerating the available devices with ESCAPI */
#include <stdio.h>
#include "escapi.h"
void main()
{
int i, j;
/* Initialize ESCAPI */
int devices = setupESCAPI();
if (devices == 0)
{
printf("ESCAPI initialization failure or no devices found.\n");
return;
}
/* Set up capture parameters.
* ESCAPI will scale the data received from the camera
* (with point sampling) to whatever values you want.
* Typically the native resolution is 320*240.
*/
struct SimpleCapParams capture;
capture.mWidth = 24;
capture.mHeight = 18;
capture.mTargetBuf = new int[24 * 18];
/* Initialize capture - only one capture may be active per device,
* but several devices may be captured at the same time.
*
* 0 is the first device.
*/
if (initCapture(0, &capture) == 0)
{
printf("Capture failed - device may already be in use.\n");
return;
}
/* Go through 10 capture loops so that the camera has
* had time to adjust to the lighting conditions and
* should give us a sane image..
*/
for (i = 0; i < 10; i++)
{
/* request a capture */
doCapture(0);
while (isCaptureDone(0) == 0)
{
/* Wait until capture is done.
* Warning: if capture init failed, or if the capture
* simply fails (i.e, user unplugs the web camera), this
* will be an infinite loop.
*/
}
}
/* now we have the data.. what shall we do with it? let's
* render it in ASCII.. (using 3 top bits of green as the value)
*/
char light[] = " .,-o+O0@";
for (i = 0; i < 18; i++)
{
for (j = 0; j < 24; j++)
{
printf("%c", light[(capture.mTargetBuf[i*24+j] >> 13) & 7]);
}
printf("\n");
}
deinitCapture(0);
}
Вкратце: программа включает веб-камеру, делает 10 снимков подряд, дабы дать камере сфокусироваться, установить выдержку и т.п., затем берёт последний кадр и выводит некую его часть в ASCII.
Нам, для «мигания» светодиодом камеры необходимо делать лишь один снимок, не выводя его на экран и/или делая с ним что-либо ещё. Ибо, если светодиод камеры включается только тогда, когда она (камера) активна, нам остаётся лишь убрать лишнюю часть кода, и… вуаля! Екзекьютэбл готов.
Новый код (только функция):
/* WebCamLED Notifier 1.0 by Sdore */
#include <stdio.h>
#include "escapi.h"
void led()
{
struct SimpleCapParams capture;
capture.mWidth = 24;
capture.mHeight = 18;
capture.mTargetBuf = new int[24 * 18];
initCapture(0, &capture);
doCapture(0);
deinitCapture(0);
}
Компилируем в пачке с библиотекой escapi, запускаем. Светодиод камеры загорается и сразу гаснет. Работает! Ну, осталось только найти применение. Следуя задумке, вполне логично сделать систему уведомлений. Программу набросаю в своей любимой среде разработки «Алгоритм 2».
Но это уже в следующей части.
P.S. Это мой первый пост, но, надеюсь, далеко не последний...
Спасибо за внимание, удачи!
Upd: По замечанию одного из комментаторов,
Стоило бы упомянуть, что описываемое решение windows-only.Об этом-то я как раз и забыл сказать. Спасибо за дополнение.
Комментарии (17)
vlreshet
18.11.2015 19:29+1А екзешничек выложить не хотите? А ещё лучше — вырезать лишнее с escapi, и запилить свою библиотеку предназначенную только для работы со светодиодом.
sdore
18.11.2015 19:361. Сейчас будет вторая часть. Там всё относительно .exe и т.п. В конце статьи же написано.
2. Как сказано в статье, у меня уж не такие знания C++, да и вообще Я.П., так что написать свою библиотеку — это для меня уж слишком… пока что.
kstep
18.11.2015 19:37+1Идея интересная, но…
1) Статья очень куцая, на статью не тянет (да, я читал, что статья пишется «по ходу разработки», но всё же осадок есть).
2) Стоило бы упомянуть, что описываемое решение windows-only.
AllexIn
18.11.2015 20:26Ну и зачем это надо?
Светодиод на камере — это детектор для определения что она работает. То есть, чтобы можно было отсечь программы-шпионы работающие с камерами(коих полно). Используя такой софт вы даете программам шпионам лазейку. Потому что они смогут адаптироваться и скрыть факт съемки за якобы уведомлением.
Уж лучше проделать дыру в корпусе ноута и воткнуть отдельный диод и им мигать.sdore
18.11.2015 21:03Тут Вы глубоко ошибаетесь. Для отображения уведомления, в данном случае, включается камера. Обычно, если не ошибаюсь, в момент камера может использоваться только одним процессом. И, т.к. библиотека при получении уведомления ненадолго включает камеру, да ещё и с нестандартным разрешением, то в это же время программа-шпион использовать камеру не сможет. Если уж так, то, сначала светодиод включится и погаснет от уведомления, а затем уже снова включится для шпиона, что его и выдаст.
Если Вы скажете, мол, шпион может не посылать в мою программу запрос на уведомление, а просто сделать снимок. Мой ответ:
В моей программе (я её разрабатываю, как сказано во 2-ой части статьи. Но UI я ещё нигде не показывал. Это будет висящий в трее значок, при ПКМ по которому открывается меню с «Service is running»; «Notifications...», «Test»; «Exit...» кнопками. Нас интересует пункт уведомлений. Если светодиод мигнул, а в списке уведомлений такового не поивилось, значит, это было не уведомление. Тут уже Юзеру решать, какие меры принимать. Да хоть салфеткой камеру закрывать, когда не используется. У меня всё.AllexIn
18.11.2015 21:15Всего делов то, ваша прога будет думать что работает с драйвером камеры, но будет при этом работать через враппер предоставленный шпионом. В итоге все действия с камерой будут осуществляться не так как хочет ваша прога.
Зло здесь не на уровне кода. Зло здесь на уровне привычек пользователя, когда он перестанет воспринимать мигание светодиода камеры как факт работы камеры и начнет считать его неким фоновым событием.
Светодиод как бы придумали для того, чтобы не вешать салчетки и изоленту не клиеть. А вы предлагаете опять к изоленте вернуться. :))sdore
18.11.2015 21:42Ну есть немного. :) НО! Относительно враппера, как насчёт просто сделать выбор камеры?)
vlreshet
19.11.2015 10:19А в чём тут будет проблема?) враппер может проксировать через себя всё что угодно, включая название камеры, и библиотека ни о чём не заподозрит)
sdore
19.11.2015 12:06Гмм, оно и верно… Тут нужно будет исправить.
vlreshet
19.11.2015 12:18Да тут нельзя что-то исправить, так или иначе любую такую защиту можно будет обойти. Идея сама по себе интересная, реализовать такое чисто для себя и быть уверенным в том что всё безопасно — это круто. Но если это начнут использовать массово то люди, как кто-то уже писал выше, просто перестанут обращать внимание на мигание камеры как на что-то опасное. И тогда посыпется поток троянов да малвари. И хоть мигать несколько раз, хоть нотификейшены слать — это всё не поможет.
sdore
19.11.2015 14:28Впринципе, оно и задумывалось как для «малого круга»/для себя. Прости решил поделиться идеей. Лично я не волнуюсь о приватности и т.п., ибо мне нечего скрывать от вирусов.
Кстати, как вариант, можно самой этой программой сделать виртуальный драйвер, установить его в системе (за заодно и для вирусов) основной, а все нужные программы настроить на использование настоящей. Как считаете, может помочь?
bockra
А идея-то отличная! Прямо очень-очень отличная, тк камерой на ноутбуке пользуюсь раз в год.
sdore
Спасибо, буду развивать :)