Spaces:
Running
Running
# -*- coding: utf-8 -*- | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import librosa | |
import librosa.display | |
from pydub import AudioSegment | |
import subprocess | |
import gradio as gr | |
# Encabezado personalizado para Gradio | |
encabezado = """ | |
Este programa permite analizar un archivo de audio (.mp3 o .wav) mediante la Transformada Rápida de Fourier (FFT) y la generación de un espectrograma. | |
Desarrollado por José R. Leonett, para el Grupo de Peritos Forenses Digitales de Guatemala www.forensedigital.gt | |
""" | |
def obtener_info_audio(archivo_audio): | |
""" | |
Obtiene información técnica del archivo de audio usando ffprobe. | |
""" | |
try: | |
resultado = subprocess.run( | |
["ffprobe", "-v", "error", "-show_format", "-show_streams", archivo_audio], | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE, | |
text=True | |
) | |
if resultado.returncode != 0: | |
return "Error al obtener información del archivo de audio." | |
return resultado.stdout | |
except Exception as e: | |
return f"Error: {e}" | |
def analizar_transcodificacion(info_audio): | |
""" | |
Analiza si el archivo está transcodificado comparando el codec con el formato. | |
""" | |
if not info_audio: | |
return "No se pudo obtener información del archivo." | |
codec = None | |
formato = None | |
for linea in info_audio.split("\n"): | |
if linea.startswith("codec_name="): | |
codec = linea.split("=")[1] | |
if linea.startswith("format_name="): | |
formato = linea.split("=")[1] | |
if codec and formato: | |
if codec.lower() == formato.lower(): | |
return f"El archivo NO está transcodificado. El codec '{codec}' coincide con el formato '{formato}'." | |
else: | |
return f"El archivo ESTÁ transcodificado. El codec '{codec}' NO coincide con el formato '{formato}'." | |
else: | |
return "No se pudo determinar si el archivo está transcodificado." | |
def procesar_audio(archivo_audio): | |
# Cargar el archivo de audio | |
y, sr = librosa.load(archivo_audio, sr=None) # sr=None mantiene la frecuencia de muestreo original | |
# Obtener información técnica del archivo | |
info_audio = obtener_info_audio(archivo_audio) | |
info_audio_str = "\nInformación técnica del archivo:\n" + info_audio | |
# Analizar si el archivo está transcodificado | |
resultado_transcodificacion = analizar_transcodificacion(info_audio) | |
transcodificacion_str = "\nAnálisis de transcodificación:\n" + resultado_transcodificacion | |
# Crear una figura para las gráficas | |
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 12)) | |
# Gráfica de la forma de onda | |
librosa.display.waveshow(y, sr=sr, ax=ax1) | |
ax1.set_title('Forma de Onda del Audio') | |
ax1.set_xlabel('Tiempo (s)') | |
ax1.set_ylabel('Amplitud') | |
ax1.grid() | |
# Transformada Rápida de Fourier (FFT) | |
fft = np.fft.fft(y) # Calcula la FFT | |
magnitudes = np.abs(fft) # Obtiene las magnitudes de la FFT | |
frecuencias = np.fft.fftfreq(len(y), d=1/sr) # Frecuencias correspondientes a la FFT | |
ax2.plot(frecuencias[:len(frecuencias)//2], magnitudes[:len(magnitudes)//2]) | |
ax2.set_title('Transformada Rápida de Fourier (FFT)') | |
ax2.set_xlabel('Frecuencia (Hz)') | |
ax2.set_ylabel('Magnitud') | |
ax2.grid() | |
# Representación del espectrograma | |
espectrograma = librosa.feature.melspectrogram(y=y, sr=sr) # Calcula el espectrograma | |
espectrograma_db = librosa.power_to_db(espectrograma, ref=np.max) # Convierte a dB | |
librosa.display.specshow(espectrograma_db, x_axis='time', y_axis='mel', sr=sr, fmax=8000, ax=ax3) | |
fig.colorbar(ax3.collections[0], ax=ax3, format='%+2.0f dB') | |
ax3.set_title('Espectograma') | |
ax3.set_xlabel('Tiempo (s)') | |
ax3.set_ylabel('Frecuencia (Hz)') | |
# Ajustar el layout | |
plt.tight_layout() | |
# Guardar la figura como una imagen | |
ruta_imagen = "graficas.png" | |
plt.savefig(ruta_imagen) | |
plt.close() | |
# Mensaje de crédito | |
creditos_str = "\nDesarrollado por José R. Leonett" | |
# Devolver la imagen y los resultados de texto | |
return ruta_imagen, info_audio_str + transcodificacion_str + creditos_str | |
# Función para manejar la interfaz de Gradio | |
def procesar_audio_gradio(archivo_audio): | |
return procesar_audio(archivo_audio) | |
# Crear la interfaz de Gradio | |
iface = gr.Interface( | |
fn=procesar_audio_gradio, | |
inputs=gr.Audio(type="filepath", label="Sube tu archivo de audio (.mp3 o .wav)"), | |
outputs=[gr.Image(label="Gráficas"), gr.Textbox(label="Resultados")], | |
title=" 🎧 Análisis de Audio con FFT y Espectograma", # Título de la interfaz | |
description=encabezado, # Encabezado personalizado | |
allow_flagging="never" | |
) | |
# Lanzar la interfaz de Gradio | |
iface.launch() | |