Связаться со мной можно, черканув пару строк на mail@mindcollapse.com или же в skype: orl-light
После просмотра видео, у вас наверняка возник немой, но вполне ожидаемый вопрос - qu'est-ce que c'est et pourquoi est-il nécessaire? Тут все просто, однажды в компании Philips решили, что было бы вполне неплохо изъебнуться и встроить в жопную часть своего телевизора RGB светодиоды, которые будут светить на стену (и не просто так, а в зависимости от цветов на экране), визуально увеличивая диагональ экрана и уменьшая световой перепад при просмотре чудес кинематографии в темной комнате. Решили и, что качественно отличает этих ребят от инноваторов из Сколково, запилили, назвали Ambilight, крутанули рекламу, но как-то народ почему-то не оценил. Возможно, очередная фокус группа состоящая чуть более, чем полностью из воинствующих эпилептиков, страдающих дальтонизмом, забраковала фишку, посчитав ее слишком сложной и непонятной для конечного потребителя, возможно, все погнались за новомодным 3D, оставив этот теплый ламповый свет в прошлом, возможно, все проблемы в том, что хитрожопые голландцы из филипса быстренько запатентовали концепцию, оставив всех стальных за бортом со связанными руками. Но это и не важно, идея получила отражение в творчестве народных масс, о чем чуть ниже.
Я давно заприметил эту интересную технологию, но раньше у меня телевизор стоял напротив окна, что, разумеется, лишало какой-либо возможности проецировать свет из задницы на отражающую поверхность. Да и все решения на тот момент времени состояли из каких-то DIY комплектов. Я, конечно, паять всякие мелочи умею, но вот возиться с хлорным железом, утюгом и SMD не было ни малейшего желания. А тут получилось выделить отдельную комнату под домашний кинотеатр и как раз случайно наткнулся на лепре на ребят из Ижевска, которые поставили производства plug and play комплектов для ambient light на конвейер. Я попал практически в конец предзаказа, 4 недели ждал изготовления и еще 2 доставки из Удмуртии в Украину. Фотографировать весь комплект до начала установки я не додумался, уж больно долгим было ожидание, но при желании вы можете посмотреть все в топике на хабре, я лишь отмечу сильные и слабые стороны подобного решения.
Наверняка, существует какое-то научное объяснения всему этому, но смотреть фильмы с ambient light очень приятно. Прежде всего, нет яркого контраста черной стены и дисплея. Особенно это чувствует при резкой смене яркости, глаза не слепнут. Эффект прекрасно выглядит на динамических сценах. Ну там где много взрывов, погоней, лазеров, бластеров и прочей хуиты. Про увеличение диагонали экрана мне судить сложно, все же наличие черной рамки экрана визуально ограничивает зону просмотра, но определенного эффекта присутствия это добавляет. Вообще, все плюсы сводятся к тому, что ты не замечаешь наличия лайтпака, он делает свое дело, но от поисходящего на экране постоянными миганиями не отвлекает, как это может ошибочно казаться при просмотре ютубовского видео. Однозначным плюсом является хорошее и удобное мультиплатформенное ПО, ну и отсутствие необходимости чего-то паять, крутить, зачищать. Наклеил, настроил и наслаждаешься.
Но, как всегда, есть и минусы. Прежде всего, основной объективный недостаток - необходимость наличия компьютера для передачи данных устройству о цветах того, что происходит на экране. Повторюсь, недостаток объективный, лично я уже очень давно использую неттоп Zotac в качестве HTPC, чего и вам желаю. nVidia ION способна лишь на это. Алгоритм и сама концепция съема цветов непосредственно с видеосигнала защищена филипсовским патентом, да и достаточно дорогостоюща в плане железной реализации, для анализа HDMI потока одним микроконтроллером и парочкой драйверов светодиодов уже не обойтись. Есть и конструктивные недочеты. Клеющаяся лента на задней стороне светодиодных лет сделана из хуй пойми чего, они вообще нифига не держатся, хотя лично у меня поверхность поклейки имеет железную шершавую поверхность и была заблаговременно обезжирена спиртом. Ну и кого-то, возможно, может отпугнуть цена, мне с доставкой получилось что-то около 4090 руб., что равняется чуть больше штуки гривен в пересчете на наши с вами.
На видео видно, что я все делал на скорую руку. Кое-где есть световые ямы, кое-где проблемы с зонами захвата, которые нужно бы увеличить, но в целом, результат меня не разочаровал. Ребята из Ижевска большие молодцы.
Чуть позже у нас будет обзор Raspberry Pi. Тут мне повезло меньше, в первую волну рассылки я не попал, деньги с карточки сняли, а обещают отправить только в начале мая. Хотя я до сих пор не понимаю, зачем мне оно нужно. Ну и напишу детальный review нового фотоаппарата (переходное звено между мыльницей и зеркалом) Canon G12, именно на него и проходили съемки вышепоказанного ролика. Не судите строго, бедняга снял вполне достойное видео, хотя и сходил с ума от ярких цветов и низкой освещенности, ну и ютуб, как всегда - изговнял всю малину. Ну и за жизнь чего-то напишу. Stay tuned!
Начнем с самого глубокого серверсайда. В распоряжении имелся старенький слабенький сервачок с ненавистным CentOS-ом, ну делать было нечего. Прежде всего, нужно понять, что без иксов нам абсолютно никак не обойтись. Они нужны для виртуальных дисплеев, куда мы будем высаживать наши браузеры. Варианта два: мы можем использовать xorg-x11-server-Xvfb либо же vncserver, который представляет собой perl обертку вокруг Xvnc. Я советую остановиться на втором варианте преимущественно по причине меньшего количества dependencies, возможности удобного удаленного подключения для настройки того же браузера и отсутствия проблем с битностью цвета. К тому же, на старике-центосе Xvfb почему-то постоянно отваливался, а ядро было собрано без поддержки framebuffer, поэтому устройство /dev/fb[0-9] отсутствовало, сводя на нет все преимущества утилит fbdump и fbgrab. После установки vncserver, протестируем его работоспособность, вызвав vncserver :11 -geometry 1920х1200 -depth 24. У вас спросят пароль при первом запуске и, если все прошло без ошибок, то вы счастливчик. Иксы на виртуальном дисплее localhost:11 у вас уже есть. Можете рассказать это своему environment (ненавижу слово "окружение") c помощью export DISPLAY=:11. А еще вы можете запустить xterm и сконектиться через VNC клиент (для виндовса есть отличный бесплатный от RealVNC) и в очередной раз убедиться, что все работает. Теперь нам нужно как-то воровать экран и сохранять его в изображение. В интернетах советуют использовать утилиту import, входящую в набор ImageMagic, но это как перевозить две горошины на грузовом самолете. Вместо нее мы будем использовать xwd из xorg-x11-apps для снятия слепка с виртуального дисплея, и xwdtopnm плюс pnmtopng из netpbm-progs для конвертации его в PNG формат. Тут все еще проще, для получения скриншота вам нужно просто выполнить xwd -root -display localhost:11 | xwdtopnm 2>/dev/null | pnmtopng > screenshot.png. Большая часть серверной магии окончена, осталось сделать небольшой скрипт автоматизации и защиты от дураков. Оговорюсь сразу, что процесс генерации сриншотов будет последователен на основе очереди задач, никакого распараллеливания. О причинах этого мы поговорим чуточку позже. После установки Хромиума, что для ебучего CentOS-а, который сыпется пылью из всех щелей, тоже нихуя не тривиальная задача, мы сделаем небольшой скрипт для облегчения рутины создания скриншотов. Хромиум запускается в инкогнито режиме в фоне, мы ждем открытия страницы 6 секунд (для многих страниц этого времени не хватает, но для тестов сойдет), снимаем скришот и жестко тушим все открытые процессы. Если вам не нужны элементы оформления браузера аля адресная строка или панель табов, то можете добавить ключ --kiosk при запуске хрома. Все пропадет, останется лишь окно с отрендериной страницей, но это выглядит как-то менее эстетично ;). Таким образом, мы собрали все необходимое для создания скриншотов, осталось написать обертку и обертку над оберткой. Пару слов про безопасность: создайте отдельного пользователя из-под которого будете запускать браузер и иксы, отключите все плагины на внутренней странице about:plugins. Клиентская и серверная валидация ссылок в добавок к жесткому ограничению времени исполнения (у нас это 6 секунд) защищает от умников, которые мечтают о stack overflow и arbitrary code execution или пытаются банально загрузить html файл размером с пару гигабайт. От запуска нескольких инстансов браузера для многопоточной генерации пришлось отказаться по этой же самой причине. И да, все настройки хромиума хранятся в JSON формате в файле ~/.config/chromium/Default/Preferences, изменить вам придется параметры размеров окна, потому что даже с ключом --start-maximized у браузера развернуть окно на весь виртуальный экран почему-то не получается.
Часть вторая - middleware или, другими словами, прослойка между сервером-клиентом и своеобразный примитивный менеджер задач. Писать мы ее будем на NodeJS и SocketIO, оба решения мне полюбились event-based моделью. В стандартный набор ноде входит функция spawn объекта child_process для асинхронного запуска дочерних процессов и получения их stdout потоков, которая и будет работать с нашим небольшим bash скриптом. Для создания последовательной модели исполнения, нам нужен какой-то неблокирующий алгоритм task queue и именно поэтому нам не подходит метод Array.forEach. Я, признаться, не стал ебать себе мозг академическими решениями и просто сделал рекурсивную функцию, которая банально вызывала Array.push при добавлении новой задачи и Array.shift при завершении выполнения и переходе на новый цикл итерации с проверкой блокирующей переменной. Решение не идеальное и при больших нагрузках могут возникать проблемы с выпадающими из стека заданиями, но никто больших нагрузок и не ждет - идеальная отговорка для лентяя, который поленился сделать асинхронную модель обработки с помощью setInterval. Чтобы не быть голословным - вот вам код прослойки. Судя по коллекции сохраненных скриншотов, некоторые куллхакеры, думающие, что, выполнив в консоле isURL = function() {return true;}, они обойдут все проверки и удалят мне /etc/passwd, соснули хуйцов и посмотрели веселые картинки на сайте gay.ru. Кекеке!
Последний и самый верхний уровень - clientside не представляет собой ничего особо интересного. Хочу лишь заметить, что при всех преимуществах охуительнейшей библиотеки SocketIO, у нее нету нормальной внятной документации или хотя бы описания API. Лично мне найти не удалось, на гитхабе только описание в примерах, но это не удобно и противоречит законам мироздания. Справедливости ради скажу, что все, описанное мной в этом посте, пахнет влагой и сыростью. Нету ни обработок исключений, ни проверок результата генерации, ни нормальной валидации ссылок, но я лишь даю болванку, а ее обтачивание - дело дорчитателей, которым это необходимо.
Куда ж мы без живых примеров? Никто в наше время тексту не верит. Пришлось перенести все на свой старенький сервачок в далекой Фрицландии, сделать симпатичную обертку на скорую руку и теперь вы можете проверить работу теории на практике в разрастающейся секретной экспериментальной лаборатории интернетовских опытов имени Коли Цискаридзе. Ссылка на ScreenShooter, который старательной описывался в этой статье, работает до последнего посетителя. В качестве бонуса всем, кто дочитал достаточно сложную для формата блога статью, я дарю самодельный уникальный инструмент по раскрутке вашего сайта, известный подписчикам моего твиттера и гуглоплюса. А если серьезно, спасибо всем, кто активно плюсует гуглокнопкой мои посты. Это достаточно приятно и позволяет понять направление дальнейшего развития тематик. Продолжайте в том же духе, нажимайте +1, у меня еще много разнообразных интересностей в черновиках.
Давайте по порядку. Сейчас в моде real-time коммуникации, в техническом смысле этого слова. Контакт, лицокнига, гуглоплюсы - все перечисленные социальные сети имею свой WebIM, позволяющий в реальном времени общаться со своими друзьями и подругами. Правда, концепция там немного другая, чаты этих социалок, как правило, представляют собой JavaScript обертку вокруг XMPP протокола, но смысл понятен. Еще, справедливости ради, стоит заметить, что WebSockets и Server-Sent Events в настоящее время выделены из спецификации HTML5 в отдельные доки, но, опять таки, я утверждаю и буду утверждать, что HTML5 - не технология, а маркетинговый бренд и писькомерялка современных браузеров, поэтому отождествление понятий тут допустимо. Передо мной была поставлена задача создать приложение, позволяющее в реальном времени обмениваться информацией между сервером и клиентом с минимальными задержками. Благо, приложение это исключительно интранетовское и платформа использование - Google Chrome, а значит технически я не был ограничен. Вариантов было несколько: long-polling HTTP запросы, HTTP Streaming или fast-polling, все это называется Comet моделью. И у каждой реализации есть свой недостаток. В спецификации HTTP/1.1 четко указано, что браузер не должен создавать одновременно более 2х параллельных соединений к серверу. Конечно, современные браузеры могут поддерживать десяток connections и подобное нарушение стандарта не является фатальным, но в каждом из вариантов решения есть свои недостатки. Fast-polling, который представляет собой многократное повторение запроса (с завершением сессии) создает приличную нагрузку на сервер, а "висящие" запросы - костыли, которые приводят либо к memory-leak (в последнем фаерфоксе сделать garbage collector для буфера запроса не удосужились, в хроме и сафари память чистится, но только для запросов, возвращающих "Transfer-Encoding: chunked"), к тому же, контролировать Comet сессию сложнее, она может отваливаться без какой-либо видимой причины, да и изначально протокол создавался не для этого. Есть еще BOSH, который используется в вышеупомянутом XMPP, но он заточен больше под создание чатов и готовых решений для этой технологии очень мало. В PaaS Google App Engine, на котором расположен этот блог, есть Channel API, что-то вроде Comet-а, я даже пытался попробовать, но возможности тоже сведены до минимума. Конечно можно еще использовать обертки вокруг flash socket или java-апплета, но не этому учила нас партия.
Вот именно таким путем, перепробовав все вышеназванные методы и оценив ресурсоемкость, я решил остановиться на server-sent events и web-sockets, которые вроде даже выведены из статуса эксперементальных в последних версиях Webkit-а. Начнем с SSE, спецификацию можно почитать тут. По сути, это тот же HTTP Streaming на стероидах. Его смысл заключается в том, что в JavaScript коде или DOM создается объект EventSource со скриптом в src атрибуте или методе-конструкторе. Этот скрипт, прежде всего, должен в контексте "висящего" соединения (хотя и не обязательно) возвращать корректный Content-Type: text/event-stream и в дальнейшем push-ить обновление клиенту в виде строки data: any_text_info \n\n. То бишь, протокол абсолютно односторонний, нас это вполне устраивает, общаться обратно мы можем и через милый сердцу XHR. Есть в нем и вкусности, к примеру, ответ event: test-remote-event \n data: success \n\n, если верить стандарту, можно обрабатывать в addEventListener('test-remote-event' ,function(data){}), правда, это пока только на бумаге. В Chrome Canary у меня работал только event onmessage. Со стороны все всегда кажется таким красивым, но тут начались проблемы, бывает, что поток просто висит. Никакой onerror или onclose не вызывался, сервер продолжает исправно посылать данные, что проверяется curl-ом в консоли, но браузеру пофиг, хотя рестарт страницы помогает. Пробовал в Chrome Stable - та же заморочка. ЧЯДНТ? Вторая и более серьезная проблема - отсутствие поддержки CORS, Access-Control-Allow-Origin: * отсылается, но браузерам на него с большой колокольни, они возвращают DOM Exception 18. Очередная брешь в стандарте, как так - XHR работает, а EventSource нет. Конечно, это все придирки, можно было бы завернуть трафик через proxy_pass в nginx, но в любом случае, осадок остался. К тому же, нужно уже было думать о проверке наличия \n\n в контенте, иначе была бы вероятность получить побитый ответ. Таким вот путем я и пришел к WebSockets. Рассказывать что-либо про клиентскую часть не имеет смысла, есть спецификация, все это делается одной строкой кода, давайте лучше кратко поговорим, как реализовать подобное на сервере. В качестве server-side для подобных проектов я всегда рекомендую брать NodeJS. Сама парадигма event based неблокирующего асинхронного сервера идеально подходит для высокозагруженных API, а этот самый интранет, он очень большой и запросы ресурсоемкие. К тому же, имеющегося в NPM добра с головой хватит для решения любых задач.
Для демонстрации возможностей, я написал небольшое приложение. Прописано оно по адресу. Работать должно в Chrome, Safari (в том числе и на iPad, iPhone с 4.2) и FF. Но в последнем нужно включить поддержку сокетов. Вот вам мануал. Долго думал, откуда бы взять большой поток данных для наглядного примера, как вспомнил про Twitter Streaming API. Код готового приложения можно невозбранно скачать архивом. Если демонстрация перестанет работать - прошу меня простить, мой старенький сервер очень нежный и неторопливый, и больше времени заняла компиляция node, чем прочтение документации или написание самого кода. Разумеется, в server.js нужно вписать свои логин и пароль. Вообще, я использую sample поток, а вы, прочитав документацию по твиттер апи и twitter-node, можете создать какой-то полезный сервис мониторинга и аналитики хештегов, или выводить в форме границ Украины аватары пользователей, написавших что-то на мове. Фантазии ограничены исключительно возможностями API твиттера, а их более чем хватает.
В заключение, хочу сказать, что я постепенно пересматриваю формат блога, если вам понравилась подобная статья - не поленитесь перейти на веб версию, если в РСС читаете, и воспользоваться кнопкой Google +1. Если соберется немного плюсов, то в ближайшее время мы поговорим про WebWorkers, Forms Validation, нарисуем мужской половой хуй в Canvas, напишем вращающийся чайник на WebGL и попробуем накладывать фильтры и получать информацию из тега <video>.
Вообще, само существо HTML5 - первоклассный маркетологичесий трюк. Вы, наверняка же знаете, как сильно я ненавижу этих крысюков. Именно из-за них скорость компьютера измеряется мегагерцами (а теперь еще и количеством ядер), именно из-за них вся техника у нас склеена из глянцевой пальцезагрязняемой пластмассы, именно они причастны к распятию Иисуса, смерти динозавров, голоду в КНДР и ценам на Apple iMac. Так вот, этот термин банально впаривается бедным несчастным домохозяйкам и домохозяевам, как что-то, что много круче веселых ферм в одноклассниках и видео с котятами на ютубах. Я же, как второе пришествие, пророк и просто хороший человек, после десятка лет медитаций и духовного роста познал всю суть, чем, собственно, и собираюсь с вами поделиться. Прежде всего, HTML5 в том виде, что он есть сейчас, является первозданным злом, еще похуже флешей и даже java апплетов, ага. Прежде всего, редакция спецификации все еще никак не выйдет из драфтов, и, зная опыт предыдущих инициатив W3C, затянуться это может на долгое-долгое время. По сути, то, что сейчас вам пихают, как высшей степени инновации и нанотехнологии, является ни чем иным, как тестовым образцом. Если завтра исчезнет тэг video, canvas или еще что - не стоит удивляться (я утрирую, разумеется дело касается более тонких материй, чем стирание абзацев про отдельный элемент), это будет просто очередная смена черновика, не более. Во-вторых, то, что сейчас называют HTML5 вышло слишком далеко за рамки своего определения: языка разметки. Взять тот же LaTeX, он обеспечивает основную задачу - верстку сложных текстов, исключая такие побочные процессы, как печать, рисование картинок для книги, генерацию рекламных текстов и прочее. HTMLпять же превращается в уродливого франкенштейна, который обрастает кусками из совершенно неадекватных функций, к примеру - нативная поддержка Drag`n`Drop или edit in place. Я уже молчу про canvas, которые совершенно не вяжется в контекст определения. Из всего этого возникает третья проблема - зависимозависимость HTML5. В первых версиях, разметка, заданная этим языком, была самодостаточная и не требовала использования чего либо, кроме официального мануала. Со временем, HTML начал обрастать CSS, а в последнее время уже и сложно представить одно без другого. Ну а теперь сюда еще входит и javascript. Иначе какой смысл от этого вашего канваса, draggable элементов и прочего?
Третья и самая основная проблема состоит в потере границ. Посмотрите исходный код модных HTML5 демосцен. Удивлены? Да, никакого хатээмэль там нету, CSS + Javascript на стероидах прекомпиляции (очень современная технология, биспезды!) и аппаратного ускорения. Вам пророчат торжество canvas над сильверлайтом или флешем? Верите? Долбоебы. Для JS не существует ни нормальных библиотек, ни адекватным врапперов, ни внятной документации с примерами для работы с холстом (ага, покурите маны libcanvas и я на вас посмотрю). Верите в миф про световую скорость современных технологий? Посмотрите демки на http://www.c3dl.org/ например, посмотрите загрузку процессора, размер исходного кода и сравните с аналогичными демками на flash. Все еще сомневаетесь? Тогда просто попробуйте написать элементарный пример, трансформацию квадрата обычно, изменение его размеров, прозрачности, вращение и прочее. Сравните потери времени, читаемость кода и получите однозначный и бесповоротный ответ. К тому же JS все же как бы client side. Нет, конечно же и для флеша существуют декомпиляторы, но бывают такие случаи, когда процесс общения клиента с серверной частью не стоит показывать всем и сразу, разве нет?
Мораль сего поста проста: не стоит гнаться за новым, забывая про старое. Я, признаться, сам ужасный противник flash, но отбрасывать эту технологию, которая верой и правдой служила интернету долгое время, без которой мог бы не появиться youtube (да и video html element, как логическое продолжение флеш видео), которая в настоящее время полностью документирована и быстродействие которой в разы выше костылей HTML5 - глупо, как минимум, и технологический популизм для одноклеточных эникейщиков, как максимум.
Added 30.10.2010 Вы только посмотрите, какой резонанс вызвал пост у закомплексованных джедаев браузеров. Чуть девушку не разорвали, а ведь одна она уловила смысл, мужланы вы неотесанные. Зрейте в корень, друзья. Пост был не про технологию, а про "медийный шум" и игре на этом. Но вы молодцы, пенисы у вас длинные и широкие и я рад, что дал вам возможность продемонстрировать это. Радует, что не все, сидя на куче дерьма троне профессионалов, утратили юмор.
В первоначальном варианте сайт выглядел намного круче из-за моего околоманиакального увлечения драфтами css3 в виде transform scale и rotate, border-radius, box-shadow, background rgb и прочих плюшек, но потом я посмотрел на это все не в webkit-овских chrome или safari, которые являются в настоящее время двумя моими основными браузерами, а на обычных пацанских интернет-смотрелках IE, Opera и Firefox последних версий. И если в огнелисе версии 3,7 более-менее работало, хотя и тормозило безбожно, то в первых двух обрубках все выглядело у-жа-с-но. Пришлось еще пару дней потратить на приведение к нормальному адекватному внешнему виду и скорости работы. Вот в такие моменты думаешь, кстати, что монополия в сфере браузеров это не так уж и плохо, особенно когда пытаешься скормить IE7 "a"-ссылку со стилем inline-block, а таких примеров over 9000. Ну и если бы еще W3C шевелился быстрее, превратив черновик в стандарт - вообще отлично было. Может даже бы краснознаменная опера подтянулась. Но это так, мечты-мечты.
На самом деле, я сейчас уже не занимаюсь разработкой сайтов на постоянной коммерческой основе. Если у вас есть какая-либо интересная идея или уникальный концепт на бумаге - пишите мне, помогу реализовать в вебе за "спасибо" или же за коньяк Бучач (5 звезд, возможны варианты Закарпатский, Alexx) в таре 0,5 литра, если это действительно будет интересно и при условии, что меня никто не будет ограничивать, как рамками ТЗ, так и временными лимитами. А вот еще один пример моей работы, я - классный.