Clearwave48 commited on
Commit
fe8bb50
·
verified ·
1 Parent(s): 8a41adc

Update denoiser.py

Browse files
Files changed (1) hide show
  1. denoiser.py +45 -17
denoiser.py CHANGED
@@ -13,42 +13,70 @@ 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
 
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 (WhatsApp Support Active)")
17
+ else:
18
+ print("[Denoiser] ⚠️ No CLEANVOICE_API_KEY found — will use preprocessed WAV only")
19
 
20
  def process(self, audio_path: str, out_dir: str, **kwargs) -> dict:
21
+ # Step A: Pre-convert to standard WAV (Handles .opus, .aac, .m4a)
22
  standard_input = os.path.join(out_dir, "input_converted.wav")
23
+ result = subprocess.run([
24
+ "ffmpeg", "-y", "-i", audio_path,
25
+ "-ar", "16000", "-ac", "1", standard_input
 
26
  ], capture_output=True)
27
 
28
+ # Fallback to original if FFmpeg fails
29
+ if result.returncode != 0 or not os.path.exists(standard_input):
30
+ logger.warning("[Denoiser] FFmpeg conversion failed — using original file")
31
+ standard_input = audio_path
32
+
33
  try:
34
+ from cleanvoice import Cleanvoice
35
  cv = Cleanvoice({'api_key': self.api_key})
 
 
36
 
37
+ # Step B: Process via Cleanvoice API
38
+ supported_kwargs = {k: v for k, v in kwargs.items() if k in ["fillers", "stutters", "long_silences"]}
39
  result = cv.process(
40
+ standard_input,
41
+ remove_noise=True,
42
+ studio_sound=True,
43
  **supported_kwargs
44
  )
45
+
46
+ # Step C: Download the processed WAV file
47
  audio_data = requests.get(result.audio.url, timeout=60).content
48
+ wav_output = os.path.join(out_dir, "clean_output.wav")
49
+ with open(wav_output, "wb") as f:
50
  f.write(audio_data)
51
+
52
+ # ✅ NEW: Convert WAV → MP3 (high quality)
53
+ mp3_output = os.path.join(out_dir, "clean_output.mp3")
54
+ subprocess.run([
55
+ "ffmpeg", "-y", "-i", wav_output,
56
+ "-codec:a", "libmp3lame", "-b:a", "192k",
57
+ "-ar", "44100", "-ac", "2",
58
+ mp3_output
59
+ ], capture_output=True)
60
+
61
+ return {'audio_path': mp3_output} # Returns MP3!
62
+
63
  except Exception as e:
64
+ logger.error(f"Denoiser error: {e}")
65
+
66
+ # Fallback: Convert original to MP3
67
+ fallback_mp3 = os.path.join(out_dir, "fallback.mp3")
68
+ subprocess.run([
69
+ "ffmpeg", "-y", "-i", audio_path,
70
+ "-codec:a", "libmp3lame", "-b:a", "192k",
71
+ fallback_mp3
72
+ ], capture_output=True)
73
+ return {'audio_path': fallback_mp3}
74
 
75
  def clean_transcript_fillers(self, transcript: str) -> str:
76
  fillers = {"um", "umm", "uh", "basically", "like", "ante", "ane"}
77
  words = transcript.split()
78
  return " ".join([w for w in words if re.sub(r'[^a-z]', '', w.lower()) not in fillers])
79
 
80
+ # Important: Dummy methods to prevent "AttributeError" in app.py
81
  def _remove_fillers(self, audio, sr, segments): return audio, 0
82
  def _remove_stutters(self, audio, sr, segments): return audio, 0