Album Lofi con Python Version Cero

En este post, les presentaré un proyecto en el que he estado trabajando: un script de Python que genera automáticamente videos de música utilizando técnicas de inteligencia artificial y procesamiento de audio. A lo largo del artículo, desglosaré el código en secciones para explicar cómo funciona y cómo cada componente contribuye a la creación de estos videos.

EL codigo se ejecuto en Google colaboratory, por lo que se puede acceder a el en el siguiente enlace:

Open In Colab

Instalar librerias

En el primer segmento de código, se instalan las librerías y herramientas necesarias para ejecutar el script:

  1. imagemagick: Esta herramienta se utiliza para procesar y manipular imágenes en diferentes formatos.

  2. Se modifica el archivo de políticas de ImageMagick (/etc/ImageMagick-6/policy.xml) para permitir la lectura y escritura de imágenes.

  3. Se instalan varias librerías de PyTorch con versiones específicas:

    • torch: Es el paquete principal de PyTorch, una biblioteca de Python para aprendizaje profundo que se utiliza en este proyecto para implementar algoritmos de inteligencia artificial.
    • torchvision: Contiene utilidades para trabajar con imágenes y aplicar transformaciones en ellas, así como modelos preentrenados de visión por computadora.
    • torchaudio: Proporciona herramientas para trabajar con datos de audio y aplicar transformaciones de audio.
    • torchtext: Utilizado para procesar y manipular datos de texto.
    • torchdata: Facilita la carga y el preprocesamiento de conjuntos de datos.
  4. Se instala la librería xformers desde un enlace específico proporcionado. Esta librería contiene implementaciones de transformadores optimizados y eficientes para tareas de procesamiento de lenguaje natural y visión por computadora.

  5. Se instalan otras librerías adicionales como:

    • diffusers: Facilita la implementación de modelos de stable diffusion, que se utilizan en este proyecto para generar imágenes.
    • transformers: Contiene implementaciones de modelos de procesamiento de lenguaje natural basados en transformadores, como BERT y GPT.
    • ftfy: Es una biblioteca para limpiar y normalizar texto, corrigiendo errores comunes de codificación y formato.
    • pydub: Permite manipular archivos de audio de diferentes formatos.
    • accelerate: Proporciona una API para ejecutar modelos de aprendizaje profundo en múltiples dispositivos y aceleradores de hardware.
  6. Se instala la librería matchering, que se utiliza para procesar y masterizar archivos de audio, ajustando el sonido y la calidad de los archivos de música generados automáticamente.

  7. Finalmente, se instala pytube, una librería que permite descargar videos de YouTube en Python.

Este segmento de código se encarga de preparar el entorno de trabajo, asegurándose de que todas las dependencias necesarias estén instaladas antes de comenzar a trabajar con el script principal.

!apt install imagemagick -qq > /dev/null
!cat /etc/ImageMagick-6/policy.xml | sed 's/none/read,write/g'> /etc/ImageMagick-6/policy.xml
!pip install -q torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 torchtext==0.14.1 torchdata==0.5.1 --extra-index-url https://download.pytorch.org/whl/cu116 -U
!pip install -q https://github.com/camenduru/stable-diffusion-webui-colab/releases/download/0.0.17/xformers-0.0.17+b6be33a.d20230315-cp39-cp39-linux_x86_64.whl
!pip install -q -U diffusers transformers ftfy pydub accelerate
!pip install -q matchering
!pip install -q pytube
Es necesario reiniciar el entorno de ejecución de google Colab después de ejecutar las intalaciones de las librerias segmento de código. Esto se busca en el menu superior Entorno de ejecución > Reiniciar entorno de ejecución

Importar Librerias

Se importan las librerías necesarias para procesar imágenes, audio y utilizar algoritmos de aprendizaje profundo. numpy y PIL (Python Imaging Library) sirven para trabajar con imágenes y matrices numéricas, mientras que pydub, scipy.io.wavfile y torchaudio se utilizan para manipular y procesar archivos de audio. Por otro lado, matchering se emplea para masterizar el audio. Finalmente, torch y diffusers proveen las herramientas para implementar modelos de inteligencia artificial, como la stable diffusion en este caso.

import numpy as np
from PIL import Image
import pydub
from scipy.io import wavfile
import io
import typing as T
from pydub import AudioSegment
from IPython.display import Audio, display
import matchering as mg

import torch
from diffusers import StableDiffusionPipeline
import torchaudio

el paso siguiente es el encargado de cargar el modelo para generar la musica automaticamente:

  1. Se define una variable model_id2 que contiene la ruta del modelo preentrenado llamado “riffusion-model-v1”. Riffusion es una aplicación basada en stable diffussion para generar música en tiempo real Riffusion. Este modelo está diseñado específicamente para trabajar con espectrogramas, lo que permite generar música de diferentes estilos y géneros.

  2. Se crea un objeto pipe2 utilizando la clase StableDiffusionPipeline. La función from_pretrained carga el modelo preentrenado especificado por model_id2 y configura el tipo de datos a torch.float16. Al utilizar el tipo de dato de precisión mixta float16, se puede reducir el consumo de memoria y mejorar el rendimiento del proceso de generación de música.

  3. Por último, se mueve el objeto pipe2 a la GPU utilizando el método to("cuda"). Esto permite que el modelo se ejecute en la GPU, aprovechando su capacidad de procesamiento paralelo y acelerando las tareas de generación de música.

model_id2 = "riffusion/riffusion-model-v1"
pipe2 = StableDiffusionPipeline.from_pretrained(model_id2, torch_dtype=torch.float16)
pipe2 = pipe2.to("cuda")

Las siguientes funciones trabajan en conjunto para generar la musica música a partir de un modelo de Riffusion preentrenado, convirtiendo espectrogramas en archivos de audio y viceversa.

  1. get_music(audiofilename, prompt, musicAI_indx, duration=5): Esta función se utiliza para generar música a partir de un modelo preentrenado de Riffusion. La función toma como parámetros el nombre del archivo de audio, la entrada de texto (prompt), el índice del modelo y la duración deseada de la música. La función crea un espectrograma y luego lo convierte en un archivo de audio en formato WAV y MP3. Devuelve el espectrograma y el nombre del archivo MP3.

  2. wav_bytes_from_spectrogram_image(image: Image.Image) -> T.Tuple[io.BytesIO, float]: Esta función toma como entrada una imagen de espectrograma y devuelve un objeto io.BytesIO que contiene los datos del archivo de audio WAV reconstruido y la duración en segundos del audio. La función realiza la reconstrucción utilizando la transformada inversa de Mel y el algoritmo de Griffin-Lim.

  3. spectrogram_from_image(image: Image.Image, max_volume: float = 50, power_for_image: float = 0.25) -> np.ndarray: Esta función toma como entrada una imagen de espectrograma y devuelve un array de magnitud de espectrograma. La función realiza una serie de operaciones en la imagen, como invertir, cambiar el volumen máximo y aplicar una curva de potencia inversa.

  4. waveform_from_spectrogram(...) -> np.ndarray: Esta función toma como entrada un array de magnitud de espectrograma y devuelve una forma de onda reconstruida. La función utiliza la transformada inversa de Mel y el algoritmo de Griffin-Lim para aproximar la fase y reconstruir la forma de onda.

  5. mp3_bytes_from_wav_bytes(wav_bytes: io.BytesIO) -> io.BytesIO: Esta función toma como entrada un objeto io.BytesIO que contiene los datos del archivo WAV y devuelve un objeto io.BytesIO que contiene los datos del archivo MP3 convertido. La función utiliza la biblioteca pydub para realizar la conversión de WAV a MP3.

#@title functions
def get_music(audiofilename, prompt, musicAI_indx, duration=5):
    mp3file_name = f"{audiofilename}.mp3"
    wavfile_name = f"{audiofilename}.wav"
    if musicAI_indx == 0:
        if duration == 5:
            width_duration=512
        else :
            width_duration = 512 + ((int(duration)-5) * 128)
        spec = pipe2(prompt, height=512, width=width_duration).images[0]
        print(spec)
        wav = wav_bytes_from_spectrogram_image(spec)
        with open(wavfile_name, "wb") as f:
            f.write(wav[0].getbuffer())


        #Convert to mp3, for video merging function
        wavfile = AudioSegment.from_wav(wavfile_name)
        wavfile.export(mp3file_name, format="mp3")
        return spec, mp3file_name


def wav_bytes_from_spectrogram_image(image: Image.Image) -> T.Tuple[io.BytesIO, float]:
    """
    Reconstruct a WAV audio clip from a spectrogram image. Also returns the duration in seconds.
    """

    max_volume = 50
    power_for_image = 0.25
    Sxx = spectrogram_from_image(image, max_volume=max_volume, power_for_image=power_for_image)

    sample_rate = 44100  # [Hz]
    clip_duration_ms = 5000  # [ms]

    bins_per_image = 512
    n_mels = 512

    # FFT parameters
    window_duration_ms = 100  # [ms]
    padded_duration_ms = 400  # [ms]
    step_size_ms = 10  # [ms]

    # Derived parameters
    num_samples = int(image.width / float(bins_per_image) * clip_duration_ms) * sample_rate
    n_fft = int(padded_duration_ms / 1000.0 * sample_rate)
    hop_length = int(step_size_ms / 1000.0 * sample_rate)
    win_length = int(window_duration_ms / 1000.0 * sample_rate)

    samples = waveform_from_spectrogram(
        Sxx=Sxx,
        n_fft=n_fft,
        hop_length=hop_length,
        win_length=win_length,
        num_samples=num_samples,
        sample_rate=sample_rate,
        mel_scale=True,
        n_mels=n_mels,
        max_mel_iters=200,
        num_griffin_lim_iters=32,
    )

    wav_bytes = io.BytesIO()
    wavfile.write(wav_bytes, sample_rate, samples.astype(np.int16))
    wav_bytes.seek(0)

    duration_s = float(len(samples)) / sample_rate

    return wav_bytes, duration_s


def spectrogram_from_image(
    image: Image.Image, max_volume: float = 50, power_for_image: float = 0.25
) -> np.ndarray:
    """
    Compute a spectrogram magnitude array from a spectrogram image.
    TODO(hayk): Add image_from_spectrogram and call this out as the reverse.
    """
    # Convert to a numpy array of floats
    data = np.array(image).astype(np.float32)

    # Flip Y take a single channel
    data = data[::-1, :, 0]

    # Invert
    data = 255 - data

    # Rescale to max volume
    data = data * max_volume / 255

    # Reverse the power curve
    data = np.power(data, 1 / power_for_image)

    return data


def waveform_from_spectrogram(
    Sxx: np.ndarray,
    n_fft: int,
    hop_length: int,
    win_length: int,
    num_samples: int,
    sample_rate: int,
    mel_scale: bool = True,
    n_mels: int = 512,
    max_mel_iters: int = 200,
    num_griffin_lim_iters: int = 32,
    device: str = "cuda:0",
) -> np.ndarray:
    """
    Reconstruct a waveform from a spectrogram.
    This is an approximate inverse of spectrogram_from_waveform, using the Griffin-Lim algorithm
    to approximate the phase.
    """
    Sxx_torch = torch.from_numpy(Sxx).to(device)

    if mel_scale:
        mel_inv_scaler = torchaudio.transforms.InverseMelScale(
            n_mels=n_mels,
            sample_rate=sample_rate,
            f_min=0,
            f_max=10000,
            n_stft=n_fft // 2 + 1,
            norm=None,
            mel_scale="htk",
            max_iter=max_mel_iters,
        ).to(device)

        Sxx_torch = mel_inv_scaler(Sxx_torch)

    griffin_lim = torchaudio.transforms.GriffinLim(
        n_fft=n_fft,
        win_length=win_length,
        hop_length=hop_length,
        power=1.0,
        n_iter=num_griffin_lim_iters,
    ).to(device)

    waveform = griffin_lim(Sxx_torch).cpu().numpy()

    return waveform


def mp3_bytes_from_wav_bytes(wav_bytes: io.BytesIO) -> io.BytesIO:
    mp3_bytes = io.BytesIO()
    sound = pydub.AudioSegment.from_wav(wav_bytes)
    sound.export(mp3_bytes, format="mp3")
    mp3_bytes.seek(0)
    return mp3_bytes

funciones para crear audios para una lista de palabras

Las siguientes fucniones trabajan en conjunto para generar música a partir de una lista de palabras, aplicar efectos de audio como crossfade y fades, y mejorar la calidad de audio mediante la masterización automática.

  1. list_get_music(list_variables, texto_prompt, dur=5): Esta función toma una lista de cadenas de texto, un prompt y la duración de la música. Para cada cadena en la lista, genera música utilizando la función get_music con el prompt y la duración especificados. Los archivos de música generados se guardan con nombres basados en su índice en la lista.

  2. list_display_audio(list_variables): Esta función toma una lista de cadenas de texto y reproduce los archivos de audio generados previamente por list_get_music. Utiliza el módulo IPython.display.Audio para reproducir los archivos de audio en formato MP3.

  3. n_times(number_segments, n_times=3): Esta función toma el número de segmentos de audio y el número de repeticiones deseadas. Multiplica las repeticiones de cada segmento de audio y guarda los resultados en archivos WAV.

  4. n_times_segments(number_segments, n_times=3): Esta función toma el número de segmentos de audio y el número de repeticiones deseadas. Multiplica las repeticiones de cada segmento de audio y devuelve una lista de objetos AudioSegment con los segmentos repetidos.

  5. audio_segments_concat(songs_list, crossfade=2000, fade_in=2000, fade_out=3000, out_filename="full_song.wav"): Esta función toma una lista de objetos AudioSegment, valores de crossfade, fade in, fade out y un nombre de archivo de salida. Concatena los segmentos de audio con crossfade, aplica fade in al principio y fade out al final, y guarda el resultado en un archivo WAV.

  6. crear_fades(seg_inicial=0, seg_final=6, fade_in=3000, fade_out=3000): Esta función toma los índices de los segmentos inicial y final, y los valores de fade in y fade out. Aplica fade in al segmento inicial y fade out al segmento final, y guarda los resultados en archivos WAV.

  7. mejoras_audio(number_segments=7, master_reference='audio.mp4'): Esta función toma el número de segmentos de audio y un archivo de referencia de masterización. Convierte cada segmento de audio de mono a estéreo, aplica la masterización automática utilizando el archivo de referencia y guarda los resultados en archivos WAV. También elimina los archivos temporales creados durante el proceso.

from os import lstat
import os

def list_get_music(list_variables:list,
                   texto_prompt: str,
                   dur:int=5) -> None:
  """Toma una lista de strs y un prompt y genera sonidos son riffusion"""

  for number, str_var in enumerate(list_variables):
    prompt = f"{str_var} {texto_prompt}"
    get_music(f"{number}",prompt=prompt, musicAI_indx=0, duration=dur)


def list_display_audio(list_variables:list)->None:
  """display audio de los sonidos generados pro rifffussion"""

  for number, _ in enumerate(list_variables):
    display(Audio(f'{number}.mp3'))

def n_times(number_segments:int,
            n_times:int=3) -> None:
  """multiplicar las repeticiones de los audios y luego
  guardarlos"""

  for number in range(number_segments):
    song = AudioSegment.from_wav(f'{number}.wav')
    song = song *n_times
    song.export(f'{number}_times.wav',format='wav')

def n_times_segments(number_segments:int,
                     n_times:int=3) -> list:
  """multiplicar las repeticiones de los segmentos y luego
  concatenarlos en una lista"""

  songs_list = []
  for number in range(number_segments):
    song = AudioSegment.from_wav(f'{number}.wav')
    song = song *n_times
    songs_list.append(song)
  return songs_list

def audio_segments_concat(songs_list:list,
                          crossfade:int = 2000,
                          fade_in:int = 2000,
                          fade_out:int = 3000,
                          out_filename:str = "full_song.wav"):
  full_song = songs_list[0]
  for song_segment in songs_list[1:]:
    full_song = full_song.append(song_segment, crossfade=crossfade)

  # fade in y fade out
  full_song = full_song.fade_in(fade_in).fade_out(fade_out)
  #almacenar cancion
  full_song.export(out_filename,format='wav')
  print(f"Archivo {out_filename} almacenado")

def crear_fades(seg_inicial:int =0,
                seg_final:int = 6,
                fade_in:int = 3000,
                fade_out:int = 3000):

  inicial = AudioSegment.from_wav(f'{seg_inicial}_times.wav')
  inicial = inicial.fade_in(fade_in)
  inicial.export(f'{seg_inicial}_times.wav',format='wav')

  final = AudioSegment.from_wav(f'{seg_final}_times.wav')
  final = final.fade_out(fade_out)
  final.export(f'{seg_final}_times.wav',format='wav')

def mejoras_audio(number_segments:int=7,
                  master_reference:str = 'audio.mp4'):
  "Convertir audio Mono a Stereo y luego aplicar ,masterizacion automatica"

  for number in range(number_segments):
    song = AudioSegment.from_wav(f'{number}_times.wav')
    #convertir a stereo
    song = song.set_channels(2)
    song.export(f'{number}_stereo.wav',format='wav')

    mg.process(
      # The track you want to master
      target=f"{number}_stereo.wav",
      # Some "wet" reference track
      reference=master_reference,
      # Where and how to save your results
      results=[
        mg.pcm16(f"{number}_master.wav")
      ],
     )
    os.remove(f"{number}_stereo.wav")
    os.remove(f"{number}_times.wav")

Audios para la misma palabra

generacion de audios para la misma palabra

# Lista de variable generadora
word = "learning" #@param {type:"string"}
prompt = "lofi programming with python" #@param {type:"string"}
palabra = (f"{word} "*7).split()

Generar los audios con una lista variable y prompt fijo, y una duracion establecida de 10 segundos que es lo que permite la version gratuita de google colab.

list_get_music(palabra,prompt,10)

Mostrar los audios generados

list_display_audio(palabra)

Aumentar las duracion de los audios generados multiplicando por 3 para que queden de 30 Segundos

n_times(len(palabra), n_times=3)

Realizar fade in y fade_out a los arudios generados para crear transiciones suaves entre los audios.

crear_fades(0,6,3000,3000)

Descargar audio de referencia para realizar masterizacion automatica


from pytube import YouTube as YT
import threading as th
video   = YT('https://www.youtube.com/watch?v=NMKsn5puEsQ', use_oauth=True, allow_oauth_cache=False)
video.streams.get_by_itag(140).download()

Masterizar los audio automaticamente mediante el uso de la libreria de python Matchering

mejoras_audio(len(palabra), 'Bookoo Bread Co Instrumental - Scallops Hotel.mp4')

crear imagenes para el video

Este bloque de código es necesario para crear las imagenes que van en le video:

  1. Define una variable img_model_id que contiene la ruta del modelo preentrenado llamado “runwayml/stable-diffusion-v1-5”. Este modelo está diseñado para trabajar con imágenes y se basa en la difusión estocástica estable, lo que permite generar imágenes de alta calidad con una amplia variedad de estilos y temas.

  2. Crea un objeto img_pipe utilizando la clase StableDiffusionPipeline. La función from_pretrained carga el modelo preentrenado especificado por img_model_id y configura el tipo de datos a torch.float16. Al utilizar el tipo de dato de precisión mixta float16, se puede reducir el consumo de memoria y mejorar el rendimiento del proceso de generación de imágenes.

  3. A continuación, mueve el objeto img_pipe a la GPU utilizando el método to("cuda"). Esto permite que el modelo se ejecute en la GPU, aprovechando su capacidad de procesamiento paralelo y acelerando las tareas de generación de imágenes.

  4. Por último, se habilita la atención eficiente en memoria para los transformadores dentro del modelo utilizando el método enable_xformers_memory_efficient_attention(). Esta optimización permite reducir el consumo de memoria de la GPU durante la inferencia, lo que puede ser útil para generar imágenes de alta resolución o ejecutar el modelo en dispositivos con recursos limitados..

img_model_id = "runwayml/stable-diffusion-v1-5"
img_pipe = StableDiffusionPipeline.from_pretrained(img_model_id, torch_dtype=torch.float16, revision="fp16")
img_pipe = img_pipe.to("cuda")
img_pipe.enable_xformers_memory_efficient_attention()

Este bloque de código define una función llamada create_images que toma como argumentos una lista de cadenas de texto (list_variables) y un prompt de texto (text_prompt). La función tiene como objetivo generar imágenes a partir de los elementos en la lista de variables utilizando el modelo de difusión estocástica estable cargado previamente.

La función realiza las siguientes acciones:

  1. Itera sobre la lista de variables y sus índices utilizando enumerate(list_variables).

  2. Para cada variable en la lista, crea un prompt completo concatenando la variable y el text_prompt proporcionado. Así, el prompt completo incluye información adicional que guía al modelo para generar imágenes de alta calidad, como “artstation hall of fame gallery” y “editors choice”.

  3. Utiliza el objeto img_pipe previamente cargado para generar una imagen a partir del prompt completo. La función img_pipe devuelve un objeto que contiene una lista de imágenes, y selecciona la primera imagen de la lista con images[0].

  4. Guarda la imagen generada en un archivo PNG utilizando el índice de la variable en la lista como nombre de archivo (por ejemplo, “0.png”, “1.png”, etc.).

En resumen, esta función crea imágenes utilizando el modelo de stable diffusion a partir de una lista de variables y un prompt de texto, y guarda las imágenes generadas en archivos PNG.

def create_images(list_variables:list,
                  text_prompt:str)->None:

  for number, str_var in enumerate(list_variables):
    prompt = f"{str_var} {text_prompt}"
    image = img_pipe(prompt + ", artstation hall of fame gallery, editors choice, #1 digital painting of all time, most beautiful image ever created, emotionally evocative, greatest art ever made, lifetime achievement magnum opus masterpiece, the most amazing breathtaking image with the deepest message ever painted, a thing of beauty beyond imagination or words").images[0]
    image.save(f"{number}.png")

Crear las imagenes para el video

create_images(palabra*2, prompt)

Visualizar las imagenes generadas

from IPython.display import Image as display_image
imagenes2 = [f"{x}.png" for x in range(7)]
for img in imagenes2:
  display(display_image(filename=img))

Crear Video final

Este código crea un video de 1900x1080 a partir de una serie de imágenes y segmentos de audio, aplicando efectos de transición y redimensionamiento, y añadiendo un fondo negro y texto al video final.

  1. Crear una imagen negra base de tamaño 1900x1080 píxeles y la guarda como ‘black.jpg’. Esta imagen se utilizará como fondo en el video final para que quede de gran resolucion.

  2. Importa las bibliotecas necesarias para el procesamiento de video y audio, como moviepy.editor, pathlib.Path y moviepy.video.fx.resize.

  3. La función creacion_video_segmentos(numero_segmentos) toma el argumento numero_segmentos que indica la cantidad de segmentos de audio e imágenes a utilizar. La función crea una lista de clips de video, donde cada clip consiste en una imagen y su correspondiente segmento de audio. La lista de clips de video se devuelve al final de la función.

  4. La función Final_concatenar_crossfade(lista_videos, custom_padding=1, nombre='lofi') toma una lista de clips de video, un valor de relleno personalizado y un nombre para el video final. Esta función crea un video final mediante las siguientes acciones:

    a. Aplicar una transición de deslizamiento a cada clip de video en la lista y concatena los clips con un relleno negativo, lo que crea un efecto de crossfade entre los clips.

    b. Redimensiona el video resultante a 1080x1080 píxeles y coloca el fondo negro creado previamente detrás de este video.

    c. Añade un texto con el nombre del video en una posición específica.

    d. Combina el video y el texto en un solo objeto de video y establece la duración del video final.

    e. Escribe el video final en un archivo MP4 con el nombre proporcionado, utilizando 24 fotogramas por segundo y el códec de audio ‘aac’.

#crear imagen negra base
from PIL import Image;
Image.new('RGB',
          (1900, 1080),
          color = (0,0,0)).save('black.jpg')
from moviepy.editor import *
from pathlib import Path
from moviepy.video.fx.resize import resize
def creacion_video_segmentos(numero_segmentos:int) -> list:
  video_clips = []

  #list images files
  for number in range(numero_segmentos):
    clip_audio = AudioFileClip(f"{number}_master.wav").set_start(0)
    clip_video = ImageClip(f"{number}.png", duration=clip_audio.duration)
    clip_video = clip_video.set_audio(clip_audio)
    video_clips.append(clip_video)
  return video_clips

def Final_concatenar_crossfade(lista_videos:list,
                         custom_padding:int=1,
                         nombre:str = 'lofi'):

  slided_clips = [CompositeVideoClip([clip.fx( transfx.slide_out, custom_padding, 'bottom')]) for clip in lista_videos]
  video_slides = concatenate( slided_clips, padding=-1)
  video_slides = resize(video_slides, width=1080, height=1080)
  black_image = ImageClip("black.jpg")
  final = CompositeVideoClip([black_image, video_slides.set_position("center")])
  final = final.set_duration(video_slides.duration)

  ## Todo Agregar el NOmbre de la cancion

  # create a TextClip object with the desired text
  text_clip = TextClip(nombre,
                       font="Amiri-regular",
                       fontsize=40,
                       color='grey40')
  # set the position of the text clip
  text_clip = (text_clip
               .set_position((100, 900))
               .set_start(0)
              )
  final = CompositeVideoClip([final, text_clip])

  # FINAL ASSEMBLY
  final_video_audio = CompositeVideoClip([final, text_clip]).set_duration(video_slides.duration)

  final_video_audio.write_videofile(f"{nombre}.mp4",
                              fps=24,
                              threads = 2,
                              audio_codec='aac',
                              audio=True)

Codigo para crear cada uno de los segmentos de audio

lista_videos = creacion_video_segmentos(7)

Creacion Final del video concatenando los segmentos generados anteriormente

# Creacion del video Final
concatenar_crossfade(lista_videos,1, word)

En este post, hemos explorado cómo utilizar un modelos de stable diffusion para generar musica e imágenes a partir de una lista de variables y un prompt de texto. A continuación, hemos utilizado la biblioteca MoviePy para combinar estas imágenes con segmentos de audio correspondientes y crear un video con transiciones suaves y efectos de redimensionamiento.

Este proceso ilustra cómo es posible combinar técnicas de inteligencia artificial y procesamiento de video para crear productos audiovisuales únicos y personalizados a partir de elementos individuales como imágenes y segmentos de audio.

Proximo Album

  • Estos videos generados solamente tienen imagenes estaticas, el proximo album sera un videos con imagenes dinamicas.
  • El audio de riffusion todavia tiene limitaciones de calidad, el proximo album sera con una nueva herramienta de generacion de audio como https://github.com/facebookresearch/audiocraft
  • MoviePy es una herramienta para automatizar la creacion de videos.

Referencias

Previous
Next