Streaming de Video con Java en Raspberry Pi
Hay dos modos de crear streming, uno es capturando las fotos (jpeg) que se toman con raspistill, el otro modo es capturando el vídeo (h264) generado con raspivid, como se observa en el tutorial de: Streaming Video desde el Raspberry Pi, ahora se va generar este streaming con Java.
Como funciona?
Proyectos necesarios vía GitHub:
git clone https://github.com/andrexweb/raspberry-pi.git
Proyecto Maven: StreamingPi
Proyecto Maven: StreamingPi
git clone https://github.com/andrexweb/java.git
Proyecto Maven: H264J
Proyecto Maven: H264J
El server, es un servidor de paquetes UDP (Datagrama) que esta en el proyecto StreamingPi, el cual solo recibe el flujo de datos, dependiendo de la opción que se incluya jpeg o h264 se activa el reproductor correspondiente, para el caso de h264, es un codec escrito en java que es un "port" de la libreria ffmpeg-libavcodec (pero solo la parte de h264). El proyecto original esta en Google Code h264j, pero copie el proyecto y agregue unas mínimas modificaciones para que reciba el streaming de forma directa, proyecto H264J.
Proyecto disponible en:
GitHub: https://github.com/andrexweb/java
Original: https://code.google.com/p/h264j/
En el momento el reproductor de fotos/vídeo (jpeg/h264) es básico, solo muestra imágenes, próximamente mas opciones.
Para el lado del cliente, es UDP, solo envía lo que genera los aplicativos raspistill y raspisvid, no se usa el modo normal de "pipe" (|), el api de Java cuenta con con una clase que permite la ejecución de comandos y obtener el "stdout" vía inputStreaming.
Ejemplo:
//command: lista de parametros, primero parametro es el comando a ejecutar.
ProcessBuilder processBuilder = new ProcessBuilder(command);
//Se incia el proceso y se obtiene el inpuStream de la ejecucion, esto es lo que se envía por UDP.
Process process = processBuilder.start();
InputStream inputStream = process.getInputStream();
Ver Clase para ver implementación completa: org.avpsoft.streaming.net.DatagramCommandClient.java
ProcessBuilder processBuilder = new ProcessBuilder(command);
//Se incia el proceso y se obtiene el inpuStream de la ejecucion, esto es lo que se envía por UDP.
Process process = processBuilder.start();
InputStream inputStream = process.getInputStream();
Ver Clase para ver implementación completa: org.avpsoft.streaming.net.DatagramCommandClient.java
Uso
Opción con raspistill
Primero ejecutamos el servidor (en windows), quien recibe el streaming:
D:\GitHub\raspberry-pi\StreaminPi>java -cp ./target/StreamingPi-1.0-SNAPSHOT.jar org.avpsoft.streaming.main.Streaming 4445 jpeg
Esto nos abre una ventana, donde se mostrara las imágenes.
Ahora ejecutamos el servidor (Raspberry Pi):
pi@raspberrypi ~ $ java -cp ./StreamingPi-1.0-SNAPSHOT.jar org.avpsoft.streaming.main.Streaming 192.168.1.2 4445 raspistill -n -t 0 -tl 150 -th 0:0:0 -w 640 -h 480 -q 5 -o -
Las primeras dos opciones es la ip del servidor y el puerto son fijas, no puede cambiar el orden.
Ejemplo del "lag" (retraso generado) al usar este metodo, 4 segundos, el mejor tiempo que pude registrar estuvo en 3 segundos.
Opción con raspivid
Se requiere este jar adicional H264J-1.0-SNAPSHOT.jar, para el codec h264.
Primero ejecutamos el servidor (en windows), quien recibe el streaming:
D:\GitHub\raspberry-pi\StreaminPi>java -cp ./*.jar org.avpsoft.streaming.main.Streaming 4445 h264
Esto nos abre una ventana, donde se mostrara las imágenes.
Ahora ejecutamos el servidor (Raspberry Pi):
pi@raspberrypi ~ $ java -cp ./StreamingPi-1.0-SNAPSHOT.jar org.avpsoft.streaming.main.Streaming 192.168.1.2 4445 raspivid -n -t 0 -w 640 -h 480 -fps 10 -o -
Las primeras dos opciones es la ip del servidor y el puerto son fijas, no puede cambiar el orden.
Ejemplo del "lag" (retraso generado) al usar este método, es de menos de 1 segundo, mas o menos 300 milisegundos.
Problemas:
* Debido a que se usa UDP y no TCP, es posible que las imágenes se distorsionen, pero es causado por la fiabilidad de la red, si tiene mala señal WIFI eso pasara.
* Cuando se ejecuta el server con h264, es posible que salga errores, pero el streaming sigue funcionando.
* Para terminan la ejecución use Ctrl+C
Andres. Lo primero de todo es darte las gracias por el esfuerzo que supone el trabajo y el publicarlo para que otros podamos aprender.
ResponderEliminarNo vengo del mundo del software pero estoy haciéndome una aplicación que necesito exactamente lo que has publicado. Mi problema es que no se bajar el proyecto desde el repositorio... ¿como puedo bajármelo?
un saludo
Hola, disculpa la tardanza en responder, pero si ingresas a esta URL: https://github.com/andresvelezperez/raspberry-pi al lado derecho aparece un boton que dice: Download Zip
Eliminaro tambien puedes instalar "git" t descargar el codigo de la url del repositorio.
como bajo el programa a la raspberry pi?
ResponderEliminargracias de nuevo
Puedes usar FileZilla para transferir los .jar.
EliminarMuy buenas Andres.
ResponderEliminarlo primero es felicitarte el año.
He visto en tu Web que tienes publicado un montón de formas distintas de hacer streaming con las cámaras de la raspberry.
Estoy haciendo una aplicación en la que necesito meter en un jpanel el video capturado en streaming desde una cámara pi de raspberry. Cuando empezé pensaba que habria drivers para su funcionamiento, pero no he sido capaz de encontar algo bueno salvo lo tuyo.
¿que me aconsejas para meter el video streaming en un jpanel?
parece que tu aplicación en java es lo más razonable, pero he visto que tienes una gran cantidad de ficheros en cada uno de los proyectos streaming pi y java y la verdad que no he sido capaz de aclararme.
muchas gracias de antemano.
Cordial Saludo
EliminarLa clase H264Player que esta en la libreria H264 es la que inicia el panel que muestra el video, para el caso de transmitir fotos, la clase JPEGPlayer que esta en StrammingPi.
La clase principal es Streaming.java dependendo de lo que se este ejecutando se incia, cliente o servidor, elservidor es el que se ejcuta en windows el que muestra el panel, el cliente es el que se ejecuta en el rpi que no tiene interfaz grafica.
Andres.
ResponderEliminarya he sido capaz de correr el programa, pero la imagen tiene ruido en exceso y no se debe a que la red alámbrica esté mal.
¿tienes idea de por donde puedo mirar para solucionar el problema?
gracias de antemano
Por favor poner URL de imagen del ruido, el ruido por se causado por la red wifi, probar con cable a ver si mejora.
EliminarAndres a mi me sucede lo mismo el video h264 se ve demasiado difuminado, se ve fatal la rpi esta conectada por cable a la red y el pc tb alguna sugerencia??
EliminarGracia makina
Posiblemente sea la versión de Java usada, si pueden compartir una imagen que toman, puede ser de utilidad.
EliminarHola andrés tu programa tiene muy buena pinta pero la imagen recivida en el servido tiene demasiado ruido practicamente no se puede vver da imagenes completamente difuminadas tengo todo conectado x cable y x lo que pones deberia verse mejor alguna ayuda??
ResponderEliminarUn Saludo y Gracias Makina
Aparte de la versión de Java, puede ser que se pierda muchos paquetes porque el protocolo usado es UDP (próximamente por TCP), pero también se puede jugar con los parámetros que se le pasan a raspivid si es para vídeo. (compartir una imagen).
Eliminar