77
88SUPPORTED_EXTENSIONS = {".mp3" , ".wav" , ".m4a" , ".ogg" , ".mp4" }
99
10- # path absoluto porque Windows no encuentra ffmpeg desde Python
11- FFMPEG_PATH = r"C:\Users\andre\AppData\Local\Microsoft\WinGet\Packages\Gyan.FFmpeg_Microsoft.Winget.Source_8wekyb3d8bbwe\ffmpeg-8.0.1-full_build\bin\ffmpeg.exe"
10+ # detecta si estamos en Linux (Docker) o Windows (local)
11+ FFMPEG_PATH = "/usr/bin/ffmpeg" if os .name != "nt" else r"C:\Users\andre\AppData\Local\Microsoft\WinGet\Packages\Gyan.FFmpeg_Microsoft.Winget.Source_8wekyb3d8bbwe\ffmpeg-8.0.1-full_build\bin\ffmpeg.exe"
12+ FFPROBE_PATH = "/usr/bin/ffprobe" if os .name != "nt" else FFMPEG_PATH .replace ("ffmpeg.exe" , "ffprobe.exe" )
1213
1314def validate_audio (filename : str , size_bytes : int ) -> None :
1415 ext = Path (filename ).suffix .lower ()
@@ -20,62 +21,25 @@ def validate_audio(filename: str, size_bytes: int) -> None:
2021 raise AudioTooLargeError (size_mb )
2122
2223def convert_to_wav (input_path : str ) -> str :
23- """
24- Convierte cualquier audio a WAV 16kHz mono.
25- Azure Speech SDK requiere este formato exacto.
26- """
27- output_path = os .path .join (
28- settings .TEMP_DIR ,
29- f"{ uuid .uuid4 ()} .wav"
30- )
24+ """Convierte cualquier audio a WAV 16kHz mono."""
25+ output_path = os .path .join (settings .TEMP_DIR , f"{ uuid .uuid4 ()} .wav" )
3126
3227 (
3328 ffmpeg
3429 .input (input_path )
35- .output (
36- output_path ,
37- ar = 16000 , # 16kHz — requerido por Azure Speech
38- ac = 1 , # mono — reduce tamaño y mejora STT
39- format = "wav"
40- )
30+ .output (output_path , ar = 16000 , ac = 1 , format = "wav" )
4131 .overwrite_output ()
42- .run (cmd = FFMPEG_PATH , quiet = True ) # cmd apunta al binario explícito
32+ .run (cmd = FFMPEG_PATH , quiet = True )
4333 )
4434
4535 return output_path
4636
47- async def save_upload (file ) -> str :
48- """
49- Guarda el archivo subido en TEMP_DIR con nombre único.
50- Retorna el path del archivo guardado.
51- """
52- import aiofiles
53-
54- os .makedirs (settings .TEMP_DIR , exist_ok = True )
55-
56- ext = Path (file .filename ).suffix .lower ()
57- temp_path = os .path .join (settings .TEMP_DIR , f"{ uuid .uuid4 ()} { ext } " )
58-
59- async with aiofiles .open (temp_path , "wb" ) as f :
60- content = await file .read ()
61- await f .write (content )
62-
63- return temp_path
64-
6537def split_audio (wav_path : str , chunk_minutes : int = 2 ) -> list [str ]:
66- """
67- Divide un WAV en chunks de chunk_minutes minutos.
68- Retorna lista de paths de los chunks.
69- """
70- import subprocess
71- import json
72-
73- # obtiene duración total con ffprobe
74- probe = ffmpeg .probe (wav_path , cmd = FFMPEG_PATH .replace ("ffmpeg.exe" , "ffprobe.exe" ))
38+ """Divide un WAV en chunks de chunk_minutes minutos."""
39+ probe = ffmpeg .probe (wav_path , cmd = FFPROBE_PATH )
7540 duration = float (probe ["format" ]["duration" ])
7641 chunk_seconds = chunk_minutes * 60
7742
78- # si el audio es corto no necesita split
7943 if duration <= chunk_seconds :
8044 return [wav_path ]
8145
@@ -99,4 +63,19 @@ def split_audio(wav_path: str, chunk_minutes: int = 2) -> list[str]:
9963 start += chunk_seconds
10064 index += 1
10165
102- return chunks
66+ return chunks
67+
68+ async def save_upload (file ) -> str :
69+ """Guarda el archivo subido en TEMP_DIR con nombre único."""
70+ import aiofiles
71+
72+ os .makedirs (settings .TEMP_DIR , exist_ok = True )
73+
74+ ext = Path (file .filename ).suffix .lower ()
75+ temp_path = os .path .join (settings .TEMP_DIR , f"{ uuid .uuid4 ()} { ext } " )
76+
77+ async with aiofiles .open (temp_path , "wb" ) as f :
78+ content = await file .read ()
79+ await f .write (content )
80+
81+ return temp_path
0 commit comments