Jakiś czas temu pojawiły się dość tanie i fajne pod względem jakości obrazu kamery UBNT AirCam. Postanowiłem je wykorzystać do mini-monitoringu a obraz transmitować na naszą stronę. Jest jednak problem: jak to zrobić? Popularne skrypty czy aplety Javy, mimo iż są banalne w konfiguracji i nie potrzebują nic po za dostępem do kamery, są dość nieekonomiczne i niezbyt bezpieczne. Nieekonomiczne gdyż przeglądarka klienta łączy się bezpośrednio z kamerą pobierając obraz wprost z niej co przy większej ilości połączeń może kamerę „zabić”. Większość kamer CCTV posiada ograniczenie jednoczesnych klientów do no 40 co jeszcze bardziej pogarsza sprawę. Druga kwestia to bezpieczeństwo – adres kamery (i wszystko co się z tym wiąże) jest przekazywany do wszystkie odwiedzających stronę z obrazem co chyba nie jest dobrym pomysłem. Oczywiście są systemy retransmisyjne popularnie zwane streamingowymi (jaki ładny polski wyraz) ale większość z nich jest płatna. Do tego tematu wrócimy nieco dalej.
Jak napisałem wcześniej obraz z kamery można pobrać za pomocą prostego appletu Javy takiego jak poniżej:
<html> <head> <script src="/javascripts/jquery.js" type="text/javascript"></script> </head> <body> <center> <APPLET CODE=LoadJpg.class ARCHIVE=loadjpg.jar name=NCApplet WIDTH=320 HEIGHT=260 CODEBASE = http://adres_ip_kamery7:port/web/> <PARAM NAME=FPS VALUE=30> <param name=ImageTransferPort value=10000> <param name=ID value=id_usera> <param name=PASSWORD value=haslo_usera> <param name="VER_FLIP" value="1"> <param name="HOR_FLIP" value="1"> </APPLET> </center> </body> </html>
Forma i sposób proste jednak wydajność całkowicie uzależniona od kamery oraz łącza jakim ona dysponuje. W starych i prostych modelach kamer często jedyna opcja. Nowe modele oferują coś takiego jak transmisję strumieniową za pomocą protokołu np: RTSP (Real Time Streaming Protocol), którego zadaniem jest sterowanie dostarczaniem danych czasu rzeczywistego przy współpracy z innym protokołem np. RTP (Real Time Protocol). Nie wchodząc w szczegóły informatyczne protokołów (bo kogo to obchodzi?) dzięki takiemu rozwiązaniu obraz, inaczej mówiąc strumień z danymi video lub audio/video, możemy odbierać z kamery i wyświetlać w odpowiednim oprogramowaniu. Może to być dedykowany soft producenta kamery, może to być wtyczka na stronie WWW a także któryś z wielu dostępnych tzw. playerów. Za przykład niech posłuży bardzo popularny VLC Media Player. Program ten, jak wiele innych, umożliwia pobieranie obrazu wprost z kamery właśnie za pomocą RTSP. Użycie jest banalne: z menu Plik wybieramy otwórz strumień w sieci (lub naciskamy CTRL-N) i w oknie Sieć w pasu adresu wpisujemy:
rtsp://adres_ip_kamery:port_strumieniowania/nazwa_strumienia
gdzie adres_ip_kamery to bezpośredni adres kamery o ile takowy ma lub adres routera z odpowiednio przekierowanym portem ( o tym w innym poście), port_strumieniowania to port pod jakim dostępny jest strumień a jego wartość zależy od ustawień kamery czy też routera za jakim ona pracuje (najczęściej jest to port 554) a ostatni parametr jest już ściśle zależny od modelu kamery o może nazywać się różnie np. live1.sdp. Jako przykład niech posłużą kamery UBNT AirCam oraz Vivotek IP8332:
rtsp://adres_ip:554/live/ch02_0 rtsp://adres_ip:554/live4.sdp
Jak widać dostęp do samego strumienia jest różny w zależności od producenta i modelu kamery – wszystko jest zawsze w dokumentacji oraz zapewne w oprogramowaniu samej kamery. OK co z tego i co to ma wspólnego z transmisją obrazu na stronę WWW? Otóż jest to kolejny sposób na uruchomienie transmisji do strony WWW ale także sposób na prosty podgląd obrazu z kamery bez instalacji specjalnego oprogramowania dedykowanego dla danego modelu kamery. Większość z nas ma już zainstalowany jakiś player, który obsługuje transmisję RTSP. Jest to także krok w stronę systemu retransmisyjnego, o czym za chwilkę a teraz prosty sposób na wstawienie obrazu z takiej kamery na stronę WWW. Wystarczy kilka linii kodu i obraz już pojawia się w naszym serwisie internetowym:
<html> <body> <object classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701" height="480" id="NSPlay" style="LEFT: 0px; TOP: 0px" type="application/x-oleobject" width="640" standby="Loading Microsoft Windows Media Player components..."> <param name="AudioStream" value="-1"> <param name="AutoSize" value="0"> <param name="AutoStart" value="-1"> <param name="AnimationAtStart" value="0"> <param name="AllowScan" value="-1"> <param name="AllowChangeDisplaySize" value="-1"> <param name="AutoRewind" value="0"> <param name="Balance" value="0"> <param name="BaseURL" value=""> <param name="BufferingTime" value="5"> <param name="CaptioningID" value=""> <param name="ClickToPlay" value="-1"> <param name="CursorType" value="0"> <param name="CurrentPosition" value="-1"> <param name="CurrentMarker" value="0"> <param name="DefaultFrame" value=""> <param name="DisplayBackColor" value="0"> <param name="DisplayForeColor" value="16777215"> <param name="DisplayMode" value="0"> <param name="DisplaySize" value="4"> <param name="Enabled" value="-1"> <param name="EnableContextMenu" value="-1"> <param name="EnablePositionControls" value="-1"> <param name="EnableFullScreenControls" value="0"> <param name="EnableTracker" value="-1"> <param name="Filename" value="rtsp://<i.p.c.a.m>:554/live/ch01_0"> <param name="InvokeURLs" value="-1"> <param name="Language" value="-1"> <param name="Mute" value="0"> <param name="PlayCount" value="1"> <param name="PreviewMode" value="0"> <param name="Rate" value="1"> <param name="SAMILang" value=""> <param name="SAMIStyle" value=""> <param name="SAMIFileName" value=""> <param name="SelectionStart" value="-1"> <param name="SelectionEnd" value="-1"> <param name="SendOpenStateChangeEvents" value="-1"> <param name="SendWarningEvents" value="-1"> <param name="SendErrorEvents" value="-1"> <param name="SendKeyboardEvents" value="0"> <param name="SendMouseClickEvents" value="0"> <param name="SendMouseMoveEvents" value="0"> <param name="SendPlayStateChangeEvents" value="-1"> <param name="ShowCaptioning" value="0"> <param name="ShowControls" value="-1"> <param name="ShowAudioControls" value="-1"> <param name="ShowDisplay" value="0"> <param name="ShowGotoBar" value="0"> <param name="ShowPositionControls" value="0"> <param name="ShowStatusBar" value="-1"> <param name="ShowTracker" value="0"> <param name="TransparentAtStart" value="0"> <param name="VideoBorderWidth" value="0"> <param name="VideoBorderColor" value="0"> <param name="VideoBorder3D" value="0"> <param name="Volume" value="-600"> <param name="WindowlessVideo" value="0"> <embed type="application/x-mplayer2" pluginspage="http://www.microsoft.com/Windows/Downloads/Contents/Products/MediaPlayer/" name="MediaPlayer" src="rtsp://adres_ip_kamery:554/live/ch01_0" height="240" width="320" showcontrols="1" showpositioncontrols="0" showaudiocontrols="1" showtracker="0" showdisplay="0" showstatusbar="1" showgotobar="0" showcaptioning="0" autostart="1" autorewind="0" animationatstart="0" transparentatstart="0" allowchangedisplaysize="0" allowscan="0" enablecontextmenu="0" clicktoplay="0"></object> </body> </html>
Niewątpliwą wadą jest konieczność instalacji odpowiedniej wtyczki choć to za nas, w większości przypadków, zrobi przeglądarka.
We wszystkich tego typu skryptach występuje wiele dodatkowych parametrów (po za ip i port) takich jak np: szerokość i wysokość obrazu. Takie dane należy pozyskać z kamery a najczęściej są one konfigurowalne. Przykładem może być kamera Vivotek IP8332, gdzie mamy cztery strumienie a każdy z nich można dość elastycznie konfigurować:
W tym przypadku stream 3 korzysta z kompresji MPEG-4, jego rozdzielczość to 640×400 25klatek na sekundę a jakość ustawiono na najlepszą (cokolwiek to oznacza według producenta).
Kamera AirCam ma mniejsze możliwości z panelu WWW mamy:
Dodam, iż dostęp do strumienia można zabezpieczyć loginem i hasłem, w przypadku AirCam:
W takiej sytuacji dostęp do strumienia RTSP wygląda tak:
rtsp://login:haslo@adres_ip:554/live/ch02_0
Kolejny sposób na transmisję obrazu do naszej strony to skorzystanie z serwisu camgate.ru oferującego możliwość prostej retransmisji jednak cały czas bezpośrednio z naszego adresu IP, co chyba jak już wyjaśniłem, nie jest dobrym pomysłem:
<html> <head> <script type="text/javascript" src="http://free.camgate.ru/camgate.js"></script> </head> <body> <script type="text/javascript"> var swf = new swfObj("http://free.camgate.ru/camgate.swf",640,360,"flvp"); swf.param("quality", "high"); swf.param("allowFullScreen","true"); swf.flashVar("addScreen","640x360"); swf.param("wmode", "opaque"); swf.flashVar("vid","rtmp://free.camgate.ru/rtmp/rtsp://adres_ip_kamery:port/live/ch01_0"); //swf.flashVar("prev","http://free.camgate.ru/camgate.jpg"); //swf.flashVar("logo","http://free.camgate.ru/logo.png"); swf.flashVar("logoUrl","http://free.camgate.ru/"); swf.flashVar("logoPos","TL"); swf.flashVar("logoHidden","Y"); swf.flashVar("hiddenPanel","5"); swf.flashVar("autoplay","Y"); swf.flashVar("buffer","5"); swf.add(); </script> </body> </html>
Wszystko pięknie i ładnie ale wszystkie powyższe metody maja wadę: wystawienie naszego adresu IP bezpośrednio do sieci oraz duże obciążenie kamery co może się le skończyć np „zatkaniem” się łącza czy spowodować niedostępność obrazu dla części (większej) odwiedzających naszą stronę WWW.
I tu dochodzimy do najmilszej części postu – darmowy system retransmisyjny. Możliwe? Tak, wspomniany wcześniej serwis free.camgate.ru umożliwia coś takiego. Są pewne ograniczenia ale w przypadku niewielkich wymagań prostych serwisów rozwiązanie to w zupełności wystarczy. Tak więc do roboty:
– logujemy sie do free.camgate.ru
– klikamy w „english wersion”
– klikamy w „Sign up and connect the camera or edit camera settings”
– zakładamy nowe konto
– po otrzymaniu maila aktywacyjnego logujemy się do swojego konta
– na górze panelu klikamy „new”
– wypełniamy formularz rejestracyjny i oczekujemy na zatwierdzenie co trwa od kilkunastu minut do kilku godzin
Dość istotną sprawą jest podanie właściwych proporcji obrazu zgodnych z parametrami strumienia z kamery tak aby obraz na stronie prezentowany był poprawnie. Dodatkową możliwością jest przesłanie własnego loga, które będzie wyświetlane w lewym górnym rogu obrazu a także tekstu reklamy przesuwającego się u dołu okna z obrazem. W polu „Player location site” należy podać nazwę domenową serwisu lub serwisów w jakim będzie prezentowany obraz z kamery. Pamiętaj aby podać właściwą nazwę strumienia z kamery (pole „Your IP cam’ URL”) w postaci adresu rtsp://ipkamery:port/strumien! Co do rozmiarów loga to najlepiej aby było ono w postaci 130×56 z przezroczystym tłem, natomiast obrazek (pole Image preview) powinno mieć wymiar zgodny z rozmiarem obrazu z kamery gdyż jeśli będzie inaczej obrazek może zostać niezbyt ładnie wyskalowany.
Po zakończeniu procesu zatwierdzania naszej kamery otrzymamy (w serwisie camgate.ru) link jaki można wstawić na stronę WWW w stylu:
<iframe style="width:640px;height:400px;border:0" src="http://player.camgate.ru/cam/html/numer_strumienia"></iframe>
Taki link uruchamia uniwersalny player z obrazem transmitowanym z serwisu camgate.ru. Wielką zaletą tego rozwiązania jest to iż obraz na stronie pobierany jest z powyższego serwisu a nie bezpośrednio z naszej kamery co podnosi poziom bezpieczeństwa oraz wydajność gdyż w tym wypadku z obrazu może jednocześnie korzystać znacznie większa liczba internautów. Zasada działania jest dość prosta: camgate.ru pobiera obraz z naszej kamery a player na stronie z serwisu 0 tyle.
Podsumowując: konfiguracja transmisji obrazu z kamery CCTV jest możliwa na wiele sposobów a serwis camgate.ru za darmo (!) umożliwia prosty streaming, który w większości wypadków w zupełności wystarczy każdemu webmasterowi, ułatwia to zarządzanie kamerami naszych klientów a przede wszystkim podnosi jakość naszych usług. Oczywiście należy zapoznać się z zasadami korzystania z tego co serwis oferuje. Jedyną wadą jest to, że serwis wspiera tylko strumienie RTSP H.264 ale to chyba nie aż taki problem gdyż większość kamer nawet tych tańszych obsługuje ten protokół.
Co do tematu routerów, przekierowania portów, DynamicDNS i konfiguracji sieciowej kamer – o tym będzie inny post.