Files changed (1) hide show
  1. app.py +58 -105
app.py CHANGED
@@ -10,39 +10,20 @@ import time
10
  import numpy as np
11
  import re
12
  import json
13
- import uuid # 👈 Session ID ထုတ်ရန်အတွက် Import လုပ်ခြင်း
14
  from google import genai
15
- from datetime import datetime, date
16
  from PIL import Image, ImageDraw, ImageFont
17
 
18
  # =====================================================================
19
- # ⚙️ SECURITY SETTINGS & LOGIN CONFIG
20
  # =====================================================================
21
  MAX_SUBTITLE_DURATION_SECONDS = 7.0
22
 
23
- # 👥 LOGIN ACCOUNTS CONFIG (အကောင့်တစ်ခုတည်းကို လူအများ မျှသုံးနိုင်ပါသည်)
24
- ACCOUNTS = {
25
- "user1": "123123", # Free User (Session/Browser အလိုက် တစ်ရက် ၂ ပုဒ်)
26
- "admin": "admin789" # Admin User (Unlimited)
27
- }
28
-
29
- EXPIRY_DATE_STR = "2026-8-31"
30
-
31
- # 🛑 USER RATE LIMIT TRACKER (Session/Browser ID အလိုက် ရေတွက်မည်)
32
- USER_LIMIT_TRACKER = {}
33
-
34
  SYSTEM_INSTRUCTION = "You are a professional movie recap writer. Translate movie subtitle lines into natural, engaging, and thrilling Burmese movie recap style. Keep it concise."
35
  MODEL_NAME = "gemini-2.5-flash"
36
 
37
  def check_app_expiry():
38
- try:
39
- expiry_date = datetime.strptime(EXPIRY_DATE_STR, "%Y-%m-%d").date()
40
- current_date = datetime.now().date()
41
- if current_date > expiry_date:
42
- return False, f"❌ ဤ App သည် သက်တမ်းကုန်ဆုံးသွားပါပြီ ({EXPIRY_DATE_STR})။"
43
- return True, "Active"
44
- except Exception as e:
45
- return False, f"လုံခြုံရေး စစ်ဆေးမှု မှားယွင်းနေပါသည်- {str(e)}"
46
 
47
  print("Loading Multilingual Faster-Whisper Base Model...")
48
  model = WhisperModel("base", device="cpu", compute_type="int8", cpu_threads=4)
@@ -81,12 +62,11 @@ def update_preview_image(video_path, blur_y_percent, blur_strength):
81
  return None
82
 
83
  # =====================================================================
84
- # ⚡ DYNAMIC USER-PROVIDED API KEY TRANSLATION ENGINE
85
  # =====================================================================
86
  def google_backup_translate(text, source_lang="en"):
87
  from urllib.parse import quote
88
  import urllib.request
89
- import json
90
  try:
91
  url = f"https://translate.googleapis.com/translate_a/single?client=gtx&sl={source_lang}&tl=my&dt=t&q={quote(text)}"
92
  req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
@@ -100,7 +80,7 @@ def translate_segments_batch(segments, user_api_key, source_lang="en"):
100
  if not segments: return segments
101
 
102
  if not user_api_key or not user_api_key.strip():
103
- print(f"⚠️ User က Gemini API Key မထည့်ထားပါ။ Google Translate Backup စနစ်ဖြင့် ဘာသာပြန်နေပါသည်။ (Source Lang: {source_lang})")
104
  for seg in segments:
105
  seg['mm_text'] = google_backup_translate(seg['text'], source_lang=source_lang)
106
  return segments
@@ -138,7 +118,7 @@ def translate_segments_batch(segments, user_api_key, source_lang="en"):
138
 
139
  translated_map = json.loads(response_text)
140
  except Exception as e:
141
- print(f"⚠️ User Gemini API Error သို့မဟုတ် Format Error: {e} -> Google Translate သို့ ပြောင်းလဲနေသည်။")
142
 
143
  for idx, seg in enumerate(segments):
144
  key_str = str(idx)
@@ -150,7 +130,7 @@ def translate_segments_batch(segments, user_api_key, source_lang="en"):
150
  return segments
151
 
152
  # =====================================================================
153
- # 🎬 TEXT WRAPPING & RENDER SYSTEMS
154
  # =====================================================================
155
  def segment_myanmar_syllables(text):
156
  return re.findall(r'[a-zA-Z0-9\s\-\.,!\?]+|[\u1000-\u102a\u103f\u1040-\u1049]+[\u102b-\u103e\u1060-\u109f]*|[^\s]', text)
@@ -180,7 +160,34 @@ def draw_line_perfect_rendering(draw, position, text, font_primary, fill_color,
180
  clean_text = text.replace(" ြ", "ြ").replace("ြ ", "ြ")
181
  draw.text((x, y), clean_text, font=font_primary, fill=fill_color, stroke_width=stroke_w, stroke_fill=stroke_c)
182
 
183
- def generate_voice_sync(text, voice_id, filename, desired_speed, target_duration_sec=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  rate_percentage = int((desired_speed - 1.0) * 100)
185
  rate_str = f"{'+' if rate_percentage >= 0 else ''}{rate_percentage}%"
186
 
@@ -195,64 +202,27 @@ def generate_voice_sync(text, voice_id, filename, desired_speed, target_duration
195
  communicate = edge_tts.Communicate(text, voice_id, rate=rate_str)
196
  await communicate.save(filename)
197
 
198
- try: loop = asyncio.get_event_loop()
199
- except RuntimeError:
200
- loop = asyncio.new_event_loop()
201
- asyncio.set_event_loop(loop)
202
-
203
- if loop.is_running():
204
- import threading
205
- t = threading.Thread(target=lambda: asyncio.run(_async_gen()))
206
  t.start()
207
  t.join()
208
- else:
209
- loop.run_until_complete(_async_gen())
210
 
211
  # =====================================================================
212
- # 🎬 HIGH-SPEED PRODUCTION AUTOMATION ENGINE
213
  # =====================================================================
214
  def process_magic_recap_video(
215
  video_path, user_api_key, ratio_select, background_fill, enable_zoom, zoom_level,
216
- logo_file, mirror_flip, filter_color, voice_gender, tone_style,
217
  text_color, stroke_color, blur_y_percent, blur_strength, sub_pos_percent, desired_speed,
218
- session_id, # 👈 Browser Session State
219
- request: gr.Request,
220
  progress=gr.Progress(track_tqdm=True)
221
  ):
222
  is_valid, msg = check_app_expiry()
223
  if not is_valid: raise gr.Error(msg)
224
  if not video_path: return None
225
-
226
- # 🛑 LOGIN ACCOUNT & SESSION ID ယူခြင်း
227
- login_username = request.username if (request and hasattr(request, 'username')) else "user1"
228
-
229
- if login_username == "admin":
230
- user_identifier = "admin"
231
- else:
232
- # Browser Session ID ဖြင့် လူတစ်ဦးစီကို သီးခြား ခွဲခြားမည်
233
- user_identifier = f"session_{session_id}"
234
-
235
- current_timestamp = time.time()
236
- print(f"👤 အသုံးပြုသူ Account: {login_username} | Identifier: {user_identifier}")
237
-
238
- # Admin မဟုတ်ပါက Session/Browser အလိုက် ၁ ရက် (၂) ပုဒ် Limit စစ်ဆေးမည်
239
- if user_identifier != "admin":
240
- if user_identifier in USER_LIMIT_TRACKER:
241
- user_data = USER_LIMIT_TRACKER[user_identifier]
242
- first_time = user_data["first_time"]
243
- count = user_data["count"]
244
- elapsed_time = current_timestamp - first_time
245
-
246
- if elapsed_time < 86400: # ၂၄ နာရီ အတွင်း
247
- if count >= 2: # ၂ ပုဒ် ပြည့်ပါက တားဆီးမည်
248
- remaining_seconds = 86400 - elapsed_time
249
- rem_hours = int(remaining_seconds // 3600)
250
- rem_mins = int((remaining_seconds % 3600) // 60)
251
- raise gr.Error(f"❌ ခွင့်ပြုချက်ကျော်လွန်နေပါသည်။ သင့် Browser မှ တစ်ရက်လျှင် ဗီဒီယို (၂) ပုဒ်သာ ထုတ်ယူခွင့်ရှိသည်။ ပြန်လည်စမ်းသပ်ရန် {rem_hours} နာရီ {rem_mins} မိနစ် လိုအပ်ပါသေးသည်။")
252
- else:
253
- USER_LIMIT_TRACKER[user_identifier] = {"count": 0, "first_time": current_timestamp}
254
- else:
255
- USER_LIMIT_TRACKER[user_identifier] = {"count": 0, "first_time": current_timestamp}
256
 
257
  temp_dir = "temp_space_workspace"
258
  if os.path.exists(temp_dir): shutil.rmtree(temp_dir)
@@ -293,9 +263,9 @@ def process_magic_recap_video(
293
 
294
  detected_lang = info.language
295
  if user_api_key and user_api_key.strip():
296
- progress(0.30, desc=f"⚡ ထည့်သွင်းထားသော Gemini API ({detected_lang}) စနစ်ဖြင့် ဘာသာပြန်နေပါသည်...")
297
  else:
298
- progress(0.30, desc=f"🌐 Google Translate Backup ({detected_lang}) စနစ်ဖြင့် ဘာသာပြန်နေပါသည်...")
299
 
300
  segments = translate_segments_batch(segments, user_api_key, source_lang=detected_lang)
301
 
@@ -328,7 +298,7 @@ def process_magic_recap_video(
328
  raw_seg_filename = os.path.join(temp_dir, f"raw_{idx}.mp3")
329
  fixed_seg_filename = os.path.join(temp_dir, f"fixed_{idx}.mp3")
330
 
331
- generate_voice_sync(mm_text, voice_id, raw_seg_filename, 1.15, orig_dur)
332
 
333
  if os.path.exists(raw_seg_filename) and os.path.getsize(raw_seg_filename) > 0:
334
  subprocess.run([
@@ -356,7 +326,10 @@ def process_magic_recap_video(
356
 
357
  font_size = int(target_h * 0.038)
358
  font_path = "Myanmar font.ttf"
359
- font_primary = ImageFont.truetype(font_path, font_size) if os.path.exists(font_path) else ImageFont.load_default()
 
 
 
360
 
361
  t_color, s_color = hex_to_rgb(text_color), hex_to_rgb(stroke_color)
362
  b_h = int(target_h * 0.12)
@@ -462,12 +435,6 @@ def process_magic_recap_video(
462
  subprocess.run(['ffmpeg', '-y', '-i', final_burn_temp, '-c:v', 'libx264', '-preset', 'ultrafast', '-threads', '0', '-pix_fmt', 'yuv420p', output_video_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
463
 
464
  if os.path.exists(temp_dir): shutil.rmtree(temp_dir)
465
-
466
- # 📈 ဗီဒီယို အောင်မြင်စွာ ထုတ်ယူပြီးမှသာ ထို Session ၏ Count ကို ၁ တိုးမည်
467
- if user_identifier != "admin":
468
- USER_LIMIT_TRACKER[user_identifier]["count"] += 1
469
- print(f"✅ [{user_identifier}] ဗီဒီယိုထုတ်ယူမှု အောင်မြင်ပါသည်။ ယနေ့ ထုတ်ယူပြီးစီးမှု: {USER_LIMIT_TRACKER[user_identifier]['count']} ကြိမ်")
470
-
471
  return output_video_path
472
 
473
  except Exception as e:
@@ -478,18 +445,9 @@ def process_magic_recap_video(
478
  # 🎨 GRADIO INTERFACE
479
  # =====================================================================
480
  def create_main_app_interface():
481
- is_valid, msg = check_app_expiry()
482
-
483
  with gr.Blocks() as main_app:
484
- # 🔑 အသုံးပြုသူတိုင်းအတွက် သီးသန့် Session ID ထုတ်ပေးခြင်း
485
- session_id_state = gr.State(lambda: str(uuid.uuid4()))
486
-
487
- gr.Markdown("<h1 style='text-align: center; color: #5B50F3;'>✨ Video Auto Recap (Multi-Account) ✨</h1>")
488
- if not is_valid:
489
- gr.Markdown(f"### {msg}")
490
- return main_app
491
-
492
- gr.Markdown("<div style='background-color: #333; padding: 10px; border-radius: 8px; text-align: center; color: #fff;'>📢 <b>Free App Rules:</b> တစ်ရက်လျှင် Video (၂) ပုဒ် အခမဲ့ ထုတ်ယူခွင့် ရှိပါသည်</div>")
493
 
494
  with gr.Row():
495
  with gr.Column(scale=2):
@@ -497,13 +455,14 @@ def create_main_app_interface():
497
  preview_image = gr.Image(label="🖼️ Interactive Blur Preview", interactive=False)
498
 
499
  with gr.Column(scale=1):
500
- user_api_key = gr.Textbox(label="🔑 သင်၏ Gemini API Key ထည့်ရန် (မထည့်ပါက Google Translate ဖြင့် လုပ်ဆောင်မည်)", placeholder="AIZAcy... (Optional)", type="password")
501
  ratio_select = gr.Dropdown(choices=["9:16 (Tiktok/Reels)", "16:9 (Landscape)"], value="9:16 (Tiktok/Reels)", label="ဗီဒီယိုအမျိုးအစား")
502
  background_fill = gr.Radio(choices=["Blur Background (အနောက်ခံ ဝါးမည်)", "Black Background (အမည်းရောင်ထားမည်)"], value="Blur Background (အနောက်ခံ ဝါးမည်)", label="နောက်ခံ ဖြည့်စွက်မှု")
503
 
504
  with gr.Column(variant="panel"):
505
  gr.Markdown("### 🗣️ အသံနှင့် စာတန်းထိုး ဆက်တင်များ")
506
- voice_select = gr.Radio(choices=["🧕 မိန်းကလေး (Female)", "👨 ယောကျာ်လေး (Male)"], value="🧕 မိန်းကလေး (Female)", label="AI အသံ အမျိးအား")
 
507
  tone_style = gr.Dropdown(choices=["Thriller", "Comedy", "Dramatic", "Action/Epic"], value="Thriller", label="🎬 Narrative Tone")
508
  text_color_input = gr.ColorPicker(label="စာလုံးအရောင်", value="#FFFF00")
509
  stroke_color_input = gr.ColorPicker(label="အနားသတ်အရောင်", value="#000000")
@@ -532,21 +491,15 @@ def create_main_app_interface():
532
  fn=process_magic_recap_video,
533
  inputs=[
534
  video_input, user_api_key, ratio_select, background_fill, enable_zoom, zoom_level,
535
- logo_file, mirror_flip, filter_color, voice_select, tone_style, text_color_input,
536
- stroke_color_input, blur_y_percent, blur_strength, sub_pos_percent, desired_speed,
537
- session_id_state # 👈 session_id ကို Function ထဲ ပို့ပေးခြင်း
538
  ],
539
  outputs=[output_video]
540
  )
541
 
542
  return main_app
543
 
544
- def verify_member(username, password):
545
- if username in ACCOUNTS and ACCOUNTS[username] == password:
546
- return True
547
- return False
548
-
549
  demo_app = create_main_app_interface()
550
 
551
  if __name__ == "__main__":
552
- demo_app.launch(auth=verify_member, theme=gr.themes.Default())
 
10
  import numpy as np
11
  import re
12
  import json
13
+ import threading
14
  from google import genai
 
15
  from PIL import Image, ImageDraw, ImageFont
16
 
17
  # =====================================================================
18
+ # ⚙️ SETTINGS & CONFIG (Login & Limits Removed)
19
  # =====================================================================
20
  MAX_SUBTITLE_DURATION_SECONDS = 7.0
21
 
 
 
 
 
 
 
 
 
 
 
 
22
  SYSTEM_INSTRUCTION = "You are a professional movie recap writer. Translate movie subtitle lines into natural, engaging, and thrilling Burmese movie recap style. Keep it concise."
23
  MODEL_NAME = "gemini-2.5-flash"
24
 
25
  def check_app_expiry():
26
+ return True, "Active"
 
 
 
 
 
 
 
27
 
28
  print("Loading Multilingual Faster-Whisper Base Model...")
29
  model = WhisperModel("base", device="cpu", compute_type="int8", cpu_threads=4)
 
62
  return None
63
 
64
  # =====================================================================
65
+ # ⚡ TRANSLATION ENGINE
66
  # =====================================================================
67
  def google_backup_translate(text, source_lang="en"):
68
  from urllib.parse import quote
69
  import urllib.request
 
70
  try:
71
  url = f"https://translate.googleapis.com/translate_a/single?client=gtx&sl={source_lang}&tl=my&dt=t&q={quote(text)}"
72
  req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
 
80
  if not segments: return segments
81
 
82
  if not user_api_key or not user_api_key.strip():
83
+ print(f"⚠️ User က Gemini API Key မထည့်ထားပါ။ Google Translate Backup စနစ်ဖြင့် ဘာသာပြန်နေပါသည်။")
84
  for seg in segments:
85
  seg['mm_text'] = google_backup_translate(seg['text'], source_lang=source_lang)
86
  return segments
 
118
 
119
  translated_map = json.loads(response_text)
120
  except Exception as e:
121
+ print(f"⚠️ Gemini API Error: {e} -> Google Translate သို့ ပြောင်းလဲနေသည်။")
122
 
123
  for idx, seg in enumerate(segments):
124
  key_str = str(idx)
 
130
  return segments
131
 
132
  # =====================================================================
133
+ # 🎬 TEXT WRAPPING & VOICE GENERATION SYSTEMS
134
  # =====================================================================
135
  def segment_myanmar_syllables(text):
136
  return re.findall(r'[a-zA-Z0-9\s\-\.,!\?]+|[\u1000-\u102a\u103f\u1040-\u1049]+[\u102b-\u103e\u1060-\u109f]*|[^\s]', text)
 
160
  clean_text = text.replace(" ြ", "ြ").replace("ြ ", "ြ")
161
  draw.text((x, y), clean_text, font=font_primary, fill=fill_color, stroke_width=stroke_w, stroke_fill=stroke_c)
162
 
163
+ def generate_voice_sync(text, voice_id, filename, desired_speed, target_duration_sec=None, user_api_key=None, voice_engine="Edge-TTS"):
164
+ # Google AI Studio Audio (Gemini Native Audio) အသုံးပြုလိုပါက
165
+ if voice_engine == "Google AI Studio Audio" and user_api_key and user_api_key.strip():
166
+ try:
167
+ client = genai.Client(api_key=user_api_key.strip())
168
+ prompt = f"Read the following Burmese movie recap text naturally and clearly with an engaging narrative tone. Generate audio output:\n{text}"
169
+ response = client.models.generate_content(
170
+ model=MODEL_NAME,
171
+ contents=prompt,
172
+ config={
173
+ "response_mime_type": "audio/mp3",
174
+ }
175
+ )
176
+ audio_saved = False
177
+ for candidate in response.candidates:
178
+ for part in candidate.content.parts:
179
+ if hasattr(part, 'inline_data') and part.inline_data:
180
+ with open(filename, "wb") as f:
181
+ f.write(part.inline_data.data)
182
+ audio_saved = True
183
+ break
184
+ if audio_saved: break
185
+ if audio_saved and os.path.exists(filename) and os.path.getsize(filename) > 0:
186
+ return
187
+ except Exception as e:
188
+ print(f"⚠️ Google AI Studio Audio Error: {e} -> Edge-TTS သို့ အလိုအလျောက် ပြောင်းလဲနေသည်။")
189
+
190
+ # Default: Edge-TTS
191
  rate_percentage = int((desired_speed - 1.0) * 100)
192
  rate_str = f"{'+' if rate_percentage >= 0 else ''}{rate_percentage}%"
193
 
 
202
  communicate = edge_tts.Communicate(text, voice_id, rate=rate_str)
203
  await communicate.save(filename)
204
 
205
+ try:
206
+ def run_in_thread():
207
+ asyncio.run(_async_gen())
208
+ t = threading.Thread(target=run_in_thread)
 
 
 
 
209
  t.start()
210
  t.join()
211
+ except Exception as e:
212
+ print(f"Audio Generation Error: {e}")
213
 
214
  # =====================================================================
215
+ # 🎬 PRODUCTION AUTOMATION ENGINE (Limits Removed)
216
  # =====================================================================
217
  def process_magic_recap_video(
218
  video_path, user_api_key, ratio_select, background_fill, enable_zoom, zoom_level,
219
+ logo_file, mirror_flip, filter_color, voice_gender, voice_engine_select, tone_style,
220
  text_color, stroke_color, blur_y_percent, blur_strength, sub_pos_percent, desired_speed,
 
 
221
  progress=gr.Progress(track_tqdm=True)
222
  ):
223
  is_valid, msg = check_app_expiry()
224
  if not is_valid: raise gr.Error(msg)
225
  if not video_path: return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
  temp_dir = "temp_space_workspace"
228
  if os.path.exists(temp_dir): shutil.rmtree(temp_dir)
 
263
 
264
  detected_lang = info.language
265
  if user_api_key and user_api_key.strip():
266
+ progress(0.30, desc=f"⚡ ထည့်သွင်းထားသော Gemini API စနစ်ဖြင့် ဘာသာပြန်နေပါသည်...")
267
  else:
268
+ progress(0.30, desc=f"🌐 Google Translate Backup စနစ်ဖြင့် ဘာသာပြန်နေပါသည်...")
269
 
270
  segments = translate_segments_batch(segments, user_api_key, source_lang=detected_lang)
271
 
 
298
  raw_seg_filename = os.path.join(temp_dir, f"raw_{idx}.mp3")
299
  fixed_seg_filename = os.path.join(temp_dir, f"fixed_{idx}.mp3")
300
 
301
+ generate_voice_sync(mm_text, voice_id, raw_seg_filename, 1.15, orig_dur, user_api_key=user_api_key, voice_engine=voice_engine_select)
302
 
303
  if os.path.exists(raw_seg_filename) and os.path.getsize(raw_seg_filename) > 0:
304
  subprocess.run([
 
326
 
327
  font_size = int(target_h * 0.038)
328
  font_path = "Myanmar font.ttf"
329
+ if os.path.exists(font_path):
330
+ font_primary = ImageFont.truetype(font_path, font_size)
331
+ else:
332
+ font_primary = ImageFont.load_default()
333
 
334
  t_color, s_color = hex_to_rgb(text_color), hex_to_rgb(stroke_color)
335
  b_h = int(target_h * 0.12)
 
435
  subprocess.run(['ffmpeg', '-y', '-i', final_burn_temp, '-c:v', 'libx264', '-preset', 'ultrafast', '-threads', '0', '-pix_fmt', 'yuv420p', output_video_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
436
 
437
  if os.path.exists(temp_dir): shutil.rmtree(temp_dir)
 
 
 
 
 
 
438
  return output_video_path
439
 
440
  except Exception as e:
 
445
  # 🎨 GRADIO INTERFACE
446
  # =====================================================================
447
  def create_main_app_interface():
 
 
448
  with gr.Blocks() as main_app:
449
+ gr.Markdown("<h1 style='text-align: center; color: #5B50F3;'>✨ Video Auto Recap (Unlimited & AI Audio) ✨</h1>")
450
+ gr.Markdown("<div style='background-color: #222; padding: 10px; border-radius: 8px; text-align: center; color: #fff;'>📢 <b>Notice:</b> Login စနစ်နှင့် ကန့်သတ်ချက်များ (Limits) အားလုံး ဖြုတ်ထားပြီးဖြစ်ပါသည်။ Google AI Studio Audio (သို့) Edge-TTS ကို ရွေးချယ်အသုံးပြုနိုင်ပါသည်။</div>")
 
 
 
 
 
 
 
451
 
452
  with gr.Row():
453
  with gr.Column(scale=2):
 
455
  preview_image = gr.Image(label="🖼️ Interactive Blur Preview", interactive=False)
456
 
457
  with gr.Column(scale=1):
458
+ user_api_key = gr.Textbox(label="🔑 သင်၏ Gemini API Key ထည့်ရန် (ဘာသာပြန်နှင့် Google AI Studio အသံအတွက် လပ်ည်)", placeholder="AIZAcy...", type="password")
459
  ratio_select = gr.Dropdown(choices=["9:16 (Tiktok/Reels)", "16:9 (Landscape)"], value="9:16 (Tiktok/Reels)", label="ဗီဒီယိုအမျိုးအစား")
460
  background_fill = gr.Radio(choices=["Blur Background (အနောက်ခံ ဝါးမည်)", "Black Background (အမည်းရောင်ထားမည်)"], value="Blur Background (အနောက်ခံ ဝါးမည်)", label="နောက်ခံ ဖြည့်စွက်မှု")
461
 
462
  with gr.Column(variant="panel"):
463
  gr.Markdown("### 🗣️ အသံနှင့် စာတန်းထိုး ဆက်တင်များ")
464
+ voice_engine_select = gr.Radio(choices=["Edge-TTS", "Google AI Studio Audio"], value="Google AI Studio Audio", label="🎙️ အသံတ်လုပ်သည့်နစ် (Voice Engine)")
465
+ voice_select = gr.Radio(choices=["🧕 မိန်းကလေး (Female)", "👨 ယောကျာ်လေး (Male)"], value="🧕 မိန်းကလေး (Female)", label="AI အသံ ပုံစံ (Edge-TTS အတွက်သာ)")
466
  tone_style = gr.Dropdown(choices=["Thriller", "Comedy", "Dramatic", "Action/Epic"], value="Thriller", label="🎬 Narrative Tone")
467
  text_color_input = gr.ColorPicker(label="စာလုံးအရောင်", value="#FFFF00")
468
  stroke_color_input = gr.ColorPicker(label="အနားသတ်အရောင်", value="#000000")
 
491
  fn=process_magic_recap_video,
492
  inputs=[
493
  video_input, user_api_key, ratio_select, background_fill, enable_zoom, zoom_level,
494
+ logo_file, mirror_flip, filter_color, voice_select, voice_engine_select, tone_style, text_color_input,
495
+ stroke_color_input, blur_y_percent, blur_strength, sub_pos_percent, desired_speed
 
496
  ],
497
  outputs=[output_video]
498
  )
499
 
500
  return main_app
501
 
 
 
 
 
 
502
  demo_app = create_main_app_interface()
503
 
504
  if __name__ == "__main__":
505
+ demo_app.launch(theme=gr.themes.Default())