Spaces:
Sleeping
Sleeping
File size: 5,142 Bytes
ab496c0 c58d9bb ab496c0 d83a342 ab496c0 c58d9bb 6b4eada c58d9bb d83a342 c58d9bb 6b4eada c58d9bb 6b4eada c58d9bb 6b4eada c58d9bb 6b4eada c58d9bb ab496c0 c58d9bb 6b4eada c58d9bb ab496c0 6b4eada ab496c0 1f4e0e1 c58d9bb ab496c0 1f4e0e1 6b4eada c58d9bb 1f4e0e1 c58d9bb 1f4e0e1 12d32cd c58d9bb 12d32cd 6b4eada c58d9bb 12d32cd c58d9bb 12d32cd ab496c0 a79fe10 ab496c0 12d32cd ab496c0 d83a342 8a80570 ab496c0 12d32cd 1f4e0e1 12d32cd ab496c0 1f4e0e1 12d32cd 1f4e0e1 12d32cd 1f4e0e1 12d32cd ab496c0 1f4e0e1 12d32cd ab496c0 1f4e0e1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
import gradio as gr
from moviepy.editor import VideoFileClip, concatenate_videoclips
import numpy as np
from scipy.io import wavfile
import tempfile
import os
from pathlib import Path
def detect_silence(audio_array, sample_rate, threshold=0.01, min_silence_len=1000):
"""Detecta períodos de silêncio no áudio"""
# Converte o threshold para amplitude
amplitude_threshold = threshold * np.max(np.abs(audio_array))
# Calcula a energia do áudio
energy = np.abs(audio_array)
if len(energy.shape) > 1:
energy = np.mean(energy, axis=1)
# Encontra regiões não silenciosas
is_sound = energy > amplitude_threshold
# Converte frames para segundos
frame_length = int(sample_rate * (min_silence_len / 1000))
# Suaviza a detecção para evitar cortes muito curtos
sound_chunks = []
start = None
for i in range(len(is_sound)):
if start is None and is_sound[i]:
start = i
elif start is not None and not is_sound[i]:
if i - start > frame_length:
sound_chunks.append((start / sample_rate, i / sample_rate))
start = None
if start is not None:
sound_chunks.append((start / sample_rate, len(is_sound) / sample_rate))
return sound_chunks
def process_video(video_path, threshold=0.01, min_silence_len=1000):
"""Remove silêncio do vídeo"""
# Carrega o vídeo
video = VideoFileClip(video_path)
# Extrai o áudio para análise
audio_array = video.audio.to_soundarray()
sample_rate = video.audio.fps
# Detecta regiões não silenciosas
sound_chunks = detect_silence(audio_array, sample_rate, threshold, min_silence_len)
if not sound_chunks:
video.close()
return video_path
# Corta e concatena os segmentos não silenciosos
clips = []
for start, end in sound_chunks:
clip = video.subclip(start, end)
clips.append(clip)
# Concatena os clips
final_clip = concatenate_videoclips(clips)
# Salva o resultado
output_path = str(Path(video_path).parent / f"processed_{Path(video_path).name}")
final_clip.write_videofile(output_path)
# Limpa os recursos
video.close()
final_clip.close()
for clip in clips:
clip.close()
return output_path
def remove_silence(video_input, silence_duration, silence_threshold):
"""Interface para remoção normal de silêncio"""
try:
if video_input is None:
raise ValueError("Por favor, faça upload de um vídeo")
# Converte o threshold de dB para amplitude relativa
amplitude_threshold = 10 ** (silence_threshold / 20)
return process_video(
video_input,
threshold=amplitude_threshold,
min_silence_len=int(silence_duration * 1000)
)
except Exception as e:
gr.Error(str(e))
return None
def remove_max_silence(video_input):
"""Interface para remoção máxima de silêncio"""
try:
if video_input is None:
raise ValueError("Por favor, faça upload de um vídeo")
# Configurações agressivas para máxima remoção
return process_video(
video_input,
threshold=0.05, # Mais sensível ao som
min_silence_len=100 # Remove silêncios mais curtos
)
except Exception as e:
gr.Error(str(e))
return None
# Interface Gradio
with gr.Blocks(title="Removedor de Silêncio de Vídeos") as app:
gr.Markdown("# Removedor de Silêncio de Vídeos")
with gr.Row():
with gr.Column():
video_input = gr.Video(
label="Selecione ou Arraste o Vídeo"
)
with gr.Row():
remove_max_btn = gr.Button("🔇 Remover 100% do Silêncio", variant="primary")
remove_custom_btn = gr.Button("Remover Silêncio Personalizado")
with gr.Group():
gr.Markdown("### Configurações Personalizadas")
silence_duration = gr.Slider(
minimum=0.1,
maximum=5.0,
value=1.0,
step=0.1,
label="Duração Mínima do Silêncio (segundos)"
)
silence_threshold = gr.Slider(
minimum=-60,
maximum=-20,
value=-40,
step=1,
label="Limite de Silêncio (dB)"
)
with gr.Row():
video_output = gr.Video(label="Vídeo Processado")
# Event handlers
remove_max_btn.click(
fn=remove_max_silence,
inputs=[video_input],
outputs=[video_output]
)
remove_custom_btn.click(
fn=remove_silence,
inputs=[
video_input,
silence_duration,
silence_threshold
],
outputs=[video_output]
)
if __name__ == "__main__":
app.launch(show_error=True) |