INVERSIÓN DE IMAGEN EN VÍDEOS CON PYTHON Y FFMPEG.

FFmpeg es una excelente herramienta a través de la cual podemos efectuar un amplio abanico de acciones relativas a la manipulación y edición de archivos de vídeo y audio, y aunque ya hemos hablado de esta en artículos anteriores, aún son muchas las posibilidades que ofrece y que nos queda por cubrir. Por ello, hoy vamos a ver como podemos usarla para invertir la imagen (tanto en horizontal como en vertical) de un archivo de vídeo. Para nuestro ejercicio, usaremos como ejemplo el archivo «traffic.mp4» y la implementación en Python de «FFmpeg» que deberemos instalar previamente en nuestra computadora:

Captura de «traffic.mp4»

INVERSIÓN HORIZONTAL.

La primera operación que vamos a realizar es la es el de cambiar la orientación horizontal de la imagen de nuestro video. FFmpeg, nos permite hacer esto en tan solo unas pocas líneas de código, usando «hflip()» para realizar la inversión:

OUTPUT:

Captura de «traffic_inv.mp4»

INVERSIÓN VERTICAL.

Del mismo modo podemos también, invertir verticalmente la imagen del video. Para ello seguiremos la misma secuencia que en el caso anterior solo que en este caso, usando la función «vflip()«:

OUTPUT:

Captura de «traffic_inv2.mp4»

INVERSIÓN CON AUDIO.

Cuando trabajamos con videos en los que haya audio, para conservar este, debemos especificar una variable a parte en la que se almacenará dicho audio (la extracción del audio la realizaremos con el método «.audio«) de modo que incorporemos dicho audio, al final del proceso, cuando usamos la función «.output()«. En este caso, almacenaremos la información relativa al audio y al video, por separado, en las variables «audio» y «stream» respectivamente:

Lo que nos generará un video de imagen invertida, solo que esta vez, conservando su correspondiente audio.

Tal y como señalamos al comienzo de este artículo, son muchas las posibilidades que, en materia de manipulado de archivos de video y audio, las que ofrece «FFmpeg«, las cuales, iremos desarrollando en futuras entradas del blog.

Saludos.

TECLADO MUSICAL (PASO A PASO) CON PYTHON Y «pydub».

Hace un par de semanas, estuvimos viendo el modo de generar tonos de audio haciendo uso de la librería «pydub» (la cual instalamos mediante el comando «pip install pydub«). Lo que hoy nos proponemos hacer es poner en practica los conocimientos adquiridos entonces para crear un sencillo teclado musical (usando «tkinter«) de dos octavas como el que mostramos a continuación:

Como siempre, lo primero que haremos es importar los recursos que vamos a necesitar, recordando que debemos instalar previamente tanto la librería «pydub» como el software «ffmpeg«:

Importados los recursos que vamos a emplear, pasaremos a crear nuestro teclado, empezando por definir sus dimensiones, título y color:

A continuación, procedemos a introducir los distintos elementos de nuestro teclado, empezando por las teclas blancas (usando la función «Button»):

Pasando a continuación a hacer los mismo con las teclas negras:

A partir de ahora, nuestra labor será la de hacer que nuestro teclado emita un sonido para cada tecla, pudiendo a su vez variar una serie de características tales como la duración de cada nota, el tipo de onda, la amplitud de esta, el volumen y el desvanecido tanto inicial como final. Para poder estableces tales parámetros, necesitaremos incluir una serie de elementos en nuestra interfaz:

En este bloque, nos hemos encargado de introducir los elementos gráficos. Concretamente un «Entry» para establecer la duración en milisegundos de cada nota (para lo cual también hemos creado la variable «self.duration«) que establecemos en 1000 como valor predeterminado), un «comboBox» en el que mostraremos las posibles formas de onda que podrá adoptar nuestro sonido (las cuales se almacenan en la variable «self.WaveForms«) y cuatro «sliders» con los que podremos regular el volumen, la amplitud (ganancia) y el desvanecido inicial y final (para estos parámetros crearemos también las respectivas variables). Si ejecutamos ahora obtenemos el siguiente resultado:

A su vez, nos hemos asegurado que en le campo «DURATION:» únicamente puedan introducirse valores enteros, para lo que hemos creado la variable «validatecommand» y la función «self.valid_duration()«:

Ya tenemos los elementos mediante los cuales podemos configurar la sonoridad de nuestro teclado, ahora hace falta hacerlo sonar. Para ello crearemos una función a la que hemos llamado «self.make_tone()» que generará nuestra nota en función del tipo de onda, duración y frecuencia (la cual será única para cada tecla y que definiremos más adelante):

A su vez, para evitar que al tocar una nota la ventana se nos pueda quedar congelada, usaremos una nueva función «self.init_task()» que ejecutará (con un «Thread«) la función anterior como un subproceso en paralelo:

Esta es la función que conectaremos directamente con cada uno de los «Button» correspondientes a cada tecla y que tomará como argumento, ahora sí, el valor correspondiente a la frecuencia de cada nota. Valor que especificaremos a través de la correspondiente función «lambda()» tanto para las teclas blancas como para las negras:

Y con ello tendríamos creado nuestro sencillo teclado musical cuyo código completo podéis consultar en el siguiente enlace:

https://github.com/antonioam82/MusicKeyBoard-/blob/main/KeyBoard.py

Saludos.

GENERACIÓN DE TONOS DE AUDIO CON «pydub».

En artículos anteriores hemos visto ya las posibilidades que ofrece la librería «pydub» a la hora de manipular y editar archivos de audio. Posibilidades las cuales no se limitan al manipulado de archivos de audio preexistentes, sino que se extiende a la posibilidad de generar (a través del módulo «pydub.generators«) dichos audios de un modo sencillo. No obstante, antes de nada, debemos empezar instalándonos (si no lo hemos hacho ya) la librería «pydub» («pip install pydub«) la cual hace uso del software «ffmpeg» cuyo proceso de instalación podéis ver en el siguiente vídeo:

Una vez que tengamos todo listo, podemos empezar a generar nuestros archivos de audio, que en este caso van a consistir en tonos de 3 segundos de duración, a una frecuencia de 440Hz para cada una de las formas de onda que se muestran a continuación:

Una vez fijado el objetivo de nuestra práctica, empezaremos importando los recursos que vamos a necesitar:

Como se ve, la totalidad de los recursos que importamos pertenecen a la librería «pydub«. Así, importamos «AudioSegement» para trabajar con archivos de audio, usamos «pydub.generators» para generar audio con distintas formas de onda (Sine, Square, Triangle y Sawtooth) y «pydub.playback» para reproducir el tono generado. Importado todo lo necesario, pasaremos a generar nuestros tonos:

Tal y como e puede aprecia, para los 4 tonos usamos la sintaxis en la que solo varía el método para generar los diferentes tipos de onda («Sine«, «Square«, «Triangle» y «Sawtooth«) y en los que introducimos como argumentos la frecuencia (440Hz) y la duración en milisegundos («duration=3000«).

Con esto tendríamos generados nuestros tonos e audio, desde aquí, para reproducir cualquiera de ellos simplemente emplearíamos la función «play()«:

A su vez, podemos usar la función «append()» para generar un audio que en el que se encadenen los tonos creados anteriormente:

Generados todos nuestros tonos, podemos proceder a almacenarlos en nuestro equipo mediante el método «export()» al que pasaremos el nombre que queramos para el archivo y su formato (que será «.wav» para todos los audios excepto para el «mutitone» que almacenaremos en formato «mp3«:

Partiendo de estos conocimientos, podemos ir más allá y crear una sencilla (y minimalista) interfaz gráfica que nos permita generar audios en distintas formas de ondas, introduciendo la duración en milisegundos y la frecuencia. El código de dicha aplicación podría ser el que se encuentra en el siguiente enlace y en cuyo repositorio tenéis la carpeta «wave_tones.zip» con los audios generados en este ejercicio:

https://github.com/antonioam82/sound-writters/blob/master/some_basic_tones.py

Saludos.

EXTRAYENDO INFORMACIÓN DE ARCHIVOS DE VÍDEO, EN PYTHON, CON «ffmpeg».

Sucede en ocasiones, que estamos elaborando alguna aplicación que haga uso o manipule de alguna manera, archivos de vídeo. Siendo a veces, necesario el contar con determinada información sobre el archivo de vídeo usado, como puede ser el tamaño, dimensiones o el «frame rate» del mismo. Pues bien, en esta ocasión , vamos a ver como podemos obtener las características de un vídeo, mediante el software de «ffmpeg» y «ffmpeg-python«. Por su parte, dado que vamos a usar el software de «ffmpeg» deberemos instalarlo previamente en nuestra computadora. Para los que puede ser de ayuda el siguiente vídeo:

Una vez instalado «ffmpeg» pasaremos a instalar, mediante el comando pip, la librería «ffmpeg-python«:

Hecho esto, podemos pasar ya a obtener la información de un archivo de vídeo, mediante un procedimiento muy sencillo:

Como se ve, empezamos importando «ffmpeg» para «python«, para a continuación usar el método «.probe()» para indicar el vídeo cuyas dimensiones queremos extraer (esto lo hacemos introduciendo la ruta al mismo, como puede verse) para, finalmente extraer su información, la cual se almacenará en la variable «video_streams«.

Y ya solo nos resta imprimir la información. Para hacerlo de modo que esta salga ordenada, usaremos «pprint» (importando primero dicho módulo y usando «pprint.pprint()«:

Visualizando, de este modo, toda la información del vídeo que podamos necesitar.

Saludos.

CONVERSOR DE ARCHIVOS DE AUDIO CON TKINTER Y «pydub».

Hace un tiempo hicimos una primera aproximación a «librosa«, una librería orientada al manejo y análisis de archivos de audio (de la que volveremos a hablar próximamente). En aquella ocasión hicimos referencia a la necesidad de que el archivo de audio a analizar estuviese en un formato descomprimido (por ejemplo «wav» o «ogg«). Para ello teníamos que contar con un archivo de audio en dicho formato. En este punto, una cosa que podemos hacer es convertir a dicho formato algún archivo que ya tengamos. Para ello podemos hacer uso de cualquiera de los conversores de audio que hay online…Aunque también podemos programar nuestro propio conversor que nos permita exportar un archivo de audio a diferentes tipos de formatos de un modo rápido, mediante la selección del archivo que queremos convertir y el formato (también de audio) al que queremos exportarlo (conservando el original). Esto lo haremos con una sencilla interfaz elaborada con «tkinter» que tendrá este aspecto:

Como se ve, la interfaz consta de una etiqueta de fondo negro (que en cada momento reflejará el nombre del archivo de audio que vamos a exportar), un botón («BUSCAR ARCHIVO«) con el que, haremos la búsqueda y selección del archivo que queremos exportar, un conjunto de 8 botones con los que seleccionaremos el formato («wav«,»ogg«,»mp3«,»flv«…) al que queremos exportar el audio previamente seleccionado y finalmente un botón («CARPETA DESTINO«) con el que podremos seleccionar la carpeta en la que se generará el archivo exportado (que por defecto será aquella en la que se encuentre alojado el programa).

Pasemos a la elaboración de nuestra aplicación: Como ya sabrán, lo primero es, siempre, realizar la importación de los módulos, librerías y demás recursos que vayamos a necesitar:

Entre dichos recursos cabe destacar «tkinter» (con la que elaboraremos la interfaz de la aplicación) y la librería «pydub» con la que realizaremos la acción de conversión-exportado de nuestro audio a otro formato. Cabe recordar que esta última funciona con el software de «ffmpeg» por lo que antes de instalarla (con el comando «pip«) deberemos proceder, también, a la instalación de dicho software.

Una vez que contemos con todos los recursos necesarios instalados. Pasaremos a la elaboración de nuestro programa, empezando, claro está, por la interfaz del mismo, definiendo también ciertas variables iniciales:

Así, creamos la ventana («root = tkinter.Tk()«), en la cual, iremos incluyendo los distintos elementos de interacción (fundamentalmente «Button«, «Label» y «Entry«), terminando con la correspondiente función «mainloop()» («root.mainloop()«). Antes de ello, ejecutaremos ya una primera función («dire()«) cuya misión será mostrar en la parte superior, el directorio de ejecución:

Como el propósito de nuestra aplicación es el de exportar un archivo de audio en un formato determinado a otro formato (también de audio). Lo primero que tenderemos que proporcionarle, es una función a través de la cual se pueda (navegando por el sistema de carpetas) seleccionar dicho archivo. Esa tarea la llevará a cabo la función «buscar_archivo()«:

Lo primero que hará esta función es cambiar el texto de la etiqueta «etiName» de «NINGÚN ARCHIVO SELECCIONADO» a «IMPORTANDO ARCHIVO…«. Para la búsqueda, usaremos la el método «askopenfilename()» al que pasaremos el conjunto de extensiones (en este caso de audio) entre las que podremos hacer la selección. Una vez completada la búsqueda (es decir que se haya seleccionado algún archivo y por lo tanto «ruta != «») extraeremos del string «ruta» el último elemento dentro de la lista resultante de aplicarle (al string) el método «split()» usando el símbolo «/» como separador. El referido elemento extraído no es otro que el nombre del archivo de audio que queremos exportar (de donde diferenciaremos el nombre «nom» y la extensión «ex» con «os.path.splitext()» (la razón de esto último la veremos en el estudio de la siguiente función) . Por su parte si resulta que no se cumple la condición «ruta != «»» (es decir que «ruta == «»«) el texto de «etiName» volverá a su estado original, y no se procederá a la ejecución de la siguiente función («abrir_archivo()«):

La primera condición que establece esta función, es que la extensión del archivo seleccionado en el paso anterior («ex«) se encuentre en la lista «formatos» (dicha lista es una de las variables iniciales que definimos al crear la ventana) que alberga los formatos de audio que puede anejar nuestro programa. Así, si no se da tal condición, usaremos el método «showwarning()» con el texto «Formato no soportado». Por contra, si resulta que sí se cumple la condición («ex in formatos») el programa procederá a cargar el archivo mediante el método «AudioSegment» correspondiente a la extensión «ex» del archivo que se quiera cargar, que vimos cundo hablamos de la librería «pydub«. A su vez, enmarcamos esta acción en un «try«. La razón de ello, es que existe la posibilidad de que se interrumpiese el proceso, por ejemplo, al cerrar la consola de «ffmpeg» que se muestra durante el mismo. En tal caso, «except:» se mostraría una nueva ventana de error, y las variables «nom» y «audio» (variable está que contendrá el archivo de audio ya cargado) volverían a su estado original.

El programa mostrará, en cada momento el nombre del archivo que vamos a convertir.

En este punto, si la carga se ha completado sin interrupciones, nuestro audio estará ya listo para ser exportado a otro formato (dejando siempre el archivo original, intacto) para ello, el usuario solo tendrá que pinchar en uno de los 8 botones de color rojo, en función del formato en el que quiere se se genere el nuevo archivo. Para ello, incluiremos en la definición de cada botón un «command» que active una función a la que hemos llamado «inicia()» que consistirá en la activación de un proceso paralelo («threading.Thread()«) consistente en la ejecución de la función destinada a realizar la conversión de formato:

Como se ve, la función que a partir de ese momento se va ejecutar, es la llamada «convert()«:

Como se ve, lo primero que hace la función es comprobar si la variable «audio» contiene alguna información (lo que pasará solo si el proceso de carga realizado por «abrir_archivo()» se ha completado satisfactoriamente). De ser así, la etiqueta ubicada debajo de la principal, mostrará el texto «PROCESO EN CURSO…«, para a continuación, llevar a cabo la operación, con el método «.export()» al que pasaremos el nombre del archivo original (el que vamos a exportar) y la extensión («format=ty«) correspondiente al nuevo formato deseado y definido como argumento de la función «lambda» definida en el «command» de cada uno de los botones de formato. En este punto cabe destacar el uso de una variable «executing» que, al iniciarse la ejecución de esta función, torna su valor a «True«. La razón de ello, es que la mayoría de funciones asociadas a algún botón, solo se ejecutarán si el valor de esta variable es «False«. Con esto se evita la ejecución de otras funciones mientras esta este funcionando, evitando posibles conflictos entre procesos (por ello, una vez que termine de ejecutarse «convert()» «executing» retornará al valor «False«, desbloqueando el resto de funciones.

Al terminar el proceso, la etiqueta inferior mostrará un mensaje con el nombre del nuevo archivo creado.

Una vez completado este proceso, se generará un nuevo archivo de audio, con el mismo nombre que el original pero, obviamente, con la extensión correspondiente al formato deseado. El archivo se generará en la ubicación del programa, a no ser, que hayamos especificado una ubicación diferente, lo cual, podrá hacerse con el botón «CARPETA DESTINO«, que activará la función «cambia_dir()«:

El proceso aquí es muy sencillo: Siempre que «executing==False» la variable «directorio» almacenará la ubicación de la carpeta deseada para alojar el nuevo archivo, a la que podremos acceder y seleccionar con «filedialog.askdirectory()«, para que si «directorio» tiene algún valor, (lo que no sucederá, por ejemplo si cerramos el navegador de carpetas sin haber seleccionado ninguna ubicación) usar «os.chdir()» para cambiar el directorio de ejecución (y por tanto cambiar el directorio en el que se generará el nuevo archivo). Finalmente, reflejaremos este cambio, en la parte superior de la ventana con «currentDir.set(os.getcwd())«, donde «currentDir» es el nombre que hemos dado al «entry» de la parte superior y «os.getcwd()» la función con la que obtenemos el directorio actual.

Finalmente, y como viene siendo habitual en estos casos, podéis consultar el código completo del programa en el siguiente enlace:

https://github.com/antonioam82/AudioFile_Converter/blob/master/audioFile_converter.py

Saludos.

COMBINAR AUDIO Y VÍDEO EN PYTHON, CON «mhmovie».

A lo largo de las muchas entradas del blog, hemos elaborado gran cantidad de programas y usado un buen número de funciones y métodos encargados de generar distintos tipos de archivos. Dentro de estos, han estado, como no podía ser de otro modo, los archivos de audio y de vídeo (por separado) en sus distintos formatos. No obstante, en ocasiones, es posible que queramos que nuestro programa nos genere un archivo multimedia en el que se incorpore vídeo y audio (en un solo archivo). Para hacer esa labor más sencilla contamos con una librería, basada en el software «ffmpeg«, llamada «mhmovie«, que instalaremos de modo sencillo, con el comando «pip» que ya conocemos:

A su vez, y dado que como hemos señalado más arriba, «mhmovie» funciona con el software de «ffmpeg«, que duda cabe que necesitaremos tener este instalado, previamente, en nuestra computadora. Dicha instalación la hicimos en su momento, para hacer uso de la librería «pydub«, para lo cual, nos fue de gran ayuda un videotutorial que volvemos a dejar a continuación:

Tutorial para la descarga de «ffmpeg» en Windows.

Bien, una vez que tengamos instalado todo lo necesario para la ocasión, vamos a pasar a crear nuestro archivo de audio y vídeo, partiendo de dos archivos (uno de vídeo, de nombre «temp_video.avi» y otro de audio llamado «temp_audio.wav«) creados previamente y de igual duración, los cuales tendremos alojados en nuestro directorio de ejecución:

Así, empezaremos abriendo nuestro editor, e importando nuestra librería «mhmovie«:

Tras ello, pasaremos a cargar, por separado los archivos de partida, haciendo uso de los métodos «.music()» (para el archivo de audio, al que asignaremos la variable «aud«) y «.movie()» (para el caso de la parte de vídeo, que asignaremos a la variable «vid«):

Cargados ambos archivos, pasaremos a combinarlos simplemente mediante la suma de sus correspondientes variables asociadas («aud» y «vid«). Asociando el resultado de la operación a una nueva variable de nombre «result«:

Hecha esta última operación ya solo nos falta guardar el contenido de «result» en un archivo (con la misma extensión que el archivo de vídeo usado). Para ello utilizaremos la función «.save()» a la que, naturalmente, pasaremos el nombre que queramos para nuestro nuevo archivo:

Una vez completada esta sencilla secuencia de pasos, aparecerá nuestro archivo de vídeo con audio (al que hemos llamado «ResultVideo.avi«) en nuestro directorio de ejecución, tal y como se ve en la imagen:

Así, con este sencillo procedimiento que nos proporciona «mhmovie» y «ffmpeg«, ya nunca tendremos dificultades para crear un archivo de vídeo con audio incorporado.

Saludos.