Spaces:
Sleeping
Sleeping
Update denoiser.py
Browse files- denoiser.py +19 -17
denoiser.py
CHANGED
|
@@ -4,49 +4,51 @@ import logging
|
|
| 4 |
import subprocess
|
| 5 |
import re
|
| 6 |
|
|
|
|
|
|
|
| 7 |
logger = logging.getLogger(__name__)
|
| 8 |
|
|
|
|
| 9 |
class Denoiser:
|
| 10 |
def __init__(self):
|
| 11 |
self.api_key = os.environ.get("CLEANVOICE_API_KEY", "")
|
| 12 |
-
|
|
|
|
| 13 |
|
| 14 |
def process(self, audio_path: str, out_dir: str, **kwargs) -> dict:
|
| 15 |
-
# Step A: Pre-convert to standard WAV (Handles .opus, .aac, .m4a)
|
| 16 |
standard_input = os.path.join(out_dir, "input_converted.wav")
|
| 17 |
subprocess.run([
|
| 18 |
-
"ffmpeg", "-y", "-i", audio_path,
|
| 19 |
-
"-ar", "16000", "-ac", "1",
|
|
|
|
| 20 |
], capture_output=True)
|
| 21 |
|
| 22 |
try:
|
| 23 |
-
from cleanvoice import Cleanvoice
|
| 24 |
cv = Cleanvoice({'api_key': self.api_key})
|
|
|
|
|
|
|
| 25 |
|
| 26 |
-
# Step B: Process via Cleanvoice API
|
| 27 |
result = cv.process(
|
| 28 |
-
standard_input,
|
| 29 |
-
remove_noise=True,
|
| 30 |
-
studio_sound=True,
|
| 31 |
-
**
|
| 32 |
)
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
audio_data = requests.get(result.audio.url).content
|
| 36 |
final_wav = os.path.join(out_dir, "clean_output.wav")
|
| 37 |
with open(final_wav, "wb") as f:
|
| 38 |
f.write(audio_data)
|
| 39 |
-
|
| 40 |
return {'audio_path': final_wav}
|
|
|
|
| 41 |
except Exception as e:
|
| 42 |
-
logger.error(f"
|
| 43 |
-
|
| 44 |
|
| 45 |
def clean_transcript_fillers(self, transcript: str) -> str:
|
| 46 |
fillers = {"um", "umm", "uh", "basically", "like", "ante", "ane"}
|
| 47 |
words = transcript.split()
|
| 48 |
return " ".join([w for w in words if re.sub(r'[^a-z]', '', w.lower()) not in fillers])
|
| 49 |
|
| 50 |
-
# Important: Dummy methods to prevent "AttributeError" in app.py
|
| 51 |
def _remove_fillers(self, audio, sr, segments): return audio, 0
|
| 52 |
def _remove_stutters(self, audio, sr, segments): return audio, 0
|
|
|
|
| 4 |
import subprocess
|
| 5 |
import re
|
| 6 |
|
| 7 |
+
from cleanvoice import Cleanvoice
|
| 8 |
+
|
| 9 |
logger = logging.getLogger(__name__)
|
| 10 |
|
| 11 |
+
|
| 12 |
class Denoiser:
|
| 13 |
def __init__(self):
|
| 14 |
self.api_key = os.environ.get("CLEANVOICE_API_KEY", "")
|
| 15 |
+
if self.api_key:
|
| 16 |
+
print("[Denoiser] ☁️ Cleanvoice API Ready")
|
| 17 |
|
| 18 |
def process(self, audio_path: str, out_dir: str, **kwargs) -> dict:
|
|
|
|
| 19 |
standard_input = os.path.join(out_dir, "input_converted.wav")
|
| 20 |
subprocess.run([
|
| 21 |
+
"ffmpeg", "-y", "-i", audio_path,
|
| 22 |
+
"-ar", "16000", "-ac", "1", "-acodec", "pcm_s16le",
|
| 23 |
+
standard_input
|
| 24 |
], capture_output=True)
|
| 25 |
|
| 26 |
try:
|
|
|
|
| 27 |
cv = Cleanvoice({'api_key': self.api_key})
|
| 28 |
+
supported_kwargs = {k: v for k, v in kwargs.items()
|
| 29 |
+
if k in ["fillers", "stutters", "long_silences"]}
|
| 30 |
|
|
|
|
| 31 |
result = cv.process(
|
| 32 |
+
standard_input,
|
| 33 |
+
remove_noise=True,
|
| 34 |
+
studio_sound=True,
|
| 35 |
+
**supported_kwargs
|
| 36 |
)
|
| 37 |
+
|
| 38 |
+
audio_data = requests.get(result.audio.url, timeout=60).content
|
|
|
|
| 39 |
final_wav = os.path.join(out_dir, "clean_output.wav")
|
| 40 |
with open(final_wav, "wb") as f:
|
| 41 |
f.write(audio_data)
|
|
|
|
| 42 |
return {'audio_path': final_wav}
|
| 43 |
+
|
| 44 |
except Exception as e:
|
| 45 |
+
logger.error(f"Cleanvoice failed: {e}")
|
| 46 |
+
return {'audio_path': standard_input}
|
| 47 |
|
| 48 |
def clean_transcript_fillers(self, transcript: str) -> str:
|
| 49 |
fillers = {"um", "umm", "uh", "basically", "like", "ante", "ane"}
|
| 50 |
words = transcript.split()
|
| 51 |
return " ".join([w for w in words if re.sub(r'[^a-z]', '', w.lower()) not in fillers])
|
| 52 |
|
|
|
|
| 53 |
def _remove_fillers(self, audio, sr, segments): return audio, 0
|
| 54 |
def _remove_stutters(self, audio, sr, segments): return audio, 0
|