Skip to content

Instantly share code, notes, and snippets.

@sjimenez44
Created December 1, 2024 16:24
Show Gist options
  • Save sjimenez44/43beae950c6e0d21fd10a08d92aad7db to your computer and use it in GitHub Desktop.
Save sjimenez44/43beae950c6e0d21fd10a08d92aad7db to your computer and use it in GitHub Desktop.
Remove silences with ffmpeg
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