suprimedev commited on
Commit
e460347
·
verified ·
1 Parent(s): b83e2b9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +185 -116
app.py CHANGED
@@ -1,133 +1,202 @@
1
- from flask import Flask, render_template, request, jsonify
2
  import requests
3
  import json
4
- import time
5
  import os
 
 
6
 
7
- app = Flask(__name__)
 
 
 
 
8
 
9
- # تنظیمات API
10
- TTS_API_URL = "https://talkbot.ir/TTS-tkun"
11
- AI_API_URL = "https://talkbot.ir/api/v1/chat/completions"
12
- AI_API_KEY = "sk-4fb613f56acfccf731e801b904cd89f5"
13
- MODEL_NAME = "deepseek-v3-0324"
14
 
15
- @app.route('/')
16
- def home():
17
- return render_template('index.html')
 
 
 
18
 
19
- @app.route('/generate_podcast', methods=['POST'])
20
- def generate_podcast():
21
- try:
22
- # دریافت موضوع پادکست از فرم
23
- topic = request.form.get('topic')
24
- voice1 = request.form.get('voice1', 'male')
25
- voice2 = request.form.get('voice2', 'female')
26
-
27
- if not topic:
28
- return jsonify({'error': 'لطفا موضوع پادکست را وارد کنید'}), 400
29
-
30
- # تولید متون پادکست با هوش مصنوعی
31
- conversation = generate_conversation(topic)
32
-
33
- if not conversation or 'parts' not in conversation:
34
- return jsonify({'error': 'خطا در تولید محتوای پادکست'}), 500
35
-
36
- # تولید فایل‌های صوتی
37
- audio_urls = []
38
- for i, part in enumerate(conversation['parts']):
39
- voice = voice1 if i % 2 == 0 else voice2
40
- audio_url = generate_tts(part['text'], voice)
41
- if audio_url:
42
- audio_urls.append({
43
- 'text': part['text'],
44
- 'speaker': "گوینده اول" if i % 2 == 0 else "گوینده دوم",
45
- 'audio_url': audio_url
46
- })
47
-
48
- # ترکیب اطلاعات پادکست
49
- podcast_data = {
50
- 'title': conversation.get('title', 'پادکست تولید شده'),
51
- 'description': conversation.get('description', 'پادکست تولید شده با هوش مصنوعی'),
52
- 'topic': topic,
53
- 'parts': audio_urls
54
- }
55
-
56
- return jsonify(podcast_data)
57
-
58
- except Exception as e:
59
- print(f"Error: {str(e)}")
60
- return jsonify({'error': str(e)}), 500
61
-
62
- def generate_conversation(topic):
63
  headers = {
64
- 'Content-Type': 'application/json',
65
- 'Authorization': f'Bearer {AI_API_KEY}'
66
  }
67
-
68
- prompt = f"""
69
- یک مکالمه پادکستی جذاب درباره '{topic}' تولید کن.
70
- پادکست باید بین دو نفر با نام‌های 'گوینده اول' و 'گوینده دوم' باشد.
71
- مکالمه باید حداکثر 6 تکه متن داشته باشد (مجموع حدود 500 کلمه).
72
- پاسخ را به فرمت JSON زیر برگردان:
73
- {{
74
- "title": "عنوان پادکست",
75
- "description": "توضیح کوتاه درباره پادکست",
76
- "parts": [
77
- {{
78
- "speaker": "گوینده اول یا دوم",
79
- "text": "متن گفته شده"
80
- }},
81
- // ...
82
- ]
83
- }}
84
- """
85
-
86
  data = {
87
- "model": MODEL_NAME,
88
  "messages": [
89
- {"role": "system", "content": "شما یک تولید کننده حرفه‌ای محتوای پادکست هستید."},
90
- {"role": "user", "content": prompt}
91
  ],
92
- "temperature": 0.7
 
 
 
93
  }
94
 
95
- response = requests.post(AI_API_URL, headers=headers, json=data)
96
-
97
- if response.status_code == 200:
98
- try:
99
- # استخراج محتوای JSON از پاسخ
100
- content = response.json()['choices'][0]['message']['content']
101
- # بررسی و حذف markdown code block اگر وجود دارد
102
- if content.startswith('```json') and content.endswith('```'):
103
- content = content[7:-3].strip()
104
- return json.loads(content)
105
- except json.JSONDecodeError as e:
106
- print(f"JSON decode error: {e}")
107
- print(f"Response content: {content}")
108
- return None
109
- else:
110
- print(f"API Error: {response.status_code} - {response.text}")
111
- return None
 
 
112
 
113
- def generate_tts(text, voice):
114
- params = {
115
- 'text': text,
116
- 'voice': voice
117
- }
118
-
119
  try:
120
- response = requests.get(TTS_API_URL, params=params)
121
- if response.status_code == 200:
122
- # برای این مثال فرض می‌کنیم پاسخ مستقیم URL فایل است
123
- # در صورت نیاز می‌توانید پردازش بیشتری انجام دهید
124
- return response.text.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  else:
126
- print(f"TTS Error: {response.status_code} - {response.text}")
127
- return None
128
- except Exception as e:
129
- print(f"TTS Exception: {str(e)}")
130
- return None
131
-
132
- if __name__ == '__main__':
133
- app.run(debug=True)
 
1
+ import streamlit as st
2
  import requests
3
  import json
 
4
  import os
5
+ import io
6
+ import base64
7
 
8
+ # --- Configuration ---
9
+ TALKBOT_TTS_URL = "https://talkbot.ir/TTS-tkun"
10
+ TALKBOT_CHAT_API_URL = "https://talkbot.ir/api/v1/chat/completions"
11
+ DEEPSEEK_API_KEY = "sk-4fb61f56acfccf731e801b904c89f5" # Replace with your actual key if different
12
+ DEEPSEEK_MODEL = "deepseek-v3-0324"
13
 
14
+ # --- Functions ---
 
 
 
 
15
 
16
+ def get_tts_audio_url(text: str) -> str:
17
+ """Gets a WAV audio URL from Talkbot TTS."""
18
+ params = {"text": text}
19
+ response = requests.get(TALKBOT_TTS_URL, params=params)
20
+ response.raise_for_status() # Raise an exception for bad status codes
21
+ return response.text.strip() # The response directly contains the URL
22
 
23
+ def generate_podcast_script_deepseek(prompt: str) -> str:
24
+ """Generates a podcast script using DeepSeek API."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  headers = {
26
+ "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
27
+ "Content-Type": "application/json"
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  data = {
30
+ "model": DEEPSEEK_MODEL,
31
  "messages": [
32
+ {"role": "system", "content": "You are a helpful assistant for generating podcast scripts."},
33
+ {"role": "user", "content": f"Generate a short podcast script on the following topic:\n\n{prompt}\n\nPlease include a clear introduction, 2-3 main points, and a conclusion. Divide the script into two distinct voices (Voice 1 and Voice 2). Label each part with 'Voice 1:' or 'Voice 2:'."}
34
  ],
35
+ "temperature": 0.7,
36
+ "max_tokens": 500,
37
+ "n": 1,
38
+ "stop": None
39
  }
40
 
41
+ try:
42
+ response = requests.post(TALKBOT_CHAT_API_URL, headers=headers, data=json.dumps(data))
43
+ response.raise_for_status() # Raise an exception for bad status codes
44
+
45
+ result = response.json()
46
+ if result and result.get("choices"):
47
+ return result["choices"][0]["message"]["content"]
48
+ else:
49
+ st.error("DeepSeek API did not return valid choices.")
50
+ return "Error: Could not generate script."
51
+ except requests.exceptions.HTTPError as e:
52
+ st.error(f"HTTP Error: {e.response.status_code} - {e.response.text}")
53
+ return f"Error: Could not generate script (HTTP Error)."
54
+ except requests.exceptions.RequestException as e:
55
+ st.error(f"Request Error: {e}")
56
+ return "Error: Could not generate script (Request Error)."
57
+ except json.JSONDecodeError as e:
58
+ st.error(f"JSON Decode Error: {e} - Response content: {response.text}")
59
+ return "Error: Could not generate script (JSON Error)."
60
 
61
+
62
+ def download_audio_from_url(url: str) -> bytes:
63
+ """Downloads audio content from a given URL."""
 
 
 
64
  try:
65
+ response = requests.get(url)
66
+ response.raise_for_status()
67
+ return response.content
68
+ except requests.exceptions.RequestException as e:
69
+ st.error(f"Error downloading audio from {url}: {e}")
70
+ return b""
71
+
72
+ def create_audio_player_from_bytes(audio_bytes: bytes, key_suffix: str):
73
+ """Creates an audio player for bytes data."""
74
+ if audio_bytes:
75
+ # Encode bytes to base64 for embedding in HTML audio tag
76
+ b64_audio = base64.b64encode(audio_bytes).decode("utf-8")
77
+ st.markdown(
78
+ f"""
79
+ <audio controls key="{key_suffix}">
80
+ <source src="data:audio/wav;base64,{b64_audio}" type="audio/wav">
81
+ Your browser does not support the audio element.
82
+ </audio>
83
+ """,
84
+ unsafe_allow_html=True,
85
+ )
86
+ else:
87
+ st.warning("No audio data available to play.")
88
+
89
+
90
+ # --- Streamlit UI ---
91
+
92
+ st.set_page_config(page_title="Podcast Generator", layout="centered")
93
+
94
+ st.title("🎙️ AI Podcast Generator")
95
+ st.markdown("Generate and listen to your custom podcasts using AI!")
96
+
97
+ # Input for podcast topic
98
+ podcast_topic = st.text_input("Enter your podcast topic:", "The future of AI in daily life")
99
+
100
+ if st.button("Generate Podcast"):
101
+ if not podcast_topic:
102
+ st.warning("Please enter a podcast topic.")
103
+ else:
104
+ st.subheader("Generating Podcast Script...")
105
+ with st.spinner("AI is thinking... this might take a moment."):
106
+ script = generate_podcast_script_deepseek(podcast_topic)
107
+ st.session_state.script = script # Store script in session state
108
+
109
+ if st.session_state.script and "Error" not in st.session_state.script:
110
+ st.success("Script Generated!")
111
+ st.subheader("Generated Podcast Script:")
112
+ st.text_area("Script", st.session_state.script, height=300)
113
+
114
+ st.markdown("---")
115
+ st.subheader("Generating Audio for Voices...")
116
+
117
+ # Split script into Voice 1 and Voice 2 parts
118
+ voice_1_lines = []
119
+ voice_2_lines = []
120
+ current_voice = None
121
+
122
+ for line in st.session_state.script.split('\n'):
123
+ line_stripped = line.strip()
124
+ if line_stripped.lower().startswith("voice 1:"):
125
+ current_voice = 1
126
+ voice_1_lines.append(line_stripped[len("voice 1:"):].strip())
127
+ elif line_stripped.lower().startswith("voice 2:"):
128
+ current_voice = 2
129
+ voice_2_lines.append(line_stripped[len("voice 2:"):].strip())
130
+ elif current_voice == 1:
131
+ voice_1_lines.append(line_stripped)
132
+ elif current_voice == 2:
133
+ voice_2_lines.append(line_stripped)
134
+
135
+ voice_1_text = " ".join(filter(None, voice_1_lines)) # Filter out empty strings
136
+ voice_2_text = " ".join(filter(None, voice_2_lines)) # Filter out empty strings
137
+
138
+ st.write(f"Voice 1 Text: {voice_1_text}")
139
+ st.write(f"Voice 2 Text: {voice_2_text}")
140
+
141
+ st.session_state.voice1_audio_url = ""
142
+ st.session_state.voice2_audio_url = ""
143
+
144
+ if voice_1_text:
145
+ with st.spinner("Getting Voice 1 audio..."):
146
+ try:
147
+ st.session_state.voice1_audio_url = get_tts_audio_url(voice_1_text)
148
+ except requests.exceptions.RequestException as e:
149
+ st.error(f"Error getting Voice 1 audio URL: {e}")
150
+ else:
151
+ st.warning("No text found for Voice 1.")
152
+
153
+ if voice_2_text:
154
+ with st.spinner("Getting Voice 2 audio..."):
155
+ try:
156
+ st.session_state.voice2_audio_url = get_tts_audio_url(voice_2_text)
157
+ except requests.exceptions.RequestException as e:
158
+ st.error(f"Error getting Voice 2 audio URL: {e}")
159
+ else:
160
+ st.warning("No text found for Voice 2.")
161
+
162
+ st.success("Audio URLs fetched!")
163
+
164
+ st.markdown("---")
165
+ st.subheader("Listen to Podcast Voices:")
166
+
167
+ col1, col2 = st.columns(2)
168
+
169
+ with col1:
170
+ st.markdown("#### Voice 1")
171
+ if st.session_state.voice1_audio_url:
172
+ st.audio(st.session_state.voice1_audio_url, format="audio/wav")
173
+ st.download_button(
174
+ label="Download Voice 1 Audio",
175
+ data=download_audio_from_url(st.session_state.voice1_audio_url),
176
+ file_name="voice_1.wav",
177
+ mime="audio/wav",
178
+ key="dl_voice1"
179
+ )
180
+ else:
181
+ st.warning("Voice 1 audio not available.")
182
+
183
+ with col2:
184
+ st.markdown("#### Voice 2")
185
+ if st.session_state.voice2_audio_url:
186
+ st.audio(st.session_state.voice2_audio_url, format="audio/wav")
187
+ st.download_button(
188
+ label="Download Voice 2 Audio",
189
+ data=download_audio_from_url(st.session_state.voice2_audio_url),
190
+ file_name="voice_2.wav",
191
+ mime="audio/wav",
192
+ key="dl_voice2"
193
+ )
194
+ else:
195
+ st.warning("Voice 2 audio not available.")
196
+
197
  else:
198
+ st.error("Failed to generate podcast script. Please try again.")
199
+
200
+ st.markdown("---")
201
+ st.markdown("Developed with ❤️ for HUGGINGFACE")
202
+ st.markdown("For more information on Talkbot TTS: [talkbot.ir](https://talkbot.ir)")