Pytałem Wujka Google co wie na ten temat, ale okazało się że spektrum możliwości niestety nie jest zbyt szerokie. Zależało mi żeby rozwiązanie działało w miarę płynnie, nie miało dużych opóźnień no i oczywiście żeby dało się je uruchomić na Raspberry Pi.
Chyba najsensowniejsze rozwiązanie które znalazłem to MJPG-streamer.
W uproszczeniu można napisać, że pobiera on z kamery statyczne obrazy i kopiuje je do pamięci. Wtyczki wyjściowe potrafią przesłać te obrazy do przeglądarki tworząc animację. Potrafi wykorzystać sprzętową kompresję wbudowaną w kamery. Dzięki temu nie zużywa dużo pamięci ani mocy procesora.
Nie mam dedykowanej kamery do Raspberry Pi, więc wykorzystałem zwykłą najtańszą kamerę USB, przechwytującą video z rozdzielczością do 640x480. Rozwiązanie jest na tyle uniwersalne że później można wymienić kamerę na lepszą :)
Jako że Raspberry Pi oparte jest o architekturę ARM, w większości przypadków programy które nie są zawarte w dystrybucji którą zainstalowaliśmy nie mają dedykowanych pakietów. Pozostaje zatem zbudowanie ich ze źródeł. Na szczęście nie stanowi to większego problemu.
Na RPI zainstalowałem dystrybucję Raspbian, która bazuje na Debianie. W tym przypadku kompilacja będzie wymagała następujących kroków (zakładam że użytkownik zalogowany jest np na koncie "pi" - lub dowolnym innym bez uprawnień administratora):
Na początek musimy zainstalować wymagane zależności. Zrobimy to następującymi poleceniami:
sudo apt-get install subversion
sudo apt-get install libv4l-dev
sudo apt-get install libjpeg8-dev
sudo apt-get install imagemagick
Następnie pobieramy kod źródłowy mjpeg-streamer'a bezpośrednio z repozytorium SVN:
svn checkout svn://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code
Przechodzimy do katalogu w którym znajdują się pobrane źródła:
cd mjpg-streamer-code/mjpg-streamer
i kompilujemy:
make USE_LIBV4L2=true clean all
po miejmy nadzieję poprawnej kompilacji, trzeba zainstalować zbudowaną aplikację w systemie:
sudo make DESTDIR=/usr install
tworzymy katalog dla obrazów:
sudo mkdir /var/www/mjpg_streamer
sudo chmod a+rw /var/www/mjpg_streamer
W tym momencie możemy już przetestować czy strumieniowanie działa.
Odpalamy polecenie:
mjpg_streamer -i "/usr/lib/input_uvc.so -d /dev/video0 -r 320x240 -f 15 -y" -o "/usr/lib/output_http.so -p 8090 -w /var/www/mjpg_streamer"
które oznacza mniej więcej tyle, że rozpoczynamy strumieniowanie obrazu z urządzenia /dev/video0 (kamera usb) o rozdzielczości 320x240, z framerate 15 FPS używając kodeka YUYV (opcja -y), na porcie 8090 wykorzystując folder /var/www/mjpeg_streamer
W przypadku mojej kamery opcja -y była niezbędna - kamera nie wspierała dekodowania MJPEG. W przypadku lepszych kamer powinno zadziałać bez tej opcji - co generalnie jest rozwiązaniem lepszym, ponieważ dekodowanie MJPEG jest podobno wydajniejsze od YUYV.
Żeby przetestować działanie strumienia trzeba spreparować sobie plik html w takiej postaci:
<html><body>
<img src="http://IP_RASPBERRY_PI:8090?action=stream">
</body></html>
I otworzyć go w przeglądarce. Okienko powinno zawierać obraz z kamery.
Gdy już mamy działający strumień, możemy przekonfigurować system aby strumieniowanie uruchamiało się automatycznie przy starcie.
W tym celu tworzymy plik stream.sh:
sudo nano /usr/bin/stream.sh
i dodajemy do niego polecenie uruchamiające strumień, czyli ponownie:
mjpg_streamer -i "/usr/lib/input_uvc.so -d /dev/video0 -r 320x240 -f 15 -y" -o "/usr/lib/output_http.so -p 8090 -w /var/www/mjpg_streamer"
i zapisujemy plik. Nadajemy mu uprawnienia wykonywalne:
sudo chmod a+x /usr/bin/stream.sh
i tworzymy dowiązanie symboliczne w /etc/init.d
Dodajemy utworzony skrypt do automatycznego startu poleceniem:
sudo update-rc.d stream.sh defaults 94 6
W tym momencie po restarcie systemu strumień powinien być automatycznie dostępny.
Docelowo w projekcie to Raspberry ma serwować stronę WWW z obrazem wideo. Dlatego musimy zainstalować na malince Apache + PHP.
Wystarczy polecenie:
sudo apt-get install php5
Serwer Apache jest w zależnościach PHP więc zainstaluje się automatycznie.
Chcemy aby nasza strona docelowo była generowana dynamicznie, zatem zamieniamy statyczny plik index.html:
sudo rm /var/www/index.html
na plik /var/www/index.php o następującej zawartości:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<body> | |
<? | |
echo ('<img src="http://'.$_SERVER['SERVER_ADDR'].':8090?action=stream"/>'); | |
?> | |
</body> | |
</html> |
Odpalenie w przeglądarce adresu:
http://IP_RASPBERRY_PI
powinno wyświetlić serwowane przez Malinkę wideo.
Z wstępnych testów wynika że przy strumieniowaniu przez WIFI obraz w rozdzielczości 320x240 przy 15 FPS działa praktycznie bez żadnych opóźnień. Strumień 640x480 przy 15FPS ma około 2-3 sekundy opóźnienia - co w praktyce może okazać się akceptowalnym wynikiem. Nie badałem jeszcze skąd te opóźnienia. Przyczyn może być kilka - wolne WIFI, słaba kamera bez obsługi MJPEG...
W każdym razie obciążenie CPU w Raspberry Pi jest praktycznie niezauważalne.
Jeśli macie lepsze propozycje przesyłania strumienia, chętnie się o nich dowiem - temat jest ciągle otwarty :)
Witam,
OdpowiedzUsuńchcę obrócić obraz.Gdzie znajdę plik input_raspi.so wykorzystujący parametr rotation i jak go zainstalować?
Pozdrawiam
Znalazłem wersję eksperymentalną z tą wtyczką: https://github.com/jacksonliam/mjpg-streamer
UsuńMożna używać 2 wtyczek na raz?
Odpowiem sobie samemu: Dwie wtyczki na raz nie działają, żeby obrócić obraz użyłem eksperymentalnej wersji z wtyczką input_raspi.so:
Usuńmjpg_streamer -i "/usr/lib/input_raspicam.so -x 640 -y 480 -fps 15 -rot 180" -o "/usr/lib/output_http.so -p 8090 -w /var/www/mjpg_streamer" MJ
Bardzo dobry wpis. Pozdrawiam serdecznie.
OdpowiedzUsuń