ОсновноеRadiotalkПользовательское
Общие вопросы по интернет радио вещанию
7   •   Посмотреть все темы

Графическая география слушателей (icecast)

 

468
Klef @Klef
Сначала хотел описать настройку жидкого мыла, по шагам, чтоб он умел танцевать джигу, выводить ведущих и варить кофе, но в ********** все давным давно описано, так что пройдем по извращениям.

Итак дорогой дружок, сейчас я научу тебя делать модною динамическую картинку для своего сайта, с отображением географии ваших радиослушателей. Вот такого рода:

Внимание: текущая картинка статичная, что бы не афишировать радиостанцию.

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

Итак, у нас есть боевой сервер icecast2 который радостно вещает на ваши сотни слушателей (ну или на пару друзей), если зайти в админку его, в раздел List Mountpoints, в нем посмотреть любой ваш маунт, то там можно увидеть список слушателей поименно ip, клиент, время подключения.
Важно: у вас должен быть доступ к админке icecast
Но как вы поняли эту информацию уже можно обрабатывать как угодно (например бы генерить карту гугла с метками). Но мы же хитрые телом, поэтому будем сами генерить карту, для этого нам понадобиться старая, добрая php-шная библиотека GD, если вы не забыли мы с ней уже **********. Ну и одна из самых важных частей, это база **********

Ну обо всем по порядку.

Во первых нам понадобится карта, на которой мы будем рисовать всякие пошлости. Но любая карта не подойдет, нам понадобиться карта в определенных пропорциях.
Например эта подойдет:


А эта уже нет:


Разницу думаю увидите сами. Самый грамотный способ, это нарисовать (или кого заставить) нарисовать карту в нужном вам графическом оформлении в соответствующих пропорциях (смотри пример), либо найти в интернете, но первый способ лучше ;)

база GeoIP, есть ********** для php, но он у меня вероломно отказался работать, так что воспользуемся "**********" набором скриптов от maxmind'a, которые и будем подключать к нашему скрипту.
Качаем чистое, располагаем в удобном месте, и подключаем в начале скрипта
  1. include ("geoipcity.inc");

Так же кроме собственно скриптов, которые работают с данными GeoIP нам собственно понадобиться бинарная база GeoIPCity, но так как она платная, а те что есть в свободном доступе малость уже устарели, то берем на офф сайте ********** для наших нужд ее хватит, но а для большего шика можно использовать пару баз: полную, но старую (найденную в свободных источниках (линки не дам, ищите)), и легкую, но крайнюю версию.

Для особо продвинутых пользователей рекомендую закинуть в крон скрип, который будет рахз в месяц (числах в 5-х) скачивать крайнюю версию с офф сайта.
Типа такого:
  1.  
  2. #!/bin/sh
  3. cd /tmp
  4. fetch **********
  5. gunzip GeoLiteCity.dat.gz
  6. mv -f GeoLiteCity.dat /usr/local/share/GeoIP
  7. chmod 644 /usr/local/share/GeoIP/GeoLiteCity.dat

команды для скачивания и разархивирования рекомендую использовать привычные вам.

Перед тем как переходить к финальной стадии написания кода поделюсь с вами скриптом, который будет нам устраивать общение с icecast, да, я ленивая скотина, и не стал писать данный кусок кода а нашел на офф форуме icecast.
Автор данного кода W. Herrmann, о чем моно и прочитать в этом коде.
**********

Итак мы подготовились, карта, база GeoIP, php модули GeoIP, скрипт icecast.class разархивированы и расположены в удобном вам месте, вы вспомнили/узнали пароль от админки то можно приступать к самому интересному и фкусному, делаем скрипт генерации карты.

Дальше следует поток кода с комментариями:

  1.  
  2. <?php
  3. error_reporting(1);
  4. //сообщаем, что на выходе будет нет текст, а графика
  5. header ("Content-type: image/png");
  6. //подключаем внешнии скрипты
  7. include("icecast.class.php");
  8. include ("geoipcity.inc");
  9. //создаем клас к которому будем обращатся
  10. $icecast = new icecast();
  11. //имя шрифта, надеюсь вы не забыли про него?
  12. $font="ft.ttf";
  13. //список маунтов, которые чекаються
  14. $mount[]="radio";
  15. $mount[]="music";
  16. $mount[]="autorj";
  17. //размер карты по ширине, т.к. мы работаем с координатами, то пропорции карты должны быть 360х180
  18. //остальные параметры, зависащии от размеров, расчитываються
  19. $glob_x=900;
  20. $glob_y=$glob_x/2;
  21. $koeficent=$glob_x/360;
  22. //начинаем опрашивать маунта, ничто не мешает крутить по циклу и список серверов
  23. //думаю параметры (хост, логин и пароль админки вы уже увидели куда вбивать)
  24. for ($nom_mount=0;$nom_mount<count($mount);$nom_mount++) {
  25. $icecast->host = "127.0.0.1";
  26. $icecast->port = 8000;
  27. $icecast->mount = $mount[$nom_mount];
  28. $icecast->user = "admin";
  29. $icecast->passwd = "hackme";
  30. //запрашиваем нужные нам параметры
  31. if ($icecast->openstats()) {
  32. if ($icecast->GetStreamStatus()) {
  33. $listeners = $icecast->GetListeners();
  34. //если массив списка слушателей получен, то сортируем его (сортировать не обязательно)
  35. if (is_array($listeners)) {
  36. sort($listeners);
  37. //обходим и записываем в массив IP адреса
  38. for ($i=0;$i<sizeof($listeners);$i++) {
  39. //массив $ip =)
  40. $ip[] = $listeners[$i]["ip"];
  41. }
  42. }
  43. }
  44. }
  45. }
  46. //подключаемся к БД GeoIP
  47. $gil = geoip_open("/usr/local/share/GeoIP/GeoLiteCity.dat", GEOIP_STANDARD);
  48. $gif = geoip_open("/usr/local/share/GeoIP/GeoIPCity.dat", GEOIP_STANDARD);
  49. //создаем первый "нулевой" элемент массивов координат
  50. $array_coo[]="0,0";
  51. $array_col[]=0;
  52. //счетчик всего слушателей
  53. $all=0;
  54. //максимальное количество слушателей на координату
  55. $maxal=0;
  56. //опять сортруем и начинаем переберать результат
  57. sort($ip);
  58. for ($z=0;$z<count($ip);$z++) {
  59. //сначало запрос к лайту, получаем координаты
  60. $geoip = GeoIP_record_by_addr($gil,$ip[$z]);
  61. //операция с коэфицентом карты (по отношению к 360) делаем чтоб в масиве у нас хранились округленные значения
  62. $ipx=round(($geoip->latitude)*$koeficent)/$koeficent;
  63. $ipy=round(($geoip->longitude)*$koeficent)/$koeficent;
  64. //на всякий пожарный ^_^
  65. $ipx=$ipx*1;
  66. $ipy=$ipy*1;
  67. //если лайт база нам вернула не очень интересные данные, нулевые координаты, или же неизвестный кород, то координаты "фейковый" (с точности до страны)
  68. if ((($ipx==0) and ($ipy==0)) or (strlen($geoip->city)==0)) {
  69. //тогда делаем запрос к полной базе (не забыли ее найти?)
  70. $geoip = GeoIP_record_by_addr($gif,$ip[$z]);
  71. //к ней работаем так же как и с лайт
  72. $ipx=round(($geoip->latitude)*$koeficent)/$koeficent;
  73. $ipy=round(($geoip->longitude)*$koeficent)/$koeficent;
  74. $ipx=$ipx*1;
  75. $ipy=$ipy*1;
  76. }
  77. //причем в массиве храним строку с долготой и широтой сразу, через запятую
  78. $coord=$ipx.",".$ipy;
  79. //ищем полученную координату в массиве координат, зачем нам создавать новый элемент, если с такими координатами уже есть
  80. $pnom=array_search($coord,$array_coo);
  81. if ($pnom==FALSE) {
  82. //не нашли, тогда создаем
  83. $array_coo[]=$coord;
  84. $array_col[]=1;
  85. if ($maxal<1) {$maxal=1;}
  86. } else {
  87. //нашли, тоже отлично, увеличиваем кол-во слушателей в этой точке
  88. $array_col[$pnom]++;
  89. //заодно проверяем это максимум тут или как
  90. if ($maxal<$array_col[$pnom]) {$maxal=$array_col[$pnom];}
  91. }
  92. $all++;
  93. }
  94. //закрываем базы GeoIP дабы они нам более не требуються
  95. geoip_close($gil);
  96. geoip_close($gif);
  97. //создаем png для работы из нашей карты
  98. $img=imagecreatefrompng("map.png");
  99. //выбираем цвет чернил, которыми будем рисовать
  100. $ink = imagecolorallocate($img, 0, 0, 0);
  101. //и перебираем массив координат
  102. for ($i=0;$i<count($array_coo);$i++) {
  103. //если в координате 0 слушателей, то не обрабатываем
  104. if ($array_col[$i]!=0) {
  105. //узнаем размер кружка
  106. //у меня тут по хитрому, все кружки пропорциональны относительно самого большого
  107. //кому не нравиться данная идея, используйте свой принцып
  108. //$kolb это диаметр кружка
  109. //для более гармоничного круга диаметр делайте кратным двум
  110. $kolb=round($array_col[$i]*10/$maxal)*2+1;
  111. //теперь нам больше не нужна запятая в координатах, разбираем на два элемента (широта и долгота)
  112. $arc=split(",",$array_coo[$i]);
  113. //соотвественно полученные координаты умножаем на коофицент, для более гармоничного рамположения на карте
  114. $arc[0]=$arc[0]*$koeficent;
  115. $arc[1]=$arc[1]*$koeficent;
  116. //т.к. 0 на графике в левов верхнем, то творим еще и такие подсчеты
  117. $smesh_x=$glob_x/2;
  118. $smesh_y=$glob_y/2;
  119. //рисуем таки кружок IMG_ARC_PIE - значит, что будет заливка
  120. imagefilledarc($img,$smesh_x+$arc[1],$smesh_y-$arc[0],$kolb,$kolb,0,360,$ink,IMG_ARC_PIE);
  121. }
  122. }
  123. //рисуем всякие надписи
  124. imagettftext($img,8,0,20,20,$ink,$font,"Special 4 radiotalk");
  125. imagettftext($img,8,0,20,36,$ink,$font,"GeoIP");
  126. imagettftext($img,8,0,20,52,$ink,$font,"listeners: ".$all);
  127. //у меня сервер по гринвичу. А у вас?
  128. $dat=date("n/j/24y g:ia",time()+14400);
  129. $mr=imagettfbbox (8,0, $font, $dat);
  130. imagettftext($img,8,0,$glob_x-20-$mr[2],22,$ink,$font,$dat);
  131. //черестрочный формат, не помешает
  132. imageInterlace($img, 1);
  133. //отдаем пользователю
  134. imagepng($img);
  135. //уничтожаем следы жизнидеятельности
  136. imagedestroy($img);
  137. ?>


Результат работы кода:


Ну и традиционно: данный код лишь направление в котором следует изучать этот вопрос. Это базовый код. Много чего можно и нужно добавить. Так же каждый желающий может написать свой код, более оптимизирован, более красивый.

0
468
Klef @Klef
Еще насчет GeoIP
Точность Lite версии **********

0
30
Alexander @Alexander_Sizintsev
Klef пишет:

Еще насчет GeoIP
Точность Lite версии **********


что-то я попыался сделать, хрен что получилось... вот **********

0
30
Alexander @Alexander_Sizintsev
как лечить напасть?

0
6245
Тарас @tarasian666
у вас проблемы с генерированием изображения, точнее там вообще ничего не сгенерировалось, смотрите лог ошибок

0
30
Alexander @Alexander_Sizintsev
tarasian666 пишет:

у вас проблемы с генерированием изображения, точнее там вообще ничего не сгенерировалось, смотрите лог ошибок


Судя по логу, ошибка в 46 строке.

И вот что это:

//подключаемся к БД GeoIP
$gil = geoip_open("/usr/local/share/GeoIP/GeoLiteCity.dat", GEOIP_STANDARD);
$gif = geoip_open("/usr/local/share/GeoIP/GeoIPCity.dat", GEOIP_STANDARD);


Наверное у меня на хостинге другой путь к файлам

0
6245
Тарас @tarasian666
а конкретно что пишет ошибка?

0
30
Alexander @Alexander_Sizintsev
tarasian666 пишет:

а конкретно что пишет ошибка?



[08-Oct-2012 12:14:19] PHP Fatal error: Call to undefined function geoip_open() in /php/geo/index.php on line 46

0
6245
Тарас @tarasian666
в php не включено или не установлено расширение geoip

0
30
Alexander @Alexander_Sizintsev
tarasian666 пишет:

в php не включено или не установлено расширение geoip


да вот в том-то и дело, что сказали что поставили =/

0
6245
Тарас @tarasian666
значит или не активировали или не перезапустили сервер после этого, так всегда )

0
30
Alexander @Alexander_Sizintsev
Вопрос есть: а эти GeoLiteCity.dat, GeoIPCity.dat устанавливаются вместе с расширением GeoIP???

0
6245
Тарас @tarasian666
вместе с geoip, но это не проблема, можно их самому скачать куда угодно

0
30
Alexander @Alexander_Sizintsev
tarasian666 пишет:

вместе с geoip, но это не проблема, можно их самому скачать куда угодно


А можете подсказать где скачать? ссылка на одну есть, а вот на вторую что-то нету =(

0
6245
Тарас @tarasian666
Для особо продвинутых пользователей рекомендую закинуть в крон скрип, который будет рахз в месяц (числах в 5-х) скачивать крайнюю версию с офф сайта.


и ниже код и ссылка

0
30
Alexander @Alexander_Sizintsev
tarasian666 пишет:

Для особо продвинутых пользователей рекомендую закинуть в крон скрип, который будет рахз в месяц (числах в 5-х) скачивать крайнюю версию с офф сайта.


и ниже код и ссылка


Блин что-то нихрена не выходит вообще =(

0
6245
Тарас @tarasian666
тогда учить мат часть )

0
30
Alexander @Alexander_Sizintsev
tarasian666 пишет:

тогда учить мат часть )


Я тебя умоляю...

Странно почему не пашет... =/ ладно тогда как хостер появится попробую решить =)

0
6245
Тарас @tarasian666
если ошибка прежняя - мучить хостера, если что то типа syntax error или not fount тогда искать причину

0
30
Alexander @Alexander_Sizintsev
tarasian666 пишет:

если ошибка прежняя - мучить хостера, если что то типа syntax error или not fount тогда искать причину



Это понятно. спс за помощь...

0





Согласие на обработку данных на нашем сайте

Продолжая просматривать страницу, вы соглашаетесь с использованием файлов «Cookie» и с Политикой конфиденциальности «Privacy».
Наверху или внизу страницы вы можете изменить валюту и язык по умолчанию. Английская версия сайта ещё находится в доработке и доступна не полностью.