Przesyłaj strumieniowo wideo na żywo z jednego telefonu z systemem Android do drugiego przez Wi-Fi

115

Od kilku dni szukałem w Internecie, jak zaimplementować funkcję przesyłania strumieniowego wideo z telefonu z systemem Android na inny telefon z systemem Android za pośrednictwem połączenia Wi-Fi, ale nie mogę znaleźć niczego przydatnego. Szukałem na programistach Androida przykładowego kodu, stackoverflow, google, blogów na Androida, ale nic. Wszystko, co mogę znaleźć, to rozwiązania typu telefon-komputer lub komputer-telefon do przesyłania strumieniowego, ale nic, co mogę pożyczyć w mojej implementacji.

Muszę sterować robotem za pomocą arduino ADK, więc używam 2 telefonów, jednego, który zostanie zamontowany na robocie, a drugiego, który będzie odbierał strumień wideo od robota. Wspominam o tym, ponieważ staram się uzyskać jak najmniejsze opóźnienie między czasem emisji a czasem oglądania.

Piszę 2 aplikacje, jedną aplikację master do sterowania robotem (z telefonu ręcznego), która będzie sterować aplikacją slave i odbierać strumień, oraz drugą aplikację slave, która będzie działać na telefonie przypiętym do robota, sterując silnikami / siłownikami / przesyłanie strumieniowe do aplikacji głównej. Niestety nie mogę korzystać z aplikacji innych firm. Muszę zintegrować kod strumienia wideo z moimi 2 aplikacjami.

Jakie są opcje osiągnięcia tego? Jest to również bardzo trudne, ponieważ nigdy nie pracowałem z transmisją wideo, chociaż radzę sobie całkiem dobrze zarówno w programowaniu w Javie, jak i Androidzie. Jak zakodować / zdekodować strumień, jak zainicjować połączenie, czy będę musiał pracować z UDP zamiast TCP / IP? Naprawdę nie wiem, od czego zacząć, nigdzie nie ma przykładowego kodu. Jestem prawie pewien, że można to osiągnąć. Po prostu nie mogę znaleźć niczego pożytecznego, aby zacząć we właściwym kierunku.

Natknąłem się na spydroida, ale używa VLC na pulpicie, więc nie jest to dla mnie dobre.


EDYCJA: Sprawdź blog Cagneya Moreau . Omawia szczegóły dotyczące wdrażania tego.

androidu
źródło
1
Czy możesz udostępnić swój projekt, robię podobne rzeczy, ale przesyłam strumieniowo wideo między Androidem a komputerem stacjonarnym (WebClient) ... Myślałem o websockets html5 +, ale mam wiele problemów ...
Buksy
1
Rozwijam takie rozwiązanie, czyli w 80% to co Ty próbujesz zrobić. Musisz skonfigurować serwer VOIP, a następnie utworzyć klientów dla tego VOIP, który będzie przesyłał Twój głos i wideo. Ja też tego szukam. jeśli ktoś wie, daj mi znać.
AZ_
1
e-mail jest podany na moim profilu
AZ_
1
Sprawdź mój projekt. Wszystko w Javie i szczegółowo wyjaśnione cagneymoreau.com/stream-video-android
Cagney
1
dzięki Pracuję też na robocie. Zabawne rzeczy
Cagney

Odpowiedzi:

55

Jeśli nie potrzebujesz funkcji nagrywania i odtwarzania w swojej aplikacji, rozsądnym wyborem jest użycie gotowej aplikacji do przesyłania strumieniowego i odtwarzacza.

Jeśli jednak potrzebujesz ich, aby były w Twojej aplikacji, będziesz musiał zajrzeć do MediaRecorder API (dla aplikacji serwera / kamery) i MediaPlayer (dla aplikacji klienta / odtwarzacza).

Szybki przykładowy kod dla serwera:

// this is your network socket
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// this is the unofficially supported MPEG2TS format, suitable for streaming (Android 3.0+)
mMediaRecorder.setOutputFormat(8);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mediaRecorder.setOutputFile(pfd.getFileDescriptor());
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
mMediaRecorder.prepare();
mMediaRecorder.start();

Po stronie gracza jest to trochę trudne, możesz spróbować tego:

// this is your network socket, connected to the server
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(pfd.getFileDescriptor());
mMediaPlayer.prepare();
mMediaPlayer.start();

Niestety, odtwarzacz mediaplayer raczej tego nie lubi, więc masz kilka opcji: albo (a) zapisz dane z gniazda do pliku i (po zebraniu trochę danych) graj z odtwarzaczem mediów z pliku, albo (b) zrób mały http serwer proxy, który działa lokalnie i może akceptować żądanie GET odtwarzacza mediów, odpowiadać za pomocą nagłówków HTTP, a następnie kopiować dane ze zdalnego serwera do niego. Dla (a) utworzyłbyś odtwarzacz mediów ze ścieżką do pliku lub adresem URL pliku, dla (b) nadaj mu adres URL http wskazujący na twoje proxy.

Zobacz też:

Przesyłaj strumieniowo wideo na żywo z telefonu do telefonu za pomocą gniazda fd

MediaPlayer zacina się na początku odtwarzania mp3

Alex I
źródło
2
Witaj Alex, czy masz jakieś doświadczenie z wysyłaniem lokalnie przechowywanego pliku audio z telefonu z Androidem przez RTP?
B770,
cześć, czy możesz przesłać mi cały projekt?
Umar Asghar
1
czy możesz opublikować swój kompletny projekt?
Yazhini Murugaiya
który jest gniazdem serwera i gniazdem klienta
Yazhini Murugaiya
1
@AhmedHamdy Rzeczywiście: na poziomie API 23 (Android 6.0) możesz użyć setDataSource(MediaDataSource)zamiast FileDescriptor. Wdrożenie MediaDataSourceumożliwiłoby wykonanie własnego odczytu i buforowania w sieci, bez zapisywania do pliku tymczasowego.
Alex I
9

Pracowałem kiedyś nad czymś takim, ale wysłanie wideo i odtworzenie go w czasie rzeczywistym to naprawdę skomplikowana sprawa. Proponuję pracować tylko z plikami PNG. W mojej implementacji zrobiłem przechwycenie PNG za pomocą kamery hosta, a następnie wysłanie ich przez sieć do klienta, który wyświetli obraz zaraz po otrzymaniu i zażąda następnego obrazu od hosta. Ponieważ korzystasz z Wi-Fi, komunikacja będzie wystarczająco szybka, aby uzyskać około 8-10 obrazów na sekundę (tylko w przybliżeniu, pracowałem na Bluetooth). Więc będzie to wyglądać jak ciągłe wideo, ale przy znacznie mniejszym wysiłku. Do komunikacji możesz użyć gniazd UDP (szybsze i mniej złożone) lub DLNA (nie wiem, jak to działa).

Arveen
źródło
Tak, to miała być moja ostatnia deska ratunku. Dziękujemy za opinię!
androidu
3
Z pewnością strumień jpeg byłby bardziej wydajny niż strumień png?
stealthcopter
Sugerowałem tylko użycie obrazu, możesz użyć dowolnego formatu
Arveen,
@krossreg> czy możesz wkleić przykładowy kod dla tego, co sugerujesz?
Jasper
8

Możesz użyć kamery internetowej IP lub DLNA. Na przykład urządzenia Samsung są wyposażone w aplikację o nazwie AllShare, która umożliwia udostępnianie i uzyskiwanie dostępu do urządzeń obsługujących DLNA w sieci. Myślę jednak, że najlepszym rozwiązaniem jest kamera internetowa IP. Powinieneś być w stanie otworzyć strumień, który tworzy za pomocą odtwarzacza MX Video lub czegoś podobnego.

Cholera
źródło
2
Piszę 2 aplikacje, jedną główną aplikację do sterowania robotem (z telefonu ręcznego) i podglądu tego, co widzi robot, oraz drugą aplikację podrzędną, która będzie działać na telefonie przypiętym do robota, sterując silnikami / siłownikami / przesyłaniem strumieniowym. Niestety nie mogę korzystać z aplikacji innych firm. Muszę zintegrować kod strumienia wideo z moimi 2 aplikacjami.
androidu
Być może możesz poszukać informacji na temat specyfikacji DLNA i spróbować stworzyć aplikację, używając jej dla siebie, lub wysłać e-maila do programisty kamery internetowej IP i poprosić o pomoc.
ldam
1
Odwróć to? : P
mgibson
Tak, myślę, że nie mam innego wyboru.
androidu
5

Możesz sprawdzić system Android VLC, który może przesyłać strumieniowo i odtwarzać wideo, jeśli chcesz więcej indagować, możesz sprawdzić ich GIT, aby przeanalizować, co robią. Powodzenia!

Ricardo Ortega Magaña
źródło
3
Patrzę na Androida VLC. Czy możesz mi powiedzieć, jak używać go do przesyłania strumieniowego wideo?
user1914692