Update app.py
Browse files
app.py
CHANGED
@@ -10,6 +10,8 @@ import re
|
|
10 |
import base64
|
11 |
import logging
|
12 |
from dash.exceptions import PreventUpdate
|
|
|
|
|
13 |
|
14 |
# Set up logging
|
15 |
logging.basicConfig(level=logging.INFO)
|
@@ -195,9 +197,23 @@ app.layout = dbc.Container([
|
|
195 |
dbc.Select(id="lang2-select", options=[{"label": lang, "value": lang} for lang in language_names.values()], className="my-2"),
|
196 |
dbc.Select(id="voice2-select", className="my-2"),
|
197 |
dbc.Button("Generate Script", id="generate-btn", color="primary", className="mt-3"),
|
198 |
-
|
199 |
-
|
200 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
dcc.Download(id="download-audio")
|
202 |
])
|
203 |
])
|
@@ -227,50 +243,59 @@ def update_voice2_options(lang):
|
|
227 |
return [{"label": v, "value": v} for v in voices]
|
228 |
|
229 |
@app.callback(
|
230 |
-
Output("script-output", "value"),
|
|
|
231 |
Input("generate-btn", "n_clicks"),
|
232 |
-
State("api-key-input", "value"),
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
prevent_initial_call=True
|
237 |
)
|
238 |
def generate_script(n_clicks, api_key, content, duration, num_hosts):
|
239 |
if n_clicks is None:
|
240 |
raise PreventUpdate
|
241 |
try:
|
242 |
-
|
|
|
|
|
|
|
|
|
243 |
except Exception as e:
|
244 |
logger.error(f"Error generating script: {str(e)}")
|
245 |
-
return f"Error: {str(e)}"
|
246 |
|
247 |
@app.callback(
|
248 |
-
Output("audio-output", "children"),
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
State("
|
253 |
-
|
254 |
-
|
255 |
-
|
|
|
256 |
prevent_initial_call=True
|
257 |
)
|
258 |
async def render_and_download_podcast(n_clicks, api_key, script, voice1, voice2, num_hosts):
|
259 |
if n_clicks is None:
|
260 |
raise PreventUpdate
|
261 |
try:
|
|
|
|
|
|
|
262 |
sample_rate, audio_data = await render_podcast(api_key, script, voice1, voice2, num_hosts)
|
263 |
audio_bytes = audio_data.tobytes()
|
264 |
audio_base64 = base64.b64encode(audio_bytes).decode('utf-8')
|
265 |
audio_src = f"data:audio/wav;base64,{audio_base64}"
|
266 |
-
return html.Audio(src=audio_src, controls=True), dcc.send_bytes(audio_bytes, "podcast.wav")
|
267 |
except Exception as e:
|
268 |
logger.error(f"Error rendering podcast: {str(e)}")
|
269 |
-
return html.Div(f"Error: {str(e)}"), None
|
270 |
|
271 |
@app.callback(
|
272 |
-
Output("lang2-select", "style"),
|
273 |
-
|
274 |
Input("num-hosts", "value")
|
275 |
)
|
276 |
def update_second_voice_visibility(num_hosts):
|
|
|
10 |
import base64
|
11 |
import logging
|
12 |
from dash.exceptions import PreventUpdate
|
13 |
+
import pandas as pd
|
14 |
+
import time
|
15 |
|
16 |
# Set up logging
|
17 |
logging.basicConfig(level=logging.INFO)
|
|
|
197 |
dbc.Select(id="lang2-select", options=[{"label": lang, "value": lang} for lang in language_names.values()], className="my-2"),
|
198 |
dbc.Select(id="voice2-select", className="my-2"),
|
199 |
dbc.Button("Generate Script", id="generate-btn", color="primary", className="mt-3"),
|
200 |
+
dcc.Loading(
|
201 |
+
id="loading-script",
|
202 |
+
type="default",
|
203 |
+
children=[
|
204 |
+
dbc.Progress(id="script-progress", value=0, className="my-3"),
|
205 |
+
dbc.Textarea(id="script-output", rows=10, className="my-3"),
|
206 |
+
]
|
207 |
+
),
|
208 |
+
dbc.Button("Generate Podcast", id="generate-podcast-btn", color="success", className="mt-3"),
|
209 |
+
dcc.Loading(
|
210 |
+
id="loading-podcast",
|
211 |
+
type="default",
|
212 |
+
children=[
|
213 |
+
dbc.Progress(id="podcast-progress", value=0, className="my-3"),
|
214 |
+
html.Div(id="audio-output", className="my-3"),
|
215 |
+
]
|
216 |
+
),
|
217 |
dcc.Download(id="download-audio")
|
218 |
])
|
219 |
])
|
|
|
243 |
return [{"label": v, "value": v} for v in voices]
|
244 |
|
245 |
@app.callback(
|
246 |
+
[Output("script-output", "value"),
|
247 |
+
Output("script-progress", "value")],
|
248 |
Input("generate-btn", "n_clicks"),
|
249 |
+
[State("api-key-input", "value"),
|
250 |
+
State("content-input", "value"),
|
251 |
+
State("duration", "value"),
|
252 |
+
State("num-hosts", "value")],
|
253 |
prevent_initial_call=True
|
254 |
)
|
255 |
def generate_script(n_clicks, api_key, content, duration, num_hosts):
|
256 |
if n_clicks is None:
|
257 |
raise PreventUpdate
|
258 |
try:
|
259 |
+
for i in range(10):
|
260 |
+
time.sleep(0.5) # Simulate progress
|
261 |
+
yield dash.no_update, (i + 1) * 10
|
262 |
+
script = generate_podcast_script(api_key, content, duration, num_hosts)
|
263 |
+
return script, 100
|
264 |
except Exception as e:
|
265 |
logger.error(f"Error generating script: {str(e)}")
|
266 |
+
return f"Error: {str(e)}", 0
|
267 |
|
268 |
@app.callback(
|
269 |
+
[Output("audio-output", "children"),
|
270 |
+
Output("download-audio", "data"),
|
271 |
+
Output("podcast-progress", "value")],
|
272 |
+
Input("generate-podcast-btn", "n_clicks"),
|
273 |
+
[State("api-key-input", "value"),
|
274 |
+
State("script-output", "value"),
|
275 |
+
State("voice1-select", "value"),
|
276 |
+
State("voice2-select", "value"),
|
277 |
+
State("num-hosts", "value")],
|
278 |
prevent_initial_call=True
|
279 |
)
|
280 |
async def render_and_download_podcast(n_clicks, api_key, script, voice1, voice2, num_hosts):
|
281 |
if n_clicks is None:
|
282 |
raise PreventUpdate
|
283 |
try:
|
284 |
+
for i in range(10):
|
285 |
+
time.sleep(0.5) # Simulate progress
|
286 |
+
yield dash.no_update, dash.no_update, (i + 1) * 10
|
287 |
sample_rate, audio_data = await render_podcast(api_key, script, voice1, voice2, num_hosts)
|
288 |
audio_bytes = audio_data.tobytes()
|
289 |
audio_base64 = base64.b64encode(audio_bytes).decode('utf-8')
|
290 |
audio_src = f"data:audio/wav;base64,{audio_base64}"
|
291 |
+
return html.Audio(src=audio_src, controls=True), dcc.send_bytes(audio_bytes, "podcast.wav"), 100
|
292 |
except Exception as e:
|
293 |
logger.error(f"Error rendering podcast: {str(e)}")
|
294 |
+
return html.Div(f"Error: {str(e)}"), None, 0
|
295 |
|
296 |
@app.callback(
|
297 |
+
[Output("lang2-select", "style"),
|
298 |
+
Output("voice2-select", "style")],
|
299 |
Input("num-hosts", "value")
|
300 |
)
|
301 |
def update_second_voice_visibility(num_hosts):
|