Spaces:
Running
Running
Update conver.py
Browse files
conver.py
CHANGED
@@ -10,7 +10,6 @@ import tempfile
|
|
10 |
from pydub import AudioSegment
|
11 |
import base64
|
12 |
from pathlib import Path
|
13 |
-
import shutil # Importamos shutil para manejo de directorios
|
14 |
|
15 |
@dataclass
|
16 |
class ConversationConfig:
|
@@ -41,7 +40,6 @@ class URLToAudioConverter:
|
|
41 |
raise ValueError("Input text cannot be empty")
|
42 |
|
43 |
try:
|
44 |
-
# Prompt mejorado para obtener JSON consistente
|
45 |
prompt = (
|
46 |
f"{text}\nConvert the provided text into a short informative podcast conversation "
|
47 |
f"between two experts. Return ONLY a JSON object with the following structure:\n"
|
@@ -51,14 +49,12 @@ class URLToAudioConverter:
|
|
51 |
chat_completion = self.llm_client.chat.completions.create(
|
52 |
messages=[{"role": "user", "content": prompt}],
|
53 |
model=self.config.model_name,
|
54 |
-
response_format={"type": "json_object"}
|
55 |
)
|
56 |
|
57 |
-
# Extracción robusta de JSON
|
58 |
response_content = chat_completion.choices[0].message.content
|
59 |
json_str = response_content.strip()
|
60 |
|
61 |
-
# Limpieza de texto alrededor del JSON
|
62 |
if not json_str.startswith('{'):
|
63 |
start = json_str.find('{')
|
64 |
if start != -1:
|
@@ -71,7 +67,6 @@ class URLToAudioConverter:
|
|
71 |
|
72 |
return json.loads(json_str)
|
73 |
except Exception as e:
|
74 |
-
# Debug: Imprime la respuesta del modelo para diagnóstico
|
75 |
print(f"Error en extract_conversation: {str(e)}")
|
76 |
print(f"Respuesta del modelo: {response_content}")
|
77 |
raise RuntimeError(f"Failed to extract conversation: {str(e)}")
|
@@ -131,24 +126,13 @@ class URLToAudioConverter:
|
|
131 |
|
132 |
combined.export(output_file, format="mp3")
|
133 |
|
134 |
-
# Limpieza
|
135 |
dir_path = os.path.dirname(filenames[0])
|
136 |
-
|
137 |
-
# Eliminar todos los archivos en el directorio
|
138 |
for file in os.listdir(dir_path):
|
139 |
file_path = os.path.join(dir_path, file)
|
140 |
if os.path.isfile(file_path):
|
141 |
-
|
142 |
-
|
143 |
-
except Exception as e:
|
144 |
-
print(f"Warning: Could not remove file {file_path}: {str(e)}")
|
145 |
-
|
146 |
-
# Intentar eliminar el directorio (no crítico si falla)
|
147 |
-
try:
|
148 |
-
os.rmdir(dir_path)
|
149 |
-
except OSError as e:
|
150 |
-
print(f"Info: Could not remove directory {dir_path}: {str(e)}")
|
151 |
-
# No es crítico, el espacio puede continuar
|
152 |
|
153 |
except Exception as e:
|
154 |
raise RuntimeError(f"Failed to combine audio files: {e}")
|
@@ -174,7 +158,7 @@ class URLToAudioConverter:
|
|
174 |
return final_output, conversation_text
|
175 |
|
176 |
async def text_to_audio(self, text: str, voice_1: str, voice_2: str) -> Tuple[str, str]:
|
177 |
-
"""
|
178 |
conversation_json = self.extract_conversation(text)
|
179 |
conversation_text = "\n".join(
|
180 |
f"{turn['speaker']}: {turn['text']}" for turn in conversation_json["conversation"]
|
@@ -184,4 +168,17 @@ class URLToAudioConverter:
|
|
184 |
)
|
185 |
final_output = os.path.join(folder_name, "combined_output.mp3")
|
186 |
self.combine_audio_files(audio_files, final_output)
|
187 |
-
return final_output, conversation_text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
from pydub import AudioSegment
|
11 |
import base64
|
12 |
from pathlib import Path
|
|
|
13 |
|
14 |
@dataclass
|
15 |
class ConversationConfig:
|
|
|
40 |
raise ValueError("Input text cannot be empty")
|
41 |
|
42 |
try:
|
|
|
43 |
prompt = (
|
44 |
f"{text}\nConvert the provided text into a short informative podcast conversation "
|
45 |
f"between two experts. Return ONLY a JSON object with the following structure:\n"
|
|
|
49 |
chat_completion = self.llm_client.chat.completions.create(
|
50 |
messages=[{"role": "user", "content": prompt}],
|
51 |
model=self.config.model_name,
|
52 |
+
response_format={"type": "json_object"}
|
53 |
)
|
54 |
|
|
|
55 |
response_content = chat_completion.choices[0].message.content
|
56 |
json_str = response_content.strip()
|
57 |
|
|
|
58 |
if not json_str.startswith('{'):
|
59 |
start = json_str.find('{')
|
60 |
if start != -1:
|
|
|
67 |
|
68 |
return json.loads(json_str)
|
69 |
except Exception as e:
|
|
|
70 |
print(f"Error en extract_conversation: {str(e)}")
|
71 |
print(f"Respuesta del modelo: {response_content}")
|
72 |
raise RuntimeError(f"Failed to extract conversation: {str(e)}")
|
|
|
126 |
|
127 |
combined.export(output_file, format="mp3")
|
128 |
|
129 |
+
# Limpieza
|
130 |
dir_path = os.path.dirname(filenames[0])
|
|
|
|
|
131 |
for file in os.listdir(dir_path):
|
132 |
file_path = os.path.join(dir_path, file)
|
133 |
if os.path.isfile(file_path):
|
134 |
+
os.remove(file_path)
|
135 |
+
os.rmdir(dir_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
except Exception as e:
|
138 |
raise RuntimeError(f"Failed to combine audio files: {e}")
|
|
|
158 |
return final_output, conversation_text
|
159 |
|
160 |
async def text_to_audio(self, text: str, voice_1: str, voice_2: str) -> Tuple[str, str]:
|
161 |
+
"""Procesamiento normal con LLM"""
|
162 |
conversation_json = self.extract_conversation(text)
|
163 |
conversation_text = "\n".join(
|
164 |
f"{turn['speaker']}: {turn['text']}" for turn in conversation_json["conversation"]
|
|
|
168 |
)
|
169 |
final_output = os.path.join(folder_name, "combined_output.mp3")
|
170 |
self.combine_audio_files(audio_files, final_output)
|
171 |
+
return final_output, conversation_text
|
172 |
+
|
173 |
+
async def raw_text_to_audio(self, text: str, voice_1: str, voice_2: str) -> Tuple[str, str]:
|
174 |
+
"""NUEVO: Modo sin LLM (texto directo)"""
|
175 |
+
conversation = {
|
176 |
+
"conversation": [
|
177 |
+
{"speaker": "Host", "text": text},
|
178 |
+
{"speaker": "Co-host", "text": "(Continuación del tema)"}
|
179 |
+
]
|
180 |
+
}
|
181 |
+
audio_files, folder_name = await self.text_to_speech(conversation, voice_1, voice_2)
|
182 |
+
output_file = os.path.join(folder_name, "raw_podcast.mp3")
|
183 |
+
self.combine_audio_files(audio_files, output_file)
|
184 |
+
return text, output_file
|