La aplicación está prácticamente terminada salvo pequeños detalles.
Cambios que hemos introducido respecto a la versión anterior:
1) La aplicación cargaba varios ficheros desde la sdcard. Ahora en lugar de eso mientras se muestra la pantalla inicial se copian esos ficheros desde la misma aplicación hasta un directorio privado que solo se puede acceder desde la aplicación. En el momento en que la aplicación sea desinstalada, estos archivos se borrarán de la memoria del teléfono. Con esto conseguimos que la aplicación funcione en cualquier móvil, tenga o no ranura para sdcard. Era algo fundamental.
2) El menú principal ahora tiene un checkBox. Si está marcado, al pulsar el botón de traducir, se leerá la entrada de texto mediante un TTS.
3) Eliminamos las actividades destinadas al text to speech y al traductor. La primera función ahora está integrada en el menú principal; y respecto al traductor, pasa a ser una clase sin extender a una actividad. En el menú principal se crea un objeto de esta clase que se usa para traducir la entrada.
Con estos cambios, la aplicación solo tiene tres actividades: la pantalla inicial, el menú, y la pantalla donde se muestran los vídeos.
4) Se ha diseñado un método de reproducción de vídeos frame a frame sin retardo entre ellos, sin problemas de memoria, y con una velocidad fácil de controlar. Además al tocar sobre el vídeo se hace visible un botón de replay. Si el botón se pulsa cuando se está reproduciendo un vídeo, entonces no hace nada, porque se superpondrían dos hilos de ejecución y el resultado es terrible. Se han probado distintas velocidades, y a 10 frames por segundo se ve bastante bien.
En la siguiente entrada al blog explicaremos la forma en la que hemos reproducido los vídeos. Es una clase bastante complicada, puesto que cuando entran threads de por medio todo se hace mucho más difícil.
Sign Language Android Application
martes, 15 de mayo de 2012
domingo, 13 de mayo de 2012
Posibilidades: 2ª opción
Primeramente, hemos intentado hacer la primera opción de las que os pusimos en el último post. Hemos optado por reducir el tamaño de las imágenes (Recordad que hacía falta una reducción del orden 1:10)
¿Cómo lo hemos hecho?
Las imágenes originales son de 480 x 640 = 307200 píxeles
307200 píxeles x 32 bits/píxel = 9.8·10^6 bits
Haciendo la reducción, nos quedan 307200/10 = 30720 píxeles
Sabemos que 480 es 3/4 veces 640. Luego, x·3/4·x = 30720
x = 202.386 ~ 200
3/4·x = 151.79 ~ 150
Total: 150x200x32 bits = 0.96·10^6 bits(10 veces menos que antes)
¿Cuál es el problema entonces?
El problema reside en que hay que pasar todos los vídeos a frames y, a su vez, reducir esos frames, es decir:
330 vídeos · 15 frames / vídeos · 330 reducciones = 1 633 500 cambios
Motivo más que suficiente para probar la otra opción que de funcionar será la definitiva.
¿Cómo lo hemos hecho?
Las imágenes originales son de 480 x 640 = 307200 píxeles
307200 píxeles x 32 bits/píxel = 9.8·10^6 bits
Haciendo la reducción, nos quedan 307200/10 = 30720 píxeles
Sabemos que 480 es 3/4 veces 640. Luego, x·3/4·x = 30720
x = 202.386 ~ 200
3/4·x = 151.79 ~ 150
Total: 150x200x32 bits = 0.96·10^6 bits(10 veces menos que antes)
¿Cuál es el problema entonces?
El problema reside en que hay que pasar todos los vídeos a frames y, a su vez, reducir esos frames, es decir:
330 vídeos · 15 frames / vídeos · 330 reducciones = 1 633 500 cambios
Motivo más que suficiente para probar la otra opción que de funcionar será la definitiva.
sábado, 12 de mayo de 2012
Reproducción de un gif/vídeo: nuevo contratiempo
Hace un par de entradas atrás pusimos las capturas de las tres opciones de reproducción de un gif que teníamos y recordad que al final llegamos a una conclusión que era que la opción tercera era la buena. Pues bien, al contrario de nuestra creencia, la reproducción en el móvil también mantiene la parte más oscura de debajo de la cabeza, es decir, que no se ven suficientemente claros los gestos.
Tras haber probado TODO con los vídeos o imágenes animadas, ya solo nos queda una opción: sacar los fotogramas de los vídeos (unos 15 aproximadamente) y buscar una manera de reproducirlos unos tras otros.
¿Qué pasa con esta opción?
Hemos estado probando y resulta que con frames (fotogramas) las animaciones se ven bien, pero solo hemos conseguido reproducir 10 frames seguidos, si metemos más da un error de memoria.
Llegados a este punto, se nos abren dos nuevas alternativas:
a) Reducir considerablemente el tamaño y la calidad: pasando a 1:10 los bytes, podríamos reproducir unos 100 frames, que pueden ser entre 7 y 12 vídeos. Como la pantalla del móvil es pequeña igual no se aprecia mucho la calidad y podría valernos.
b) Crear un objeto de tipo AnimationDrawable(), al que le añadamos los frames que queramos, y así será más fácil hacer operaciones del tipo: controlar velocidad, botón de start y stop.
Con un thread ir cambiando el fondo, por ejemplo. Hay que tener cuidado porque la UI (Interfaz de usuario) solo la puede cambiar el thread principal, por lo que habría que mandarle mensajes a este cada vez que queramos cambiar de imagen. Esta es más complicada, pero en principio evitaríamos los problemas de memoria.
Vamos a probar ambas alternativas y ver qué resultado es más satisfactorio.
Tras haber probado TODO con los vídeos o imágenes animadas, ya solo nos queda una opción: sacar los fotogramas de los vídeos (unos 15 aproximadamente) y buscar una manera de reproducirlos unos tras otros.
¿Qué pasa con esta opción?
Hemos estado probando y resulta que con frames (fotogramas) las animaciones se ven bien, pero solo hemos conseguido reproducir 10 frames seguidos, si metemos más da un error de memoria.
Llegados a este punto, se nos abren dos nuevas alternativas:
a) Reducir considerablemente el tamaño y la calidad: pasando a 1:10 los bytes, podríamos reproducir unos 100 frames, que pueden ser entre 7 y 12 vídeos. Como la pantalla del móvil es pequeña igual no se aprecia mucho la calidad y podría valernos.
b) Crear un objeto de tipo AnimationDrawable(), al que le añadamos los frames que queramos, y así será más fácil hacer operaciones del tipo: controlar velocidad, botón de start y stop.
Con un thread ir cambiando el fondo, por ejemplo. Hay que tener cuidado porque la UI (Interfaz de usuario) solo la puede cambiar el thread principal, por lo que habría que mandarle mensajes a este cada vez que queramos cambiar de imagen. Esta es más complicada, pero en principio evitaríamos los problemas de memoria.
Vamos a probar ambas alternativas y ver qué resultado es más satisfactorio.
domingo, 6 de mayo de 2012
Concatenación de Videos ( I )
También hemos dado los primeros pasos para la concatenación de los vídeos en C++.
La idea es que esta clase en c++ cree el gif salida.gif (varios gifs consecutivos) en la carpeta Assets y la clase Video que llama a GifDecoderView descrita en el anterior post lo reproduzca.
La clase en C++ la hemos llamado merge_gif y hemos creado su correspondiente fichero .h (merge_gif.h). El archivo .h contiene la definición de la clase mientras que el .cpp contiene la definición de las funciones de la clase.
Hemos cambiado los char* por jstrnigs ya que recordad que daban problemas los char en java y en c++ al no funcionar de igual manera.
En traduce.cpp, que era la clase encargada de la traducción en c++, añadimos un método que llame a este método que hemos llamado Concatenar de la clase merge_gif.cpp. También lo añadimos en el makefile.
Con todo esto, está listo para la compilación, que hay que hacer siempre que trabajemos con los ficheros de c++ para su correcto funcionamiento en Java. Esta compilación la hacíamos ejecutando el archivo ndk-build con Cygwin. En traduciendo.java, llamamos al método de C++ : public native void ConcatenarGifs(String frase);
La idea es que esta clase en c++ cree el gif salida.gif (varios gifs consecutivos) en la carpeta Assets y la clase Video que llama a GifDecoderView descrita en el anterior post lo reproduzca.
La clase en C++ la hemos llamado merge_gif y hemos creado su correspondiente fichero .h (merge_gif.h). El archivo .h contiene la definición de la clase mientras que el .cpp contiene la definición de las funciones de la clase.
Hemos cambiado los char* por jstrnigs ya que recordad que daban problemas los char en java y en c++ al no funcionar de igual manera.
En traduce.cpp, que era la clase encargada de la traducción en c++, añadimos un método que llame a este método que hemos llamado Concatenar de la clase merge_gif.cpp. También lo añadimos en el makefile.
Con todo esto, está listo para la compilación, que hay que hacer siempre que trabajemos con los ficheros de c++ para su correcto funcionamiento en Java. Esta compilación la hacíamos ejecutando el archivo ndk-build con Cygwin. En traduciendo.java, llamamos al método de C++ : public native void ConcatenarGifs(String frase);
Clase para la reproducción de un Gif
Hoy hemos conseguido la reproducción de un solo gif.
Lo que hemos hecho ha sido que pase de menuprincipal.java a Video.java en lugar de traduciendo para evitar errores de otro tipo que no tienen que ver con la reproducción.
En la clase Video es donde trabajamos para ello.
Teníamos tres posibilidades de reproducción de un gif animado. Estas posibilidades las hemos encontrado por Internet:
http://droid-blog.net/2011/10/15/tutorial-how-to-play-animated-gifs-in-android-%E2%80%93-part-2/
La primera posibilidad y la tercera no funcionaban como esperábamos. Basta con ver la ejecución en este caso de la opción tres(Usando WebView):
Como véis, la imagen sale cortada por la mitad y, además, solo se reproducía el primer fotograma por lo que era básicamente una imagen, un gif sin animar.
Con la primera parte tuvimos problemas en la vinculación del gif al programa:
Al final, la buena resultó ser la opción 2, que era la más compleja y que, en un principio, quisimos evitar. Para esta manera, el gif lo guardamos en la carpeta Assets y el método se llama GifDecoderView. Hemos localizado en esta opción la posibilidad de controlar la velocidad de los fotogramas, que se podrá hacer o bien poniendo varios botones con 2x, 0.5x, 0.25x... o bien con una slidebar.
En la captura obviamente no se aprecia pero esta vez sí se reproducía el gif. La parte más oscura del vídeo es cosa del emulador, ya que en el teléfono móvil sí funciona correctamente.
Lo que hemos hecho ha sido que pase de menuprincipal.java a Video.java en lugar de traduciendo para evitar errores de otro tipo que no tienen que ver con la reproducción.
En la clase Video es donde trabajamos para ello.
Teníamos tres posibilidades de reproducción de un gif animado. Estas posibilidades las hemos encontrado por Internet:
http://droid-blog.net/2011/10/15/tutorial-how-to-play-animated-gifs-in-android-%E2%80%93-part-2/
La primera posibilidad y la tercera no funcionaban como esperábamos. Basta con ver la ejecución en este caso de la opción tres(Usando WebView):
Como véis, la imagen sale cortada por la mitad y, además, solo se reproducía el primer fotograma por lo que era básicamente una imagen, un gif sin animar.
Con la primera parte tuvimos problemas en la vinculación del gif al programa:
Al final, la buena resultó ser la opción 2, que era la más compleja y que, en un principio, quisimos evitar. Para esta manera, el gif lo guardamos en la carpeta Assets y el método se llama GifDecoderView. Hemos localizado en esta opción la posibilidad de controlar la velocidad de los fotogramas, que se podrá hacer o bien poniendo varios botones con 2x, 0.5x, 0.25x... o bien con una slidebar.
En la captura obviamente no se aprecia pero esta vez sí se reproducía el gif. La parte más oscura del vídeo es cosa del emulador, ya que en el teléfono móvil sí funciona correctamente.
Paso de videos .mp4 a imagenes .gif
Aquí dejamos unas capturas del proceso de paso de archivos.mp4 a .gif, por medio del programa VirtualDub.
De la siguiente manera, especificamos que solo se reproduzcan una única vez, sin repeticiones:
miércoles, 25 de abril de 2012
Vídeos en formato gif
Vamos a intentar solucionar nuestros problemas con los vídeos pasándolos de formato mp4 a gif con el programa VirtualDub. Esto ya esta hecho y ahora nos ponemos con la clase que haga el play de un gif.
En android ya viene predefinida una clase llamada android.graphics.Movie que nos permite reproducir distintos InputStreams( cualquier cosa de la que se leen bytes. Puede ser el teclado, un fichero, un socket, o cualquier otro dispositivo de entrada).
Una vez que consigamos hacer compilar la clase y veamos que funcione, intentaremos controlar el número de repeticiones del Gif para que no se reproduzca indefinidamente.
Por otro lado, ya hemos hecho el TTS(text to speech) y funciona correctamente.
Más adelante subiremos muestras de todo esto.
Suscribirse a:
Comentarios (Atom)