embedingHF commited on
Commit
6d86e61
·
verified ·
1 Parent(s): e9c5ac9

Update converters/audio_converter.py

Browse files
Files changed (1) hide show
  1. converters/audio_converter.py +95 -64
converters/audio_converter.py CHANGED
@@ -1,99 +1,130 @@
1
  import os
 
2
  from pathlib import Path
3
  from typing import Callable, Dict, Any
4
- import traceback
5
 
6
- # Setup ffmpeg for pydub
7
- import shutil
8
 
9
- ffmpeg_path = shutil.which('ffmpeg') or shutil.which('ffmpeg.exe')
10
  if ffmpeg_path:
11
  os.environ["FFMPEG_BINARY"] = ffmpeg_path
12
 
13
- try:
14
- from pydub import AudioSegment
15
-
16
- PYDUB_AVAILABLE = True
17
- except ImportError:
18
- PYDUB_AVAILABLE = False
19
- print("pydub not installed. Audio conversion will not work.")
20
 
21
 
22
  class AudioConverter:
23
- def __init__(self):
24
- pass
25
 
26
- def convert(self, input_path: str, output_path: str,
27
- options: Dict[str, Any], progress_callback: Callable = None) -> bool:
28
- """Convert audio files"""
29
- try:
30
- if not PYDUB_AVAILABLE:
31
- print("pydub library not available")
32
- return False
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- self._update_progress(progress_callback, 10)
 
35
 
36
- # Check if input file exists
37
  if not os.path.exists(input_path):
38
- print(f"Input file not found: {input_path}")
39
- return False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  # Load audio
42
  audio = AudioSegment.from_file(input_path)
43
 
44
- self._update_progress(progress_callback, 40)
45
 
46
- # Apply AI enhancement if requested
47
- if options.get("ai_enhancement", False):
48
- audio = self.enhance_audio(audio)
49
 
50
- self._update_progress(progress_callback, 60)
 
51
 
52
- # Get quality settings
53
- quality_settings = options.get("quality_settings", {})
54
- bitrate = quality_settings.get("audio", "192k")
55
 
56
- # Create output directory
57
- Path(output_path).parent.mkdir(parents=True, exist_ok=True)
58
 
59
- # Export to desired format
60
- output_ext = Path(output_path).suffix.lower()
 
 
61
 
62
- export_params = {
63
- '.mp3': {'format': 'mp3', 'bitrate': bitrate},
64
- '.wav': {'format': 'wav'},
65
- '.ogg': {'format': 'ogg', 'bitrate': bitrate},
66
- '.m4a': {'format': 'mp4', 'bitrate': bitrate},
67
- '.flac': {'format': 'flac'}
68
- }
69
 
70
- if output_ext in export_params:
71
- audio.export(output_path, **export_params[output_ext])
72
- else:
73
- audio.export(output_path)
74
 
75
- self._update_progress(progress_callback, 100)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
- print(f"✓ Successfully converted: {os.path.basename(input_path)} → {output_ext}")
78
  return True
79
 
80
  except Exception as e:
81
- print(f"Audio conversion error for {input_path}: {str(e)}")
82
- traceback.print_exc()
83
  return False
84
 
85
- def _update_progress(self, callback, value):
86
- """Safely update progress"""
87
- if callback is not None:
88
- try:
89
- callback(value)
90
- except Exception:
91
- pass
92
 
93
- def enhance_audio(self, audio):
94
- """Basic audio enhancement"""
95
  try:
96
- audio = audio.normalize()
97
- return audio
98
- except:
99
- return audio
 
1
  import os
2
+ import shutil
3
  from pathlib import Path
4
  from typing import Callable, Dict, Any
 
5
 
6
+ # Setup FFmpeg
7
+ ffmpeg_path = shutil.which("ffmpeg") or shutil.which("ffmpeg.exe")
8
 
 
9
  if ffmpeg_path:
10
  os.environ["FFMPEG_BINARY"] = ffmpeg_path
11
 
12
+ from pydub import AudioSegment
 
 
 
 
 
 
13
 
14
 
15
  class AudioConverter:
 
 
16
 
17
+ SUPPORTED_FORMATS = {
18
+ ".mp3",
19
+ ".wav",
20
+ ".flac",
21
+ ".ogg",
22
+ ".aac",
23
+ ".m4a",
24
+ ".wma"
25
+ }
26
+
27
+ def convert(
28
+ self,
29
+ input_path: str,
30
+ output_path: str,
31
+ options: Dict[str, Any] | None = None,
32
+ progress_callback: Callable | None = None
33
+ ) -> bool:
34
+
35
+ options = options or {}
36
 
37
+ try:
38
+ self._update(progress_callback, 10)
39
 
40
+ # Check input file
41
  if not os.path.exists(input_path):
42
+ raise FileNotFoundError(f"Input file not found: {input_path}")
43
+
44
+ input_ext = Path(input_path).suffix.lower()
45
+ output_ext = Path(output_path).suffix.lower()
46
+
47
+ # Validate formats
48
+ if input_ext not in self.SUPPORTED_FORMATS:
49
+ raise ValueError(f"Unsupported input format: {input_ext}")
50
+
51
+ if output_ext not in self.SUPPORTED_FORMATS:
52
+ raise ValueError(f"Unsupported output format: {output_ext}")
53
+
54
+ # Create output folder
55
+ Path(output_path).parent.mkdir(
56
+ parents=True,
57
+ exist_ok=True
58
+ )
59
 
60
  # Load audio
61
  audio = AudioSegment.from_file(input_path)
62
 
63
+ self._update(progress_callback, 35)
64
 
65
+ # Trim audio
66
+ start = int(options.get("start_ms", 0))
67
+ end = int(options.get("end_ms", len(audio)))
68
 
69
+ if start < 0:
70
+ start = 0
71
 
72
+ if end > len(audio):
73
+ end = len(audio)
 
74
 
75
+ audio = audio[start:end]
 
76
 
77
+ self._update(progress_callback, 55)
78
+
79
+ # Normalize safely
80
+ if options.get("normalize", True):
81
 
82
+ # Prevent silent audio crash
83
+ if audio.dBFS != float("-inf"):
 
 
 
 
 
84
 
85
+ target_dbfs = options.get("target_dbfs", -20.0)
 
 
 
86
 
87
+ change = target_dbfs - audio.dBFS
88
+
89
+ audio = audio.apply_gain(change)
90
+
91
+ self._update(progress_callback, 75)
92
+
93
+ # Bitrate
94
+ bitrate = options.get("bitrate", "192k")
95
+
96
+ # Export format
97
+ export_format = output_ext.replace(".", "")
98
+
99
+ export_args = {}
100
+
101
+ # WAV does not use bitrate
102
+ if export_format != "wav":
103
+ export_args["bitrate"] = bitrate
104
+
105
+ # AAC handling
106
+ if export_format == "aac":
107
+ export_format = "adts"
108
+
109
+ # Export audio
110
+ audio.export(
111
+ output_path,
112
+ format=export_format,
113
+ **export_args
114
+ )
115
+
116
+ self._update(progress_callback, 100)
117
 
 
118
  return True
119
 
120
  except Exception as e:
121
+ print(f"Audio conversion error: {e}")
 
122
  return False
123
 
124
+ def _update(self, callback, value):
 
 
 
 
 
 
125
 
 
 
126
  try:
127
+ if callback:
128
+ callback(value)
129
+ except Exception as e:
130
+ print(f"Progress callback error: {e}")