Presentaciones de fotos en formato vídeo (slideshows) desde la línea de comandos

Posted: julio 18th, 2020 | Author: | Filed under: Sin categoría | Tags: , , | No Comments »

Hace ya algunos años apareció en este blog como hacer presentaciones de fotos en formato vídeo. A pesar de que hay muchos programas buenos para editar vídeo en GNU/Linux, esta vez quería tener un proceso sencillo y fácilmente replicable aún a costa de perder un poco de calidad o efectos (como degradado entre imágenes, …).

En este tutorial veremos, sin entrar en muchos detalles (mis conocimientos no dan para ello), una forma muy rápida de crear un slideshow con música usando únicamente el terminal. Como limitante partimos de la base de que todas las imágenes están en el mismo formato (en este caso JPEG)

Las herramientas


sudo apt-get install --install-recommends rename imagemagick ffmpeg

Normalizar los nombres y ordenar las imágenes

El primer paso es ordenar las imágenes poniéndolos un «nombre normalizado» que represente ese orden. En este caso partimos de unas imágenes que ya tienen cierto orden, pero arreglamos las mayúsculas, usamos dos caracteres para los números y ajustamos las del medio.

Cada caso será muy particular pero veamos un ejemplo:


$ cp -r original copia
$ cd copia
$ ls
0.JPG 1_1.JPG 12_1.JPG 13.jpg 15.jpg 17.JPG 19.jpg 20.jpg 22.jpg 24.jpg 26.jpg 28.jpg 2.JPG 31.jpg 4.JPG 6.JPG 8.JPG
10.JPG 11.JPG 12.JPG 14.jpg 16.jpg 18.jpg 1.JPG 21.JPG 23.jpg 25.JPG 27.jpg 29.jpg 30.jpg 3.JPG 5.jpg 7.JPG 9.JPG
$ rename 's/.JPG/.jpg/' *.JPG
$ rename 's/3(\d).jpg/5$1.jpg/' 3*.jpg
$ rename 's/2(\d).jpg/4$1.jpg/' 2*.jpg
$ rename 's/1([2-9]).jpg/3$1.jpg/' 1*.jpg
$ ls
0.jpg 1_1.jpg 12_1.jpg 2.jpg 33.jpg 35.jpg 37.jpg 39.jpg 40.jpg 42.jpg 44.jpg 46.jpg 48.jpg 4.jpg 51.jpg 6.jpg 8.jpg
10.jpg 11.jpg 1.jpg 32.jpg 34.jpg 36.jpg 38.jpg 3.jpg 41.jpg 43.jpg 45.jpg 47.jpg 49.jpg 50.jpg 5.jpg 7.jpg 9.jpg
$ mv 12_1.jpg 31.jpg
$ rename 's/1([0-1]).jpg/2$1.jpg/' 1*.jpg
$ rename 's/([1-9]).jpg/1$1.jpg/' ?.jpg
$ mv 0.jpg 00.jpg
$ mv 1_1.jpg 01.jpg
$ ls
00.jpg 11.jpg 13.jpg 15.jpg 17.jpg 19.jpg 21.jpg 32.jpg 34.jpg 36.jpg 38.jpg 40.jpg 42.jpg 44.jpg 46.jpg 48.jpg 50.jpg
01.jpg 12.jpg 14.jpg 16.jpg 18.jpg 20.jpg 31.jpg 33.jpg 35.jpg 37.jpg 39.jpg 41.jpg 43.jpg 45.jpg 47.jpg 49.jpg 51.jpg

Rotar las imágenes

A pesar de que en la previsualización del explorador de archivos podamos ver todas las imágenes rectas, alguna de ellas puede estar girada. Esto es por qué muchas herramientas usan por defecto los metadatos EXIF de la imagen para rotarlas de la forma lógica.


# las que no tengan un `1` están rotadas
identify -verbose * | grep -E '(Image:|Orientation)'

# Rotarlas. https://stackoverflow.com/a/19475281/930271
# Esto modifica todas las fotos, por lo que mejor usarlo sólo con la que deben
# ser rotadas
mogrify -auto-orient *.jpg

identify -verbose * | grep -E '(Image:(.*)|exif:Orientation: [2-9])'
mogrify -auto-orient 16.jpg
mogrify -auto-orient 45.jpg

Identificar tamaños y «aspect ratio»

Para montar las imágenes en el vídeo debemos investigar sus tamaños y sobre todo la relación de aspecto. El comando identify de ImageMagick nos puede dar la información más relevante y podemos ordenarla por aspect ratio, anchura, …


# https://unix.stackexchange.com/questions/50252

# ordenadas por aspect ratio
$ identify -format "%[fx:w/h] %w %h %M\n" *.jpg | sort -n -k1

1.5 4608 3072 20.jpg
0.75 1944 2592 15.jpg
0.75 2304 3072 16.jpg
0.75 3864 5152 45.jpg
1.33333 1280 960 44.jpg
1.33333 1280 960 46.jpg
1.33333 1280 960 47.jpg
1.33333 2592 1944 13.jpg
1.33333 3072 2304 17.jpg
1.33333 3264 2448 01.jpg
1.33333 3264 2448 14.jpg
1.33333 3264 2448 19.jpg
1.33333 3264 2448 33.jpg
1.33333 4000 3000 43.jpg
1.33333 4000 3000 50.jpg
1.33333 4000 3000 51.jpg
1.33333 4320 3240 18.jpg
1.33333 4608 3456 31.jpg
1.33333 4672 3504 34.jpg
1.33333 4672 3504 35.jpg
1.33333 5120 3840 49.jpg
1.33333 5152 3864 32.jpg
1.33333 5152 3864 37.jpg
1.33472 1280 959 38.jpg
1.33884 2592 1936 00.jpg
1.33884 2592 1936 11.jpg
1.49841 3776 2520 21.jpg
1.77778 3072 1728 12.jpg
1.77778 3264 1836 39.jpg
1.77778 3968 2232 41.jpg
1.77778 5312 2988 36.jpg
1.77778 5312 2988 40.jpg
1.77778 5312 2988 42.jpg
1.77778 5312 2988 48.jpg

# ordenadas por width
identify -format "%[fx:w/h] %w %h %M\n" *.jpg | sort -n -k2

Aquí la clave es:

  • Ajustar las imágenes para que tengan todas la misma relación de aspecto y que no salgan deformadas. Cosa que haremos directamente con ffmpeg al crear el vídeo.
  • Escoger el tamaño de referencia a usar para las imágenes. La «redimensión» la haremos directamente al crear el vídeo.

Sin entender mucho de vídeos mi criterio es coger el aspect ratio más común a las imágenes, en este caso 1.333, y un tamaño intermedio, de modo que haya pocas imágenes por debajo de ese tamaño, y que al ampliar no pixelen demasiado, en este caso me quedo con 2592×1936

Montar el vídeo

La wiki de ffmpeg da el comando básico para hacer el slideshow, y en stackoverflow también hay buenas respuestas

El comando que usaremos en este caso es:


ffmpeg -framerate 1/5 -pattern_type glob -i '*.jpg' -i audio.mp3 -vf 'scale=2592:1936:force_original_aspect_ratio=decrease,pad=2592:1936:(ow-iw)/2:(oh-ih)/2,setsar=1' -c:v libx264 -c:a copy -crf 14 -r 25 -pix_fmt yuv420p -shortest output.mp4

Los parámetros más relevantes para el slideshow:

  • -framerate 1/5: El denominador define cuanto se mostrará cada imagen
  • -pattern_type glob -i '*.jpg': Cuando las imágenes no están ordenadas exactamente de forma secuencial con este parámetro las meterá en el video ordenadas por nombre
  • 'scale=2592:1936:force_original_aspect_ratio=decrease,pad=2592:1936:(ow-iw)/2:(oh-ih)/2,setsar=1': Escala las imágenes a 2592×1936 y mete bandas negras de relleno cuando no se pueda conservar la relación de aspecto

Charlas “Programming Style” por Douglas Crockford

Posted: julio 1st, 2017 | Author: | Filed under: Sin categoría | Tags: , , , , , , | No Comments »

Otra de las series de charlas más conocidas de Crockford, son en las que habla de la importancia del estilo de código que empleamos.

A good style can help produce better programs. Style should not be about personal preferences and self-expression. Douglas Crockford

De esta serie creo que la más interesante es:

  • YUIConf 2011. 66′. Douglas Crockford. Programming Style & Your brain. En esta charla Crockford explica lo importante que es usar un estilo de código adecuado, y como hay estilos mejores que otros (según el lenguaje que estemos usando). Al programar no debemos tratar de demostrar lo listos que somos, si no escribir código para que otros puedan entenderlo, y hay estilos que favorecen esto además de reducir los bugs que podamos cometer. La charla se centra en Javascript y la herramienta JSLint, pero el porqué de usar un estilo y herramientas es importante vale para cualquier lenguaje.

Otras charlas similares serían:

Escogiendo un estilo de código

Crockford dice que al escoger un estilo, debemos priorizar (y en ese orden) que:

  1. Evite errores (aunque sea errores que raramente sucedan)
  2. Sea legible. Comuniqué claramente su intención al resto de programadores. Y se debe preferir esto sobre ahorrar memoria o velocidad.

Algunos comentarios de estilo de su charla con los que estoy de acuerdo

La llave va a la derecha

La llave va a la derecha, porqué el siguiente código en js produce un error silencioso:

[cc lang=»javascript»]
return
{
ok: false
};
[/cc]

Mientras que esto funciona correctamente:

[cc lang=»javascript»]
return {
ok: false
};
[/cc]

Usar Strict Equality Comparison

No usar nunca «==» usar siempre «===». Evita resultados indeseados al hacer casting.

No usar el slash para generar strings multilínea

No usar el slash para generar strings multilínea porqué si hay un espacio después del slash se produce un error
[cc lang=»javascript»]
«hola \
mundo»
[/cc]

Usar siempre las llaves para los bloques de código

Usar siempre las llaves aunque sea para escribir en la misma linea [cci lang=»javascript»]if (flag) { doSomething(); }[/cci]

No usar pre/post incremento

No usar pre/post incremento. En lugar de ++x o x++ usar x+=1; Los primeros casos obligan a pensar más en lo que se está haciendo de que valor va a tener x cuando se ejecute algo, e introduce más errores.

No usar asignación transitiva

No usar la asignación transitiva var a = b = 0. Porqué no está claro si lo que se quería hacer era
[cc lang=»javascript»]
var a = 0,
b = 0;

b = 0;
var a = b;
[/cc]

En los switch usar siempre break

En el switch usar siempre break después de cada caso. Es muy fácil usarlo mal, y que se presente un bug difícil de depurar.

Forma de usar las IIFE

Al usar Immediately Invocable Function Expression, preferir la tercera forma que aparece aquí
[cc lang=»javascript»]
function () {

}(); // Syntax error!

(function () {

})(); // Bien

(function () {

}()); // Mejor. Queda más claro lo que estamos haciendo según Crockford
[/cc]

Usar siempre el «;»

Usar siempre el ; para evitar el Automatic Semicolon Insertion que puedo provocar bugs difíciles de depurar.

Algunos con los que puedo estar de acuerdo, pero debería revisar

Declaración de variables en el top

Como javascript no tiene (¿tenía?) block scope, si no sólo function scope, hay que declarar todas las variables en la parte de arriba y declarar todos los métodos antes de usarlos. Esto deja claro como funciona el hoisting en javascript que puede introducir errores. Esto incluye el no declarar variables dentro del for – for (var i …) {, para dejar claro que la variable i es válida para toda la función, y tiene valor antes (undefined) y después del for (el último valor que haya tomado en el bucle). Habría que ver como se conjuga esto con let, const, …

Espacio entre paréntesis y resto de elementos

Una serie de reglas sobre donde y como usar los paréntesis, del tipo:

  • No space before ( when used to invoke a function
  • No space between a function name and a parameter list
  • One space between all other names and (

Uso equivocado según crockford:

  • foo (bar);
  • function foo (b) {…}
  • function(x) {…}
  • return(a+b);
  • if (a=== 0) {…}

 


Charlas «The better Parts» por Douglas Crockford

Posted: mayo 28th, 2017 | Author: | Filed under: Sin categoría | Tags: , , , , , | No Comments »

Seguramente las charlas más conocidas de Crockford son las basadas en su libro The good parts y o algunas más modernas a las que llama de «The better parts» donde revisa alguna de sus anteriores prácticas y comenta features de ES6.

Dentro de esta serie de The Better Parts se pueden encontrar varias dadas en distintas momentos, entre ellas.

  • The Better Parts | .concat() 2015. El problema de esta charla es que no se ven las transparencias (y a pesar de ser similares) a las slides que usa en otras se hace un poco complicado seguir el hilo. Creo que una de las novedades de esta charla respecto a otra es cuando habla de los Template Literals.
  • The Better Parts. Infoq. Agosto/2014. Las transparencias de esta charla, que también valen de guía para el resto están aquí. La de la JSConfUY me pareció un poco más fluída que esta. Pero hay al menos dos secciones que en esta están mejor explicadas o ampliadas la que llama en las transaprecias New Good Parts in ES6 que empieza en el minuto 12 y acaba en el 25. Y cuando explica su constructor pattern (slide 46) a partir del minuto 34. El constructor también lo explica en la JSConfUY pero aquí se entienda mejor.
  • The Better Parts – JSConfUY Septiembre/2014. En apareciencia esta tiene un poco más de carga filosófica que la de Infoq.

Yo ví la charla de JSConfUY, ojee la de concat, y fuí a algunas partes concretas de la de InfoQ. Mi recomendación es que veas la de InfoQ. O si no que veas de la JSConfUY y las partes concretas que mencionó de la de InfoQ.

A nivel contenidos las charlas son similares.

Arranca con una cita de Saint-Exupéry, «It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to subtract.» y de como los programadores deben buscar la perfección. Por ello hace incapié en uno de sus habituales, que un lenguaje nos dé un montón de características no significa que tengamos que usarlas todas si no sólo las «buenas».

Luego habla de jslint y de su libro de «The good parts». Combate algunas de las criticas que se hacen de jslint y defiende porqué el estilo de desarrollo no es simplemente un «acuerdo», si no que hay estilos mejores que otros, y que escribir de una determinada forma elimina bugs y por tanto te acerca a la perfección.

Continúa con una mini revisión de esas buenas partes de JavaScript en general mezclándolo con como debería ser el lenguaje del futuro (tiene otra charla sobre esto llamada The Post JavaScript Apocalypse), centrándose en su propuesta para un nuevo tipo de datos numérico llamado DEC64.

Y termina hablando un poco de JSON.

The better parts

Entre las prácticas que menciona como mejores están.

* No usar for. Sólo array.forEach y derivados
* No dice nada de for..of, supongo que en el momento todavía no habría una propuesta al respecto, pero si habla de evitar for..in y emplear unicamente Object.keys(object).forEach
* Y dice que tampoco usa ya while si no que usa una construcción de este tipo

function repeat(func) {
if (func() !== undefined) {
return repeat(func);
}
}

Como vemos, y como el mismo dice, estás Better Parts van en la línea de usar JavaScript como un lenguaje funcional.

Especial atención merece su nuevo patrón para la construcción de objetos. Hace tiempo que aboga por no usar new pero también ha dejado de usar Object.create, de hecho ha dejado de usar this para evitar problemas de seguridad. También defiende que la herencia basada en prototipos es una mejor idea que las jerarquías clásicas. Porqué, las jerarquías son en general erróneas, y además suelen establecerse al principio del proyecto, cuando menos información se tiene de como debe ser.

Su patrón para la construcción de objetos tendría este aspecto


function constructor(spec) {
let {member} = spec,
{other} = other_constructor(spec),
method = function () {
// member, other, method
};

return Object.freeze({
method,
other
});
}

Donde

  • spec será generalmente un object literal, que permite inicializar el objeto
  • member será un miembro privado de la clase, no accesible desde el exterior
  • Esta construcción permite que se pueden llamar tantas veces como se quiera a otros constructores (other_constructor), de ese modo se obtiene herencia múltiple, y se pueden copiar, las funciones de interés de esos otros objetos en nuestro objetos
  • También puedo crear nuevos métodos (method), que tendrán acceso a los miembros privados, a otros métodos, a lo que proporcione other. En este caso method es público porque se devuelve al llamante pero con el mismo diseño podría ser un método privado
  • Se devuelve un nuevo objeto (el literal dentro de freeze, con todos los métodos de interés)
  • Lo congela para hacerlo inmutable, con todas las implicaciones que eso trae. Seguridad, comparaciones más sencillas, …
  • Comenta que este sistema tiene un costo en memoria. Al contrario que otras estrategias que reaprovechan los métodos, en esta method sería creado cada vez. Pero a cambio es muy rápido, porque no hay que recorrer el prototype chain para encontrar las claves si no que están directamente en el propio objeto

En otro momento, me gustaría hacer un artículo con los distintos patrones de creación de objetos de Javascript, pero debo decir que este me convence mucho, porque debe ser de las pocas veces que veo algo de este tema en JS que parece tener sentido a la primera. Lo que no comprendo es porque llama «constructor» a su función de ejemplo cuando en realidad es una «factory».


Aitor Guevara hablando de la arquitectura de Ducksboard

Posted: septiembre 26th, 2015 | Author: | Filed under: Sin categoría | Tags: , , , , | No Comments »

Un vídeo algo antiguo (2013) en el que Aitor Guevara (CTO de Ducksboard) nos habla de cual era la arquitectura de Ducksboard en aquel momento. A pesar de que el vídeo dura más de una hora y media Aitor consigue hacer amena una charla técnica. No entra al mínimo detalle técnico pero si da una buena idea general. Responde sin rubor a preguntas como cual era el costo de la infraestructura que tenían en Linode (400$) o cuantos clientes de pago tienen.

Por el medio de la charla caen perlas del estilo de:

  • Usamos twisted para hacer aplicaciones asíncronas en python. ¿Conoceis nodejs? pues lo mismo pero tiene 10 años en lugar de 1.
  • Usamos backbone, porque tenemos un montón de javascript. Tenemos un montón no porque nos guste si no porque es lo que hay.

Otra de las cosas que más me gustan es la defensa que hace de PostgreSQL, que es el componente central de su infraestructura (especialmente hacia el minuto 50 pero en realidad lo hace en varios momentos). Hacia el minuto 44 explica como usan ellos backbone. La verdad es que aquí no me quedo muy claro desde donde servían el html, o si iba todo en los templates, porque el django del frontend en principio sólo actuaba como API Rest sirviendo JSON al navegador. Eso si, su django usa SQLAlchemy y no django-orm porque tenían cosas en el postgres que django-orm no soporta.

Los últimos minutos de la charla presenta un par de herramientas que «análisis del negocio» que también son de interés.

En este post además del vídeo están las transparencias.


Video: Aplicaciones en tiempo real con python y postgres

Posted: agosto 25th, 2015 | Author: | Filed under: Sin categoría | Tags: , , , , , , , | No Comments »

Una charla de como montar aplicaciones en tiempo real con python y postgres. Tiempo real entendido como notificaciones de un chat, hacer algo cada vez que se actulice una tabla de la bd etc,…

El vídeo se hace un poco largo, seguramente con las transparencias llegaba para hacerse una idea general. Pero aún así se hace interesante por alguna de las técnicas que emplea:

  • Aboga por no usar frameworks en python. Con las librerías de hoy en día es sencillo montar una API Rest gestionando las llamadas de bajo nivel directamente
  • Usa las funciones de postgres de LISTEN y NOTIFY que combinadas con un trigger permiten que código cliente (psycopg2) sean notificados cuando algo pasa en la base de datos (se modifica una fila o lo que sea) y actuén en consecuencia (provocar un cambio en el navegador mediante websockets)
  • Para simplificar la API y el diseño de la bd, los datos se guardan como tipos nativos postgres (varchar, boolean,…), y se usa la función de postgres row_to_json para recuperarlos una cadena de texto con formato json.
  • Usa httpie para probar la API Rest. Si alguna vez usaste curl para esto enseguida verás que está bien conocer httpie.
  • A pesar de que la idea principal de la charla es montar una aplicación en tiempo real con el mínimo número de dependencias (complejidad) el proceso de build que monta no parece trivial. pip para dependencias en python, nodeenv (una especie de entorno virtual para node que se integra con el virtualenv de python), bower para las dependencias javascript de cliente,… Todo ello orquestrado por un Makefile.
  • No muestra como hacer la parte del frontend, pero en todo caso el código está en su repo

Canciones de Karaoke a partir de vídeos del Youtube

Posted: diciembre 24th, 2012 | Author: | Filed under: Sin categoría | Tags: , , , , , , | No Comments »

Llegan las fechas navideñas, lo que implica fiestas hogareñas y con ello, los amantes del Karaoke se vuelven más exigentes. Como hacer para quitar la voz a uno de esos vídeos de Youtube creados en plan Karaoke. Hagamos un ejemplo con En El mundo genial de las cosas que dices de Maldita Nerea. Si te gusta el disco y lo compras a través de este enlace
yo me llevo un porcentaje que motiva a seguir escribiendo ;).

El primer paso es buscar en youtube o similar un vídeo donde alguien se haya molestado en añadir la letra a la canción. Buscando en el propio youtube el título de la canción + karaoke se encuentran muchos, por ejemplo este.

A continuación descargaremos el vídeo, hay muchas formas de hacerlo, pero una de las más sencillas es a través de keepvid. Llega con poner la dirección del vídeo que queremos descargar, y aceptar la ejecución del applet de java. Pasado un ratillo nos dará la opción de descargar el vídeo en varios formatos. Cualquiera de los formatos es válido, en este ejemplo usaremos MP4.

Para quedarnos con el audio de la canción usaremos la línea de comandos por ser lo más sencillo. Aunque también se puede hacer de forma gráfica.

ffmpeg -i fichero_original.mp4 -acodec copy audio.aac

Para tratar de eliminar la voz del cantante de la parte instrumental del canción usaremos Audacity. Hay varios tutoriales por ahí, tanto usando el efecto vocal removal como un poco más manual. Como este proceso es muy rápido y sencillo, prueba los dos procedimientos y quedate con el que tenga más calidad. La voz no es completamente eliminada pero si se reduce bastante. Podemos exportar el audio al formato que queramos, ya que el original estaba en AAC, lo exportaremos a este.

Para recombinar audio y vídeo, volvemos a usar la línea de comandos. Con la siguiente orden le estamos diciendo que coja el audio del fichero audio_sin_voz.aac, lo mezcle con el vídeo del fichero original (el audio original será descartado automáticamente) y producirá un nuevo vídeo de salida respetando los codecs originales.

ffmpeg -i audio_sin_voz.aac -i fichero_original.mp4 -vcodec copy -acodec copy Maldita_Nerea-El_mundo_genial_de_las_cosas_que_dices.mp4

Puedes ver como queda en mi youtube.