# -*- 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()