Лайм.Телеком, Lime.Telecom

Ошибки молодости или как не надо устанавливать FreePBX.

Для офисных нужд мы используем FreePBX 13 (очень рекомендую всем любителям «Русского языка» пока оставаться на 12 версии, но об этом в другой раз), и вон на днях на почту администратору начали приходить алерты о том, что место на диске сервера с FreePBX заканчивается с катастрофической скоростью. Первым делом грешили на сырую 13 версию, и начали перепроверять всё через «командную строку» (самое ненавистное занятие для убеждённого виндовода).
Свернуть )
Лайм.Телеком, Lime.Telecom

Как мы дружили с ZTE-MF823

Есть в песочнице на Хабре прекрасная статья "Автоматическая работа с SMS на модеме ZTE-MF823" о том как организовать автоматизированную отправку SMS сообщение при помощи модема ZTE-MF823 и PHP (http://habrahabr.ru/sandbox/94841/). Проблема в том что она в песочнице и авторство не указанно и связаться с автором нет возможности.

Поэтому решили дописать небольшое дополнение к этой статье с надеждой что автор её увидит и дополнит свою. Собственно проблема в том что в новых прошивках от полосатых пчеловодов для этого модема, прямое обращение к "goform/goform_set_cmd_process" залочено и модем в ответ вам будет постоянно выдавать "{"result":"failure"}".

Но блокировка оказалась проста и реализованна первым что приходит в голову - это проверка рефера :) Поэтому к коду автору требуется добавить:

curl_setopt($ch, CURLOPT_REFERER, 'http://'.$this->ip.'/index.html');

в любое место функции "function url($url,$post="")".
Лайм.Телеком, Lime.Telecom

Как всем офисом перейти на LibreOffice (Часть 1 "Как всё было хорошо первые два часа").

Задача: И так вдохновившись статьями с небезызвестного ИТ ресурса о том что новый LibreOffice (LO) можно наконец использовать в работе без вероятности системному администратору слечь в сумасшедший дом. Было принято "эпохальное решение" всем офисом отказаться от платного Microsoft Office (MO) и перейти на бесплатный LibreOffice 4.4.1.2 (как мы уже выяснили в предыдущей статье, версия программы иногда оказывает решающее значение).

Реализация: Для начала небольшое отступление, почему мы решили отказаться от MO и почему вы можете повторить наш путь если ваша компания удовлетворяет следующим условиям:
1. Мы не интегрированы в продукты Microsoft. MO у нас используется исключительно для целей набрать исходящее письмо, распечатать договор (об этом чуть подробнее будет ниже), открыть таблицу или текстовый документ присланный от партнёров, подготовить приказ по предприятию и т.п.
2. Мы небольшая компания где все друг друга знают и находятся в шаговой доступности. Поэтому перевести всех и разом оказалось дело 30 минут (время на установку LO на всех машинах в офисе).
3. У нас "синусоидальный" режим нагрузки на сотрудников офиса. То есть в нашем рабочем месяце (где то с 10 по 20 число) количество работы минимальное и мы можем себе позволить всё сломать и построить заново и на это у нас есть 10 дней.

И так часть первая "Как всё было хорошо первые два часа":
[Хотите узнать почему, читаем дальше...]Установка офиса задача простая и подробно на ней останавливаться не будем, в общих чертах MO удалили, LO поставили. Во время установки поставили галочку чтобы LO загружался в месте с системой (заметно ускоряет запуск приложений).

Сразу после установки всё было прекрасно, старые doc и xls открываются без проблем, с мелкими незначительными нарушениями в разметке. Что самое интересное открывались без особых проблем и новые форматы MO docx и xlsx.

Интерфейс интуитивно понятный, а те кто застал MO 2003 сразу приступили к работе на задавая никаких вопросов, одно "но" заранее договоритесь со всем коллективом использовать одни и те же иконки в интерфейсе (в LO их можно выбирать по вкусу), так как иначе вы рискуете попасть в ситуацию когда один сотрудник пытается объяснить другому как выглядит иконка "Поиск и замена" а тот его не понимает. Лично мне "работа напильником" а именно выравнивание таблиц, текстов установка отступов, показалась более приятной и "однозначной" чем в MO.

Всё было прекрасно и замечательно до момента пока один из сотрудников не решил распечатать договор на очередного абонента. Тут небольшое пояснение как у нас формируется договор: мы оператор связи у нас есть сертифицированное ядро учёта абонентов и управления ими, поверх этого ядра нами написана удобная CRM (Система управления взаимоотношениями с клиентами) на PHP, она автоматически формирует текст договора в формате HTML, получая данные из карточки абонента. Браузеру договор в формате HTML посылается с волшебными заголовками, заставляющими его думать что ему предлагают скачать файл odt (изначально было doc), вот как это выглядит в коде:

header("Content-Type: application/vnd.oasis.opendocument.text");
header("Expires: 0");
header("Cache-Control: no-cache");
header("content-disposition: attachment;filename=rosnet_contract_".$ab_dog_uni_sv.".odt");
print '<html>
<head> далее идёт сам договор...


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

Пока у нас был MO вся эта отлаженная процедура прекрасно работала, как выяснилось позже потому что MO допускает боле вольное трактование HTML разметки (более продвинут в познаниях HTML если перефразировать). В противовес ему LO оказался боле придирчив и прекрасно оформленный и размеченный договор "развалился по швам" при очередной попытке его сформировать. Что же случилось, разбираем по пунктам:

1. Все стили шрифтов, таблиц и параграфов в нашем договоре подгружались из отдельного CSS файла, с LO такая конструкция не пройдёт и даже больше вы не сможете заставить его переварить стили заключив их непосредственно в теле и окружив тегами:

<style></style>

Единственно что позволит вам LO это указать там параметры полей и body. Собственно этим мы и воспользовались и написали "кроссофисный" стиль оформления отступов полей (его понимает и MO и LO):

<style type="text/css">
@page WordSection1{
margin-top:1cm;
margin-left:2cm;
margin-right:1cm;
margin-bottom:1cm;
}
div.WordSection1{
page:WordSection1;
}
</style>

Ну и соответственно весь договор надо завернуть в DIV с калассом WordSection1:

<body><div class=WordSection1> Текст договора </div></body>

А остальные стили нужно прописывать в каждой ячейке, каждом параграфе, в каждом DIV-е, только тогда LO начинает их честно обрабатывать. Однако не расслабляйтесь как выяснилось экзотические стили которые понимал MO не всегда понимает ("правильно") LO, но для формирование договора в большинстве случаев вы с этим не столкнётесь.

2. Ну а теперь самое интересное что собственно и сподвигло нас к написанию этого поста, рассказ о том как логотип нашей компании остановил работу этой самой компании на двое суток.

Разобравшись что LO корректно принимает стили заключенные только в конструкцию "style=", мы продолжили переделывать исходный код договора и всё шло прекрасно пока не дошли до таблиц. Они с упорством древнегреческих героев не воспринимали заданные поля документа и выползали далеко за них. Что самое интересное из двух таблиц с одинаковым стилем первая всегда упералась в поля (width=100%) а вторая вываливалсь за них.

Вот так это выглядит:
1

У тех кто не первый год в HTML сразу подозрение что гдето не закрыт тэг, но многочасовые поиски и создание пустых бланков без текста и только с таблицами доказывали что все теги закрыты. И так шли вторые сутки поиска что именно влияет на расползание 2-3 таблицы в документе. Открывался чистый документ вручную создавались несколько таблиц, вставлялся текст, всё это сохранялось в HTML и открывалось редаторами для поиска святого грааля, которого нехватает в нашем коде.

В конце вторых суток грааль был обнаружен. Как мы уже упоминали выше - это тэг ставки изображения с логотипом. Если его убирали из когда все таблицы возвращались на нужные места. Как он выглядел:

<td width="50%" height="55px" valign="top" align="left">
<img src="https://****.ru/****_data/img/doc_logo.png" width="200" height="45" border="0">
</td>


Ну как видите что либо подозрительное, а LO видит, и видит он отсутствие заданного выравнивания картинки а именно align="left", хотя в теге ячейки таблицы выравнивание по левому краю указанно. Меняем наш код на:

<td width="50%" height="55px" valign="top" align="left">
<img src="https://****.ru/****_data/img/doc_logo.png" width="200" height="45" align="left" border="0">
</td>

Результат:
2

Как выравнивание изображения в траблице на уровень выше влияет на таблицу на уровень ниже, так и осталось загадкой.

Лайм.Телеком, Lime.Telecom

Стабильное вещание с IP-камеры на сайт 24х7 (без Linux).

Задача: организовать вещание с китайской IP камеры на корпоративном сайте в формате 24х7, с использованием как можно меньшего количества узлов отказа (как это уже работает у нас http://amurnet.ru/web/web_stream.php).

Реализация:
В своё время уже приходилось строить подобную систему, и воспоминания были только негативные, то стример повиснет то камера, от того что зависла камера опять завис стример и т.д. Что больше всего раздражало что в сети куча пошаговых мануалов и у всех всё работает (правда уже тогда заметил что у всех немного разные конфиги). И вот спустя годы, аналогичная задача расставила всё на свои места, всё дело оказалось в многочисленных версиях используемого ПО.

И так что нам понадобится:
1. Неттоп, Десктоп, Сервер с установленной системой Windows (В нашем варианте это был Неттоп на Intel Atom D525 1.8, со свежеустановленной Windows 7 Home Basiс, встроенной видеокартой и сетевой картой Realtek).
2. VLC 2.1.5 (вот тут первый важный момент, нам нужна строго эта версия http://download.videolan.org/pub/videolan/vlc/2.1.5/win32/vlc-2.1.5-win32.exe).
3. Китайская IP-камера (или любая другая камера, которая отдаёт RTSP поток с кодеком H.264, что собственно делают 90% IP-камер среднего ценового диапазона).
4. Flowplayer 3.2.18 (тут второй важный момент качаем версию https://releases.flowplayer.org/flowplayer/flowplayer-3.2.18.zip).

[Если вам интересно, читаем дальше...]Собираем:
1. Настройка системы:
1.1. Заходим: Пуск\Панель управления\Все элементы панели управления\Электропитание там выбираем Сбалансированный план и заходим в его настройки. В настройках отключаем Выключение дисплея и Переход в спящий режим.
1

1.2. На диске С: создаём папку с именем VLC.
1.3. Если вы установили пароль для основного пользователя, нужно настроить автовход в систему при загрузке. Для этого нажмите Пуск и в строке поиска введите netplwiz, запустите найденное приложение. Уберите в нём галочку Требовать ввода имени пользователя и пароля, и нажмите кнопку Применить. После этих действий если потребуется перезагрузить сервер вам не потребуется подключатся к нему для запуска VLC.

2. Устанавливаем и настраиваем VLC.
2.1. Заранее скаченную версию VLC 2.1.5 запускаем на стандартную установку. Если у вас стояла другая версия VLC в процессе установки поставьте галочку очистить настройки и кеш.
2.2. После завершения процесса установки запускаем VLC и при первом запуске, снимаем галочки о получении данных и обновлений из сети.
2.3. Условимся что вы заранее выяснили как получить RTSP поток с вашей камеры используя RTSP ссылку. В нашем случае она выглядит так rtsp://192.168.11.1:554/user=admin&password=admin&channel=1&stream=0.sdp.
2.4. На данном этапе проведём первую проверку. Запустите VLC плеер, нажмите Медиа/Открыть URL... в появившемся окне вставьте в поле сетевой адрес RTSP ссылку от потока камеры.
2

2.5. Нажмите кнопку Воспроизвести и вы должны увидеть видео с камеры, чёткое без задержек и артефактов (для того что бы на более поздних этапах уже точно знать что на связке камера - сервер все хорошо).
2.6. Закройте VLC.
2.7. Зайдите в папку C:\VLC (созданную в пункте 1.2). Создайте там текстовый файл start_vlc.txt. В эту же папку скопируйте ваш логотип для трансляции в формате PNG и переименуйте его в LOGO.png.
2.8. Откройте созданный файл start_vlc.txt. Вставьте туда следующий код:

start /D "C:\Program Files\VideoLAN\VLC\" vlc.exe "rtsp://192.168.11.1:554/user=admin&password=admin&channel=1&stream=0.sdp" --sout #transcode{vcodec=FLV1,acodec=none,scale=0.5,vb=2048,sfilter={logo{file=C:\VLC\LOGO.png,x=10,y=10,opacity=200}}}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=192.168.11.2:8088/stream.flv} --rtsp-caching=5000 --http-caching=5000 --loop

2.9. Разберём по пунктам:
2.9.1. start /D "C:\Program Files\VideoLAN\VLC\" vlc.exe "rtsp://192.168.11.1:554/user=admin&password=admin&channel=1&stream=0.sdp" - запустить VLC и открыть RTSP поток с камеры.
2.9.2. vcodec=FLV1, acodec=none - пакуем полученный поток в видеокодек FLV1 (можно попробовать H264 но он потребляет в 3-4 раза больше ресурсов процессора и Intel Atom тут уже не хватит), аудиокодек не используем так как наша камера "глухая".
2.9.3. scale=0.5,vb=2048 - вот это одна из главных записей в конфигурации и тут нужно остановится подробнее. VLC кодирует в FLV используя ffmpeg и в разных сборках VLC он разный, именно поэтому мы особое внимание обращали на версию VLC (на момент написания этой статьи вышел VLC 2.2.0 где параметр scale уже не работает). Теперь подробнее о параметрах, наша камера вещает с разрешением 1280х720 (битрейт 4 Мегабита/с) это много для вещания в сеть, поэтому мы уменьшаем разрешение в два раза до 640х360 (битрейт 1-1.3 Мегабита/с в зависимости от времени суток). Тогда вопрос зачем мы задаём битрейт параметром vb=2048 - всё просто: если не прописать это значение (число может быть любое больше единицы) то ffmpeg будет очень сильно сжимать качество потока и вы будете наблюдать квадратные артефакты на всём изображении в независимости от разрешения.
2.9.4. sfilter={logo{file=C:\VLC\LOGO.png,x=10,y=10,opacity=200}} - это пункт вставки вашего логотипа в видео. Очень рекомендую не отказываться от этой процедуры, так как охотников выдать вашу трансляцию за свою будет очень много. x=10,y=10 - это отступ от левого верхнего угла. opacity=200 - это прозрачность логотипа (1 прозрачный, 255 не прозрачный).
2.9.5. std{access=http{mime=video/x-flv} - доступ к транскодированному потоку будет по протоколу http, mime тип контента video/x-flv.
2.9.6.
dst=192.168.11.2:8088/stream.flv - в этой строке указан IP адрес интерфейса на котором будет подниматься поток вещания на порту 8088 (IP адрес сетевой карты Неттопа/Десктопа/Сервера).
2.9.7. --loop - так же один из важных параметров. Всё дело в том что камера с которой мы принимаем поток может периодически виснуть и перегружаться, при этом без этого параметра VLC будет останавливать транскодинг. Параметр loop заставляет перебирать плейлист VLC по кругу и в нашем случае в случае потери потока с камеры, VLC будет пытаться его получить снова и снова.
2.10. Сохраняем файл start_vlc.txt и закрываем его.
2.11. Меняем расширение файла start_vlc.txt на start_vlc.bat.
2.12. Запускаем файл start_vlc.bat. Должен запустится VLC. Для проверки что транскодинг работает, зайдите в Инструменты/Информация о кодеке. В поле Битрейт должна отображаться скорость входного потока.
3

2.13. Закройте Информацию о медиаисточнике. На этом этапе VLC можно свернуть.
2.14. Создайте ярлык для файла start_vlc.bat и поместите его в Пуск/Автозагрузка (системы Windows). Конечно в сети не мало способов запустить VLC в виде сервиса, но испытав их на практике вы поймёте с запуском из командной строки гораздо проще менять конфигурацию "на лету" и отслеживать работу самого VLC.

3. Создаём страницу на веб-сервере.
3.1. Принимаем во внимание что у вас уже собран веб сервер и он имеет доступ к камере. В нашем случае как вы уже наверно догадались камера и транскодер на базе VLC находятся за NAT-серверов, на котором настроен проброс портов. Без экзотики порт 8088 вешнего IP адреса 62.33.***.*** NAT-сервера преобразовывается на порт 8088 локального IP адреса транскодера 192.168.11.2.
3.2. На веб-сервере создаём отдельный папку stream для страницы плеера. В этой папку создаём ещё одну папку js для скриптов.
3.3. Открываем скаченный архив с Flowplayer 3.2.18, копируем файлы flowplayer.controls-3.2.16.swf, flowplayer-3.2.13.min.js, flowplayer-3.2.18.swf в папку на веб-сервере stream/js.
3.4. В папке stream создаём два файла index.txt и stream.txt.
3.5. Открываем index.txt и вставляем в него следующий код:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Моя камера</title>
<meta name="" content="">
</head>
<body>
<center><iframe src="stream.html" width="640" height="360" border="0" frameborder="no"></iframe></center>
</body>
</html>


3.6. Тут снова небольшое пояснение собственно кодом вставки (который вы будете раздавать своим друзьям или другим владельцам сайтов) видео с камеры на любой сайт будет <center><iframe src="stream.html" width="640" height="360" border="0" frameborder="no"></iframe></center>. Всё дело в том что "мир не стоит на месте" и самый простой способ моментально внести изменения в вашу будущую трансляцию у всех ваших коллег это использовать iframe и хранить код самого плеера у вас на сервере. Естественно в место stream.html будет полный адрес до вашего веб-сервера.
3.7. Сохраняем файл index.txt и закрываем его.
3.8. Открываем stream.txt и вставляем в него следующий код:

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Cache-Control" content="no-cache">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<script type="text/javascript" src="js/flowplayer-3.2.13.min.js"></script>
<style type="text/css">
html, body { height:100%; overflow:hidden; }
body { margin:0; }
</style>
</head>
<body>
<a href="http://62.33.***.***:8088/stream.flv" style="display:block;width:100%;height:100%" id="player"></a>
<script>
flowplayer("player", "js/flowplayer-3.2.18.swf", {
clip: {
autoPlay: false,
scaling: 'fit',
autoBuffering: true,
live: true
},
canvas: {
background: '#000000',
backgroundGradient: 'none'
},
plugins: {
controls: {
url: "js/flowplayer.controls-3.2.16.swf",
buttonColor: '#FFFFFF',
buttonOverColor: '#FFFFFF',
backgroundColor: '#000000',
backgroundGradient: 'none',
height: '30',
opacity: '0.6',
all: false,
play: true,
fullscreen: true
}
}
});
</script>
</body>
</html>

3.9. Тут тоже уточняем. Это код вставки Flowplayer с отключенными лишними кнопками временной полосой и т.д. Вместо http://62.33.***.***:8088/stream.flv нужно вставить адрес вашего NAT-сервер или напрямую адрес транскодера если вещание будет только в локальной сети.
3.10. Закрываем файл
index.txt и закрываем его.
3.11. Меняем расширения обоих файлов
index.txt и stream.txt на index.html и stream.html соответственно.
3.12. Открываем файл index.html на вашем веб-сервер и наблюдаем видео.
4