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:
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ń