
Mis códigos
Por aquí algunas de ideas que he empezado a explorar con los lenguajes de programación. Si usas el código en tus trabajos académicos puedes citarlo de esta forma:
Barreto, A. (fecha del código). Nombre del código [Notebook de Google Colab]. Google Colab. https://alexgbarreto.wixsite.com/vitae/projects-6
Transcripción Total con Whisper (22 de octubre 2025)
Este código en python utilizando google Colab, permite que descargues o cargues archivos y luego los transcribas utilizando modelos de IA.
# ============================================================
# 🎧 DESCARGA O CARGA + TRANSCRIPCIÓN AUTOMÁTICA CON WHISPER
# ============================================================
!pip install -q yt-dlp openai-whisper
from google.colab import drive, files
import yt_dlp
import os
import re
import time
import shutil
import glob
import whisper
import torch
# ============================================================
# 🔧 CONFIGURACIÓN INICIAL
# ============================================================
drive.mount('/content/drive')
drive_folder = "/content/drive/My Drive/YoutubeDownloads"
os.makedirs(drive_folder, exist_ok=True)
# ============================================================
# 🧩 FUNCIONES AUXILIARES
# ============================================================
def cuenta_regresiva(segundos, mensaje, default):
print(f"\n{mensaje} (esperando {segundos}s, valor por defecto: {default})")
for i in range(segundos, 0, -1):
print(f"{i}...", end=" ", flush=True)
time.sleep(1)
print("\n⏰ Tiempo agotado, seleccionando valor por defecto.")
return default
def limpiar_nombre(nombre):
"""Reemplaza caracteres especiales por '_'."""
return re.sub(r'[^A-Za-z0-9]', '_', nombre)
def generar_nombre_final(nombre, es_segmento=False):
"""Genera nombre corto según reglas del usuario."""
base = os.path.splitext(os.path.basename(nombre))[0]
base = limpiar_nombre(base)
if len(base) <= 10:
nuevo = base
else:
nuevo = base[:5] + "_" + base[-4:]
if es_segmento:
nuevo += "_seg"
final_path = os.path.join(drive_folder, nuevo)
# Evitar duplicados
contador = 1
while os.path.exists(final_path + os.path.splitext(nombre)[1]):
final_path = os.path.join(drive_folder, f"{nuevo}_{contador}")
contador += 1
return final_path
def formatear_tiempo_para_nombre(tiempo):
"""Convierte tiempos como 1:23:45 o 0:45 a formato 1h23m45s."""
partes = tiempo.split(':')
partes = [p.zfill(2) for p in partes]
if len(partes) == 3:
return f"{int(partes[0])}h{int(partes[1])}m{int(partes[2])}s"
elif len(partes) == 2:
return f"{int(partes[0])}m{int(partes[1])}s"
elif len(partes) == 1:
return f"{int(partes[0])}s"
return tiempo
def listar_resoluciones(url):
"""Lista resoluciones disponibles para un video de YouTube."""
ydl_opts = {'quiet': True}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=False)
formatos = []
for f in info['formats']:
if f.get('vcodec') != 'none' and f.get('acodec') == 'none':
res = f.get('height')
ext = f.get('ext')
if res:
formatos.append((res, ext))
formatos = sorted(list(set(formatos)), key=lambda x: x[0])
print("\n📺 Resoluciones disponibles:")
for i, (res, ext) in enumerate(formatos, start=1):
print(f"{i}. {res}p ({ext})")
return formatos
def descargar_video(url, tipo, resolucion=None, seccion=None):
"""Descarga contenido de YouTube con opciones personalizadas."""
with yt_dlp.YoutubeDL({'quiet': True}) as ydl:
info = ydl.extract_info(url, download=False)
titulo = limpiar_nombre(info.get('title', 'video'))
etiqueta_seccion = ""
if seccion:
inicio, fin = seccion.split('-')
inicio_fmt = formatear_tiempo_para_nombre(inicio)
fin_fmt = formatear_tiempo_para_nombre(fin)
etiqueta_seccion = f"_{inicio_fmt}-{fin_fmt}"
base_nombre = f"{titulo}{etiqueta_seccion}"
opciones = {
'outtmpl': f"{drive_folder}/{base_nombre}.%(ext)s",
'noplaylist': True,
'merge_output_format': 'mp4',
}
if tipo == "audio":
opciones.update({
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
})
elif tipo == "video_sin_audio":
opciones.update({'format': f'bestvideo[height={resolucion}]'})
elif tipo == "video_con_audio":
opciones.update({'format': f'bestvideo[height={resolucion}]+bestaudio/best'})
else:
print("❌ Tipo no válido.")
return None
if seccion:
opciones['download_sections'] = [f"*{seccion}"]
opciones['postprocessor_args'] = ['-ss', seccion.split('-')[0], '-to', seccion.split('-')[1]]
with yt_dlp.YoutubeDL(opciones) as ydl:
ydl.download([url])
# Buscar el archivo descargado
archivos = glob.glob(os.path.join(drive_folder, f"{titulo}*"))
if not archivos:
print("❌ No se encontró el archivo descargado.")
return None
archivo_descargado = max(archivos, key=os.path.getctime)
# Renombrar final según reglas
es_segmento = bool(seccion)
base_path = generar_nombre_final(archivo_descargado, es_segmento)
nuevo_nombre = base_path + os.path.splitext(archivo_descargado)[1]
shutil.move(archivo_descargado, nuevo_nombre)
print(f"\n✅ Archivo final: {nuevo_nombre}")
return nuevo_nombre
# ============================================================
# 🚀 INTERFAZ INTERACTIVA
# ============================================================
print("¿Deseas descargar un video de YouTube o cargar un archivo desde tu dispositivo?")
print("1. 🔽 Descargar de YouTube")
print("2. 📂 Cargar archivo manualmente")
modo = input("👉 Opción (1/2): ").strip()
archivo_final = None
if modo == "1":
url = input("🔗 Ingresa la URL del video de YouTube: ").strip()
print("\nElige el tipo de descarga:")
print("1. 🎵 Solo audio (mp3)")
print("2. 🎬 Solo video (sin audio)")
print("3. 📀 Video con audio")
opcion = input("👉 Opción (1/2/3): ").strip() or cuenta_regresiva(10, "Seleccionando tipo de descarga...", "1")
print("\n¿Deseas descargar todo el video o solo una parte?")
print("1. ⏯️ Todo el video")
print("2. ✂️ Solo una parte (indica tiempo de inicio y fin)")
parte = input("👉 Opción (1/2): ").strip() or cuenta_regresiva(10, "Seleccionando opción...", "1")
seccion = None
if parte == "2":
print("\nFormato de tiempo: 0:30 o 1:02:15 o 01:02:15")
inicio = input("⏱️ Desde (inicio): ").strip()
fin = input("🏁 Hasta (fin): ").strip()
seccion = f"{inicio}-{fin}"
tipo = "audio"
if opcion == "2" or opcion == "3":
resoluciones = listar_resoluciones(url)
if not resoluciones:
print("❌ No se encontraron resoluciones disponibles.")
else:
indice = input("\n📌 Elige el número de la resolución: ").strip()
if not indice:
print("⏰ Tiempo agotado, seleccionando 720p.")
resolucion = 720
else:
indice = int(indice) - 1
resolucion = resoluciones[indice][0]
tipo = "video_sin_audio" if opcion == "2" else "video_con_audio"
archivo_final = descargar_video(url, tipo, resolucion if opcion != "1" else None, seccion)
else:
print("\n📂 Carga tu archivo de audio o video (mp3, mp4, wav, etc.)")
subido = files.upload()
nombre = next(iter(subido))
es_segmento = False
base_path = generar_nombre_final(nombre, es_segmento)
nuevo_nombre = base_path + os.path.splitext(nombre)[1]
shutil.move(nombre, nuevo_nombre)
archivo_final = nuevo_nombre
print(f"✅ Archivo cargado y renombrado: {archivo_final}")
# ============================================================
# 🧠 TRANSCRIPCIÓN CON WHISPER
# ============================================================
if archivo_final:
modelo = input("\n🤖 Modelo de Whisper (tiny, base, small, medium, large): ").strip().lower()
if not modelo:
modelo = cuenta_regresiva(10, "Esperando modelo de Whisper...", "small")
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"\nCargando modelo Whisper '{modelo}' en {device}...")
model = whisper.load_model(modelo, device=device)
print("Transcribiendo...")
result = model.transcribe(archivo_final)
texto = result["text"]
base_txt = os.path.splitext(archivo_final)[0] + ".txt"
with open(base_txt, "w", encoding="utf-8") as f:
f.write(texto)
print("\n--- TRANSCRIPCIÓN ---\n")
print(texto)
print(f"\n✅ Transcripción guardada en: {base_txt}")
else:
print("❌ No se encontró archivo para transcribir.")
Descarga Video YT (12 de marzo de 2025)
Este código en python utilizando google Colab, permite que descargues un video de YT según tus necesidades para la investigación
# ============================================================
# DESCARGA INTERACTIVA DE VIDEOS DE YOUTUBE EN GOOGLE COLAB
# ============================================================
!pip install -q yt-dlp
from google.colab import drive
import os
import yt_dlp
import re
# Montar Google Drive
drive.mount('/content/drive')
# Carpeta donde se guardarán las descargas
drive_folder = "/content/drive/My Drive/YoutubeDownloads"
os.makedirs(drive_folder, exist_ok=True)
def limpiar_nombre(nombre):
"""Conserva solo los primeros 8 caracteres del título, reemplazando caracteres especiales."""
nombre_limpio = re.sub(r'[^A-Za-z0-9]', '_', nombre) # Reemplaza todo lo no alfanumérico
return nombre_limpio[:8] or "video" # Si queda vacío, usa "video"
def formatear_tiempo_para_nombre(tiempo):
"""Convierte tiempos como 1:23:45 o 0:45 a formato 1h23m45s."""
partes = tiempo.split(':')
partes = [p.zfill(2) for p in partes]
if len(partes) == 3:
return f"{int(partes[0])}h{int(partes[1])}m{int(partes[2])}s"
elif len(partes) == 2:
return f"{int(partes[0])}m{int(partes[1])}s"
elif len(partes) == 1:
return f"{int(partes[0])}s"
return tiempo
def listar_resoluciones(url):
"""Lista las resoluciones de video disponibles para una URL de YouTube."""
ydl_opts = {'quiet': True}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=False)
formatos = []
for f in info['formats']:
if f.get('vcodec') != 'none' and f.get('acodec') == 'none':
res = f.get('height')
ext = f.get('ext')
if res:
formatos.append((res, ext))
formatos = sorted(list(set(formatos)), key=lambda x: x[0])
print("\n📺 Resoluciones disponibles:")
for i, (res, ext) in enumerate(formatos, start=1):
print(f"{i}. {res}p ({ext})")
return formatos
def descargar_video(url, tipo, resolucion=None, seccion=None):
"""Descarga contenido de YouTube según las opciones dadas."""
# Obtener título del video para generar nombre corto
with yt_dlp.YoutubeDL({'quiet': True}) as ydl:
info = ydl.extract_info(url, download=False)
titulo = limpiar_nombre(info.get('title', 'video'))
etiqueta_seccion = ""
if seccion:
inicio, fin = seccion.split('-')
inicio_fmt = formatear_tiempo_para_nombre(inicio)
fin_fmt = formatear_tiempo_para_nombre(fin)
etiqueta_seccion = f"_{inicio_fmt}-{fin_fmt}"
# Base del nombre final
base_nombre = f"{titulo}{etiqueta_seccion}"
# Configuración general
opciones = {
'outtmpl': f"{drive_folder}/{base_nombre}.%(ext)s",
'noplaylist': True,
'merge_output_format': 'mp4',
}
# Opciones según tipo
if tipo == "audio":
opciones.update({
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
})
elif tipo == "video_sin_audio":
opciones.update({'format': f'bestvideo[height={resolucion}]'})
elif tipo == "video_con_audio":
opciones.update({'format': f'bestvideo[height={resolucion}]+bestaudio/best'})
else:
print("❌ Tipo no válido.")
return
# Si se solicita una parte del video
if seccion:
opciones['download_sections'] = [f"*{seccion}"]
# También forzamos el corte con ffmpeg en caso de streams
opciones['postprocessor_args'] = [
'-ss', seccion.split('-')[0],
'-to', seccion.split('-')[1]
]
# Descargar
with yt_dlp.YoutubeDL(opciones) as ydl:
ydl.download([url])
print(f"\n✅ Descarga completada y guardada en: {drive_folder}")
# ============================================================
# 🚀 INTERFAZ INTERACTIVA
# ============================================================
url = input("🔗 Ingresa la URL del video de YouTube: ").strip()
print("\nElige el tipo de descarga:")
print("1. 🎵 Solo audio (mp3)")
print("2. 🎬 Solo video (sin audio)")
print("3. 📀 Video con audio")
opcion = input("👉 Opción (1/2/3): ").strip()
print("\n¿Deseas descargar todo el video o solo una parte?")
print("1. ⏯️ Todo el video")
print("2. ✂️ Solo una parte (indica tiempo de inicio y fin)")
parte = input("👉 Opción (1/2): ").strip()
seccion = None
if parte == "2":
print("\nFormato de tiempo: 0:30 o 1:02:15 o 01:02:15")
inicio = input("⏱️ Desde (inicio): ").strip()
fin = input("🏁 Hasta (fin): ").strip()
seccion = f"{inicio}-{fin}"
if opcion == "1":
descargar_video(url, "audio", seccion=seccion)
elif opcion in ["2", "3"]:
resoluciones = listar_resoluciones(url)
if not resoluciones:
print("❌ No se encontraron resoluciones disponibles.")
else:
indice = int(input("\n📌 Elige el número de la resolución: ")) - 1
resolucion = resoluciones[indice][0]
tipo = "video_sin_audio" if opcion == "2" else "video_con_audio"
descargar_video(url, tipo, resolucion, seccion)
else:
print("❌ Opción no válida.")
Separar Demucs
Este código en python utilizando Google Colab, permite separar la voz, el bajo, la percusión y el resto de la pista en archivos separados. Útil para los músicos.
# ===============================================
# 🎧 Separación de pistas con Demucs en Colab
# (compatible con YouTube o archivos locales)
# ===============================================
import os
import shutil
import subprocess
from google.colab import files
from IPython.display import Audio
import re
# ==== CONFIGURACIÓN ====
from google.colab import drive
drive.mount('/content/drive')
# Carpeta base donde se guardarán los resultados
BASE_OUTPUT_DIR = "/content/drive/MyDrive/_Strings_Studio/Demucs/separated_audio"
os.makedirs(BASE_OUTPUT_DIR, exist_ok=True)
# ==== FUNCIONES ====
def limpiar_nombre(nombre):
"""Elimina caracteres problemáticos del nombre del archivo."""
base = os.path.basename(nombre)
seguro = re.sub(r'[^\w\-.]', '_', base)
limpio = os.path.join("/content", seguro)
if limpio != nombre:
os.rename(nombre, limpio)
return limpio
def detectar_dispositivo():
"""Detecta si hay GPU disponible."""
try:
result = subprocess.run("nvidia-smi", shell=True, capture_output=True, text=True)
if "NVIDIA" in result.stdout:
print("✅ GPU CUDA detectada, usando GPU.")
return "cuda"
else:
print("⚙️ No se detectó GPU, usando CPU.")
return "cpu"
except:
print("⚙️ No se detectó GPU, usando CPU.")
return "cpu"
def separar_audio(audio_path):
"""Ejecuta Demucs y separa el audio, guardando resultados en carpeta única."""
audio_path = limpiar_nombre(audio_path)
base_name = os.path.splitext(os.path.basename(audio_path))[0]
device = detectar_dispositivo()
# Crear carpeta específica para este archivo
output_dir = os.path.join(BASE_OUTPUT_DIR, base_name)
os.makedirs(output_dir, exist_ok=True)
print(f"\n🎧 Separando: {base_name}")
print(f"💾 Guardando resultados en: {output_dir}")
try:
comando = f'demucs -o "{output_dir}" --device {device} "{audio_path}"'
resultado = subprocess.run(comando, shell=True, capture_output=True, text=True)
if resultado.returncode != 0:
print("❌ Error al ejecutar Demucs:")
print(resultado.stderr)
return
except Exception as e:
print("⚠️ Error inesperado:", e)
return
# Buscar carpeta creada por Demucs dentro del output_dir
subcarpetas = [
os.path.join(output_dir, f)
for f in os.listdir(output_dir)
if os.path.isdir(os.path.join(output_dir, f))
]
if not subcarpetas:
print("⚠️ No se encontró carpeta de salida generada por Demucs.")
return
carpeta_modelo = subcarpetas[-1]
stems_subfolder = os.path.join(carpeta_modelo, os.listdir(carpeta_modelo)[0])
# Mover archivos resultantes a la carpeta principal específica
for archivo in os.listdir(stems_subfolder):
shutil.move(os.path.join(stems_subfolder, archivo), output_dir)
shutil.rmtree(carpeta_modelo, ignore_errors=True)
print(f"✅ Separación completada. Archivos guardados en:\n{output_dir}")
# ==== MENÚ DE OPCIONES ====
print("Selecciona una opción:")
print("1️⃣ Descargar audio desde YouTube")
print("2️⃣ Subir archivo desde tu computador")
opcion = input("Opción (1 o 2): ").strip()
audio_path = None
if opcion == "1":
# Descarga robusta con yt-dlp
!pip install -q yt-dlp
url = input("🔗 Ingresa la URL de YouTube: ").strip()
output_name = "input_audio.mp3"
print("⬇️ Descargando audio con yt-dlp...")
download_cmd = f'yt-dlp -x --audio-format mp3 -o "/content/{output_name}" "{url}"'
result = subprocess.run(download_cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print("❌ Error al descargar el audio de YouTube:")
print(result.stderr)
else:
print("✅ Audio descargado correctamente.")
audio_path = f"/content/{output_name}"
elif opcion == "2":
print("📁 Sube tu archivo de audio (.mp3, .wav, etc.)")
uploaded = files.upload()
audio_path = list(uploaded.keys())[0]
audio_path = f"/content/{audio_path}"
print("✅ Archivo subido:", audio_path)
else:
print("⚠️ Opción no válida.")
# ==== PROCESAR ====
if audio_path:
separar_audio(audio_path)
else:
print("⏹ No hay archivo para procesar.")
