File size: 6,781 Bytes
84fed9b f304938 84fed9b f304938 84fed9b f304938 84fed9b f304938 84fed9b f304938 84fed9b f304938 84fed9b f304938 84fed9b f304938 84fed9b f304938 84fed9b e3bea0f 84fed9b f3b14e5 84fed9b f3b14e5 84fed9b 74245b5 84fed9b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
import dash
from dash import dcc, html, Input, Output, State, callback
import dash_bootstrap_components as dbc
import base64
import io
import google.generativeai as genai
import numpy as np
import edge_tts
import asyncio
import re
import logging
import json
from dash.exceptions import PreventUpdate
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Initialize Dash app
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
# Initialize Gemini AI
genai.configure(api_key='YOUR_GEMINI_API_KEY')
# Helper functions (keep the existing functions)
def generate_podcast_script(api_key, content, duration, num_hosts):
# ... (keep the existing implementation)
async def text_to_speech(text, voice):
# ... (keep the existing implementation)
async def render_podcast(api_key, script, voice1, voice2, num_hosts):
# ... (keep the existing implementation)
async def get_voice_list():
# ... (keep the existing implementation)
# Language names dictionary (keep the existing dictionary)
language_names = {
# ... (keep the existing dictionary)
}
# Layout
app.layout = dbc.Container([
html.H1("AI Podcast Generator", className="my-4"),
dbc.Card([
dbc.CardBody([
dbc.Input(id="api-key-input", type="password", placeholder="Enter your Gemini API Key"),
dbc.Textarea(id="content-input", placeholder="Paste your content or upload a document", rows=5),
dcc.Upload(
id='document-upload',
children=html.Div(['Drag and Drop or ', html.A('Select a File')]),
style={
'width': '100%',
'height': '60px',
'lineHeight': '60px',
'borderWidth': '1px',
'borderStyle': 'dashed',
'borderRadius': '5px',
'textAlign': 'center',
'margin': '10px 0'
}
),
dcc.RadioItems(
id="duration",
options=[
{'label': '1-5 min', 'value': '1-5 min'},
{'label': '5-10 min', 'value': '5-10 min'},
{'label': '10-15 min', 'value': '10-15 min'}
],
value='1-5 min',
inline=True
),
dcc.RadioItems(
id="num-hosts",
options=[
{'label': '1 host', 'value': 1},
{'label': '2 hosts', 'value': 2}
],
value=2,
inline=True
),
dcc.Dropdown(id="lang1-select", options=[{'label': lang, 'value': lang} for lang in language_names.values()], value="English (United States)"),
dcc.Dropdown(id="voice1-select"),
html.Div([
dcc.Dropdown(id="lang2-select", options=[{'label': lang, 'value': lang} for lang in language_names.values()], value="English (United States)"),
dcc.Dropdown(id="voice2-select")
], id="second-voice-container"),
dbc.Button("Generate Script", id="generate-btn", color="primary", className="mt-3"),
dbc.Textarea(id="script-output", rows=10, className="mt-3"),
dbc.Button("Render Podcast", id="render-btn", color="success", className="mt-3"),
html.Div(id="audio-output")
])
], className="mt-4")
], fluid=True)
# Callbacks
@app.callback(
Output("voice1-select", "options"),
Input("lang1-select", "value")
)
def update_voice1_options(lang):
selected_lang = next((key for key, value in language_names.items() if value == lang), None)
voices = asyncio.run(get_voice_list()).get(selected_lang, [])
return [{'label': voice, 'value': voice} for voice in voices]
@app.callback(
Output("voice2-select", "options"),
Input("lang2-select", "value")
)
def update_voice2_options(lang):
selected_lang = next((key for key, value in language_names.items() if value == lang), None)
voices = asyncio.run(get_voice_list()).get(selected_lang, [])
return [{'label': voice, 'value': voice} for voice in voices]
@app.callback(
Output("second-voice-container", "style"),
Input("num-hosts", "value")
)
def update_second_voice_visibility(num_hosts):
return {'display': 'block' if num_hosts == 2 else 'none'}
@app.callback(
Output("content-input", "value"),
Input("document-upload", "contents"),
State("document-upload", "filename")
)
def update_content(contents, filename):
if contents is not None:
content_type, content_string = contents.split(',')
decoded = base64.b64decode(content_string)
try:
if 'csv' in filename:
df = pd.read_csv(io.StringIO(decoded.decode('utf-8')))
return df.to_string()
elif 'xls' in filename:
df = pd.read_excel(io.BytesIO(decoded))
return df.to_string()
elif 'txt' in filename:
return decoded.decode('utf-8')
else:
return 'Unsupported file type'
except Exception as e:
return f'Error processing file: {str(e)}'
return ''
@app.callback(
Output("script-output", "value"),
Input("generate-btn", "n_clicks"),
State("api-key-input", "value"),
State("content-input", "value"),
State("duration", "value"),
State("num-hosts", "value")
)
def generate_script(n_clicks, api_key, content, duration, num_hosts):
if n_clicks is None:
raise PreventUpdate
try:
script = generate_podcast_script(api_key, content, duration, num_hosts)
return script
except Exception as e:
return f"Error generating script: {str(e)}"
@app.callback(
Output("audio-output", "children"),
Input("render-btn", "n_clicks"),
State("api-key-input", "value"),
State("script-output", "value"),
State("voice1-select", "value"),
State("voice2-select", "value"),
State("num-hosts", "value")
)
def render_podcast_audio(n_clicks, api_key, script, voice1, voice2, num_hosts):
if n_clicks is None:
raise PreventUpdate
try:
sample_rate, audio_data = asyncio.run(render_podcast(api_key, script, voice1, voice2, num_hosts))
audio_base64 = base64.b64encode(audio_data.tobytes()).decode('utf-8')
return html.Audio(src=f"data:audio/wav;base64,{audio_base64}", controls=True)
except Exception as e:
return html.Div(f"Error rendering podcast: {str(e)}", style={'color': 'red'})
if __name__ == '__main__':
print("Starting the Dash application...")
app.run(debug=True, host='0.0.0.0', port=7860)
print("Dash application has finished running.") |