Created
December 1, 2024 16:24
-
-
Save sjimenez44/43beae950c6e0d21fd10a08d92aad7db to your computer and use it in GitHub Desktop.
Remove silences with ffmpeg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import subprocess | |
# Función para ejecutar el comando FFmpeg | |
def run_ffmpeg(command): | |
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
return result.stdout.decode(), result.stderr.decode() | |
# Detectar los silencios en un archivo de audio | |
def detect_silence(input_file): | |
command = f"ffmpeg -i {input_file} -af silencedetect=n=-45dB:d=1 -f null -" | |
stdout, stderr = run_ffmpeg(command) | |
return stderr | |
# Generar los intervalos de tiempo no silenciosos | |
def extract_non_silent_intervals(silence_output): | |
silence_logs = ([ii for ii in silence_output.split("\r\n") if "silence_" in ii]) | |
silences = [] | |
for log in silence_logs: | |
# Buscar valores de silence_start | |
start_match = re.search(r"silence_start:\s*([\d.]+)", log) | |
if start_match: | |
silences.append(float(start_match.group(1))) | |
# Buscar valores de silence_end | |
end_match = re.search(r"silence_end:\s*([\d.]+)", log) | |
if end_match: | |
silences.append(float(end_match.group(1))) | |
return silences | |
# Crear el filtro 'aselect' basado en los intervalos no silenciosos | |
def create_aselect_filter(intervals): | |
filter_str = "" | |
num_silents = int(len(intervals) / 2) | |
for ii in range(num_silents): | |
# Agregar intervalo no silencioso antes del primer silencio y después | |
if ii == num_silents - 1: | |
filter_str += f"between(t,{intervals[ii]},{intervals[ii + 1]})" | |
else: | |
filter_str += f"between(t,{intervals[ii]},{intervals[ii + 1]})+" | |
# Retornar el filtro para FFmpeg | |
return f"aselect='not({filter_str})'" | |
# Obtener la duración total del archivo de audio | |
def get_audio_duration(input_file): | |
command = f"ffmpeg -i {input_file}" | |
stdout, stderr = run_ffmpeg(command) | |
for line in stderr.splitlines(): | |
if "Duration" in line: | |
duration_str = line.split("Duration:")[1].split(",")[0].strip() | |
hours, minutes, seconds = map(float, duration_str.split(":")) | |
duration = hours * 3600 + minutes * 60 + seconds | |
return duration | |
return 0 | |
# Función principal para procesar el audio | |
def remove_silence(input_file, output_file): | |
# Detectar los silencios | |
silence_output = detect_silence(input_file) | |
# Extraer los intervalos de silencio | |
intervals = extract_non_silent_intervals(silence_output) | |
print(intervals) | |
# Crear el filtro 'aselect' para seleccionar las partes no silenciosas | |
aselect_filter = create_aselect_filter(intervals) | |
# Ejecutar el comando FFmpeg para generar el archivo de salida sin los silencios | |
command = f"ffmpeg -i {input_file} -af \"{aselect_filter}\",asetpts=N/SR/TB {output_file}" | |
stdout, stderr = run_ffmpeg(command) | |
print(command) | |
print("Comando ejecutado con éxito. Archivo generado:", output_file) | |
# Ejemplo de uso | |
input_file = 'Grabación.m4a' # Ruta de tu archivo de audio | |
output_file = 'output3.mp3' # Ruta del archivo de salida sin los silencios | |
remove_silence(input_file, output_file) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment