suprimedev commited on
Commit
319ea69
·
verified ·
1 Parent(s): 5c1e078

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +140 -121
app.py CHANGED
@@ -1,133 +1,152 @@
1
- import gradio
 
2
  import requests
3
  import json
 
4
  import os
5
 
6
- # اطلاعات API TTS
7
- TTS_API_BASE_URL = "https://talkbot.ir/TTS-tkun"
8
- TTS_API_FORMAT = "?text="
 
 
9
 
10
- # اطلاعات API OpenAI (برای Talkbot.ir)
11
- OPENAI_API_BASE_URL = "https://talkbot.ir/api/v1/chat/completions"
12
- OPENAI_API_KEY = "sk-4fb61f56acfcc731e801b904cd89f5" # دقت کنید که این کلید API از Talkbot.ir است و ممکن است با OpenAI اصلی متفاوت باشد.
13
- OPENAI_MODEL = "deepseek-v3-0324"
14
-
15
- def get_text_from_ai(prompt_text):
16
  """
17
- تولید متن پادکست با استفاده از API هوش مصنوعی.
18
  """
19
- headers = {
20
- "Authorization": f"Bearer {OPENAI_API_KEY}",
21
- "Content-Type": "application/json"
22
- }
23
-
24
- payload = {
25
- "model": OPENAI_MODEL,
26
- "messages": [
27
- {"role": "system", "content": "You are a helpful assistant that generates podcast scripts."},
28
- {"role": "user", "content": f"Generate a short podcast script about: {prompt_text}"}
29
- ],
30
- "max_tokens": 500,
31
- "temperature": 0.7
32
- }
33
-
34
  try:
35
- response = requests.post(OPENAI_API_BASE_URL, headers=headers, json=payload)
36
- response.raise_for_status() # Raises an HTTPError for bad responses (4xx or 5xx)
37
- data = response.json()
38
- if data and data.get("choices"):
39
- return data["choices"][0]["message"]["content"].strip()
40
- else:
41
- print("AI response did not contain expected data.")
42
- return None
43
- except requests.exceptions.RequestException as e:
44
- print(f"Error connecting to AI API: {e}")
45
- return None
46
- except json.JSONDecodeError:
47
- print("Error decoding JSON response from AI API.")
48
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
- def get_audio_wav_link(text):
51
- """
52
- دریافت لینک فایل WAV از API تبدیل متن به گفتار.
53
- """
54
- encoded_text = requests.utils.quote(text) # Encode URL-unsafe characters
55
- tts_url = f"{TTS_API_BASE_URL}{TTS_API_FORMAT}{encoded_text}"
56
-
57
- try:
58
- # برای این API، فقط ساختار URL مهم است، نیازی به درخواست مستقیم برای دریافت لینک نیست.
59
- # فرض می‌شود که API بلافاصله لینک wav را به عنوان پاسخ GET برمی‌گرداند.
60
- # اما طبق توضیحات شما، خروجی به صورت لینک wav است.
61
- # این یعنی درخواست GET به آن URL، مستقیماً لینک را برمی‌گرداند.
62
- # اگر API مستقیماً لینک WAV را در بدنه پاسخ برمی‌گرداند، می‌توان از request.text استفاده کرد.
63
- # در غیر این صورت، شاید باید یک درخواست واقعی انجام داد.
64
- # با توجه به "خروجی صوت به صورت لینک wav است"، فرض می‌شود که خود URL ورودی، لینک WAV خروجی است.
65
- # اگر API یک JSON با لینک wav برمی‌گرداند، باید کد را تغییر داد.
66
- return tts_url
67
-
68
  except requests.exceptions.RequestException as e:
69
- print(f"Error generating TTS link: {e}")
70
- return None
71
-
72
- def main():
73
- print("--------------------------------------------------")
74
- print(" Talkbot Podcast Generator ")
75
- print("--------------------------------------------------")
76
- print("این اسکریپت یک متن پادکست تولید و لینک‌های صوتی را فراهم می‌کند.")
77
- print(" برای خروج، 'exit' را تایپ کنید.")
78
- print("--------------------------------------------------")
79
-
80
- while True:
81
- topic = input("\nموضوع پادکست را وارد کنید (یا 'exit' برای خروج): ")
82
- if topic.lower() == 'exit':
83
- break
84
-
85
- print(f"\nدر حال تولید اسکریپت پادکست برای '{topic}' با هوش مصنوعی...")
86
- podcast_script = get_text_from_ai(topic)
87
-
88
- if podcast_script:
89
- print("\n------------------- اسکریپت پادکست -------------------")
90
- print(podcast_script)
91
- print("------------------------------------------------------")
92
-
93
- # تقسیم متن به دو بخش برای صدای اول و صدای دوم
94
- # این یک تقسیم‌بندی ساده است. ممکن است نیاز به منطق دقیق‌تری داشته باشید.
95
- sentences = [s.strip() for s in podcast_script.split('.') if s.strip()]
96
-
97
- if len(sentences) >= 2:
98
- speaker1_text = sentences[0]
99
- speaker2_text = sentences[1]
100
- elif len(sentences) == 1:
101
- speaker1_text = sentences[0]
102
- speaker2_text = "" # یا بخشی از جمله اول
103
- else:
104
- print("متن کافی برای تقسیم بین دو گوینده وجود ندارد.")
105
- speaker1_text = podcast_script
106
- speaker2_text = ""
107
-
108
- print("\nدر حال ساخت لینک‌های صوتی...")
109
-
110
- audio_link_speaker1 = get_audio_wav_link(speaker1_text)
111
- audio_link_speaker2 = get_audio_wav_link(speaker2_text) # اگر speaker2_text خالی باشد، لینک معناداری تولید نمی‌شود.
112
-
113
- if audio_link_speaker1:
114
- print(f"لینک صدای اول (Speaker 1): {audio_link_speaker1}")
115
- else:
116
- print("خطا در تولید لینک صدای اول.")
117
-
118
- if audio_link_speaker2 and speaker2_text: # فقط اگر متن برای گوینده دوم وجود داشته باشد
119
- print(f"لینک صدای دوم (Speaker 2): {audio_link_speaker2}")
120
- elif speaker2_text: # اگر speaker2_text داشتیم و لینکی تولید نشد
121
- print("خطا در تولید لینک صدای دوم.")
122
- else:
123
- print("متن کافی برای تولید صدای دوم وجود نداشت.")
124
-
125
- print("\n------------------------------------------------------")
126
- else:
127
- print("متن پادکست از هوش مصنوعی دریافت نشد.")
128
- print("لطفاً اتصال به اینترنت و کلید API را بررسی کنید.")
129
-
130
- print("\nخروج از برنامه. موفق باشید!")
131
 
132
  if __name__ == "__main__":
133
- main()
 
1
+ # -*- coding: utf-8 -*-
2
+ import gradio as gr
3
  import requests
4
  import json
5
+ from pydub import AudioSegment
6
  import os
7
 
8
+ # API Keys and Endpoints
9
+ TTS_URL = "https://talkbot.ir/TTS-tkun"
10
+ TEXT_GEN_URL = "https://talkbot.ir/api/v1/chat/completions"
11
+ TEXT_GEN_API_KEY = "sk-4fb613f56acfccf731e801b904cd89f5"
12
+ TEXT_GEN_MODEL = "deepseek-v3-0324"
13
 
14
+ def generate_podcast(topic):
 
 
 
 
 
15
  """
16
+ Generates a podcast based on a given topic.
17
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  try:
19
+ # 1. Generate podcast script using the text generation API
20
+ print("Generating podcast script...")
21
+ headers = {
22
+ "Authorization": f"Bearer {TEXT_GEN_API_KEY}",
23
+ "Content-Type": "application/json"
24
+ }
25
+ payload = {
26
+ "model": TEXT_GEN_MODEL,
27
+ "messages": [
28
+ {"role": "system", "content": "به عنوان یک تولیدکننده پادکست، یک متن جذاب برای پادکست با دو گوینده (صدای اول و صدای دوم) در مورد موضوع زیر ایجاد کنید. متن باید شامل گفتگو بین دو گوینده باشد."},
29
+ {"role": "user", "content": f"موضوع: {topic}"}
30
+ ],
31
+ "stream": False
32
+ }
33
+
34
+ response = requests.post(TEXT_GEN_URL, headers=headers, json=payload)
35
+ response.raise_for_status() # Raise an exception for bad status codes
36
+ script_data = response.json()
37
+ podcast_script = script_data['choices'][0]['message']['content']
38
+ print("Podcast script generated.")
39
+
40
+ # 2. Split the script into sections for each voice (This is a simplified approach)
41
+ # You might need a more sophisticated parsing method for real-world scenarios
42
+ lines = podcast_script.split('\n')
43
+ voice1_lines = []
44
+ voice2_lines = []
45
+ current_voice = 1 # Assuming the first line is for voice 1
46
+
47
+ for line in lines:
48
+ if line.strip().startswith("صدای اول:"):
49
+ voice1_lines.append(line.replace("صدای اول:", "", 1).strip())
50
+ current_voice = 1
51
+ elif line.strip().startswith("صدای دوم:"):
52
+ voice2_lines.append(line.replace("صدای دوم:", "", 1).strip())
53
+ current_voice = 2
54
+ elif line.strip(): # Lines withoutexplicit voice indicators
55
+ if current_voice == 1:
56
+ voice1_lines.append(line.strip())
57
+ else:
58
+ voice2_lines.append(line.strip())
59
+
60
+
61
+ voice1_text = " ".join(voice1_lines)
62
+ voice2_text = " ".join(voice2_lines)
63
+
64
+ if not voice1_text.strip() and not voice2_text.strip():
65
+ return None, "خطا در تجزیه متن پادکست. لطفاً متن generado شده را بررسی کنید.", None
66
+
67
+ # 3. Generate audio for each voice
68
+ print("Generating audio for voice 1...")
69
+ voice1_audio_url = requests.get(TTS_URL, params={"text": voice1_text}).text.strip()
70
+ print(f"Voice 1 audio URL: {voice1_audio_url}")
71
+
72
+ print("Generating audio for voice 2...")
73
+ voice2_audio_url = requests.get(TTS_URL, params={"text": voice2_text}).text.strip()
74
+ print(f"Voice 2 audio URL: {voice2_audio_url}")
75
+
76
+ if not voice1_audio_url.startswith("http") or not voice2_audio_url.startswith("http"):
77
+ return None, "خطا در تولید صدای TTS. لطفاً متن را بررسی کنید.", None
78
+
79
+ # 4. Download audio files
80
+ print("Downloading audio files...")
81
+ voice1_audio_response = requests.get(voice1_audio_url)
82
+ voice1_audio_response.raise_for_status()
83
+ voice1_audio_path = "voice1.wav"
84
+ with open(voice1_audio_path, "wb") as f:
85
+ f.write(voice1_audio_response.content)
86
+
87
+ voice2_audio_response = requests.get(voice2_audio_url)
88
+ voice2_audio_response.raise_for_status()
89
+ voice2_audio_path = "voice2.wav"
90
+ with open(voice2_audio_path, "wb") as f:
91
+ f.write(voice2_audio_response.content)
92
+
93
+ print("Audio files downloaded.")
94
+
95
+ # 5. Combine audio files (This is a simple concatenation for demonstration)
96
+ # For a proper podcast with alternating speakers, you would need more complex pydub manipulation
97
+ print("Combining audio files...")
98
+ audio1 = AudioSegment.from_wav(voice1_audio_path)
99
+ audio2 = AudioSegment.from_wav(voice2_audio_path)
100
+
101
+ # A simple way to interleave: This assumes segments are short and alternate
102
+ # For longer narrations, you'd need to split the audio files further
103
+ combined_audio = AudioSegment.empty()
104
+ max_len = max(len(audio1), len(audio2))
105
+ segment_length = 5000 # Example segment length in milliseconds
106
+
107
+ for i in range(0, max_len, segment_length):
108
+ segment1 = audio1[i : i + segment_length]
109
+ segment2 = audio2[i : i + segment_length]
110
+ if segment1:
111
+ combined_audio += segment1
112
+ if segment2:
113
+ combined_audio += segment2
114
+
115
+ output_mp3_path = "podcast.mp3"
116
+ combined_audio.export(output_mp3_path, format="mp3")
117
+ print(f"Podcast saved as {output_mp3_path}")
118
+
119
+ # 6. Clean up temporary files
120
+ os.remove(voice1_audio_path)
121
+ os.remove(voice2_audio_path)
122
+
123
+ return podcast_script, None, output_mp3_path
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  except requests.exceptions.RequestException as e:
126
+ return None, f"خطا در اتصال به API ها: {e}", None
127
+ except Exception as e:
128
+ return None, f"خطای نامشخص: {e}", None
129
+
130
+ # Gradio Interface
131
+ def gradio_interface(topic):
132
+ script, error, audio_path = generate_podcast(topic)
133
+ if error:
134
+ return error, None
135
+ else:
136
+ return script, audio_path
137
+
138
+ with gr.Blocks() as demo:
139
+ gr.Markdown("## ساخت پادکست با هوش مصنوعی")
140
+ topic_input = gr.Textbox(label="موضوع پادکست خود را وارد کنید")
141
+ generate_button = gr.Button("شروع تولید پادکست")
142
+ script_output = gr.Textbox(label="متن پادکست", interactive=False)
143
+ audio_output = gr.Audio(label="پادکست تولید شده", type="filepath")
144
+
145
+ generate_button.click(
146
+ fn=gradio_interface,
147
+ inputs=topic_input,
148
+ outputs=[script_output, audio_output]
149
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
 
151
  if __name__ == "__main__":
152
+ demo.launch()