Tamiloneto8 commited on
Commit
40027a1
Β·
verified Β·
1 Parent(s): fce5193

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -322
app.py CHANGED
@@ -11,7 +11,7 @@ logger = logging.getLogger(__name__)
11
  # It's recommended to set the HUGGINGFACE_TOKEN as an environment variable
12
  token = os.getenv("HUGGINGFACE_TOKEN")
13
 
14
- def create_DubIndic_interface():
15
  """
16
  Creates and configures the Gradio interface for the DubIndic application.
17
  """
@@ -26,15 +26,15 @@ def create_DubIndic_interface():
26
  with gr.Blocks() as demo:
27
  gr.Markdown("# 🚨 DubIndic - Connection Error")
28
  gr.Markdown(f"**Error Details:** {str(e)}")
29
- gr.Markdown("Please check your connection and try again.")
30
  return demo
31
 
32
  # Define wrapper functions to call the API endpoints
33
  def start_processing(audio_file, target_language):
34
  if not audio_file or not target_language:
 
35
  return (
36
- "⚠️ Please provide both an audio file and select a target language.",
37
- None, "", "", None, "",
38
  gr.update(visible=False), gr.update(visible=False)
39
  )
40
  try:
@@ -45,18 +45,16 @@ def create_DubIndic_interface():
45
  api_name="/process_audio_pipeline_step1"
46
  )
47
  logger.info("Received result from step 1: %s", result)
48
-
49
- # API returns a 7-element tuple, we map it to our UI outputs
50
- # [status, internal_val, orig_audio, trans, transl, dubbed_audio, progress]
51
  return (
52
  f"βœ… {result[0]}", result[2], result[3], result[4], result[5], result[6],
53
  gr.update(visible=True), gr.update(visible=True)
54
  )
55
  except Exception as e:
56
  logger.error("Error in start_processing: %s", e, exc_info=True)
 
57
  return (
58
- f"❌ Error: {str(e)}",
59
- None, "", "", None, "",
60
  gr.update(visible=False), gr.update(visible=False)
61
  )
62
 
@@ -64,31 +62,32 @@ def create_DubIndic_interface():
64
  api_to_call = "/lambda" if direction == "prev" else "/lambda_1"
65
  try:
66
  logger.info("Calling %s to navigate.", api_to_call)
67
- result = client.predict(
68
- t=transcription,
69
- tr=translation,
70
- api_name=api_to_call
71
- )
72
  logger.info("Received result from navigation: %s", result)
73
  return result[1], result[2], result[3], result[4], result[5]
74
  except Exception as e:
75
  logger.error("Error navigating chunks: %s", e, exc_info=True)
76
- return None, f"❌ Navigation error: {str(e)}", "", None, ""
 
77
 
78
  def generate_dubbed_chunk(transcription, translation):
79
  if not transcription and not translation:
 
80
  return None
81
  try:
82
  logger.info("Calling /generate_dubbed_chunk.")
 
83
  dubbed_path = client.predict(
84
  transcription=transcription,
85
  translation=translation,
86
  api_name="/generate_dubbed_chunk"
87
  )
88
  logger.info("Received dubbed chunk: %s", dubbed_path)
 
89
  return dubbed_path
90
  except Exception as e:
91
  logger.error("Error generating dubbed chunk: %s", e, exc_info=True)
 
92
  return None
93
 
94
  def finalize_current_chunk():
@@ -96,322 +95,70 @@ def create_DubIndic_interface():
96
  logger.info("Calling /finalize_current_chunk.")
97
  progress = client.predict(api_name="/finalize_current_chunk")
98
  logger.info("Received finalization progress: %s", progress)
 
99
  return f"βœ… {progress}"
100
  except Exception as e:
101
  logger.error("Error finalizing chunk: %s", e, exc_info=True)
 
102
  return f"❌ Error finalizing: {str(e)}"
103
 
104
  def merge_all_chunks():
105
  try:
106
  logger.info("Calling /merge_audio_files.")
 
107
  final_status, final_audio = client.predict(api_name="/merge_audio_files")
108
  logger.info("Received final merged audio.")
 
109
  return f"πŸŽ‰ {final_status}", final_audio
110
  except Exception as e:
111
  logger.error("Error merging audio files: %s", e, exc_info=True)
 
112
  return f"❌ Merge error: {str(e)}", None
113
 
114
- # Create custom theme with enhanced styling
115
- custom_theme = gr_themes.Soft(
116
- primary_hue="orange",
117
- secondary_hue="red",
118
- neutral_hue="slate"
119
- )
120
 
121
- # Enhanced CSS with creative design elements
122
- enhanced_css = """
123
- /* Main container styling */
124
- .gradio-container {
125
- background: linear-gradient(135deg, #fff8e6 0%, #fef3e2 50%, #fff8e6 100%);
126
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
127
- min-height: 100vh;
128
- }
129
-
130
- /* Header styling with animated gradient */
131
- .main-header {
132
- background: linear-gradient(45deg, #f97316, #ef4444, #f97316);
133
- background-size: 300% 300%;
134
- animation: gradientShift 6s ease infinite;
135
- -webkit-background-clip: text;
136
- -webkit-text-fill-color: transparent;
137
- background-clip: text;
138
- text-align: center;
139
- font-weight: 800;
140
- font-size: 2.5rem;
141
- margin-bottom: 1rem;
142
- }
143
-
144
- @keyframes gradientShift {
145
- 0% { background-position: 0% 50%; }
146
- 50% { background-position: 100% 50%; }
147
- 100% { background-position: 0% 50%; }
148
- }
149
-
150
- /* Card-like sections */
151
- .step-card {
152
- background: rgba(255, 255, 255, 0.9);
153
- border: 2px solid rgba(249, 115, 22, 0.2);
154
- border-radius: 16px;
155
- padding: 24px;
156
- margin: 16px 0;
157
- box-shadow: 0 8px 32px rgba(249, 115, 22, 0.1);
158
- backdrop-filter: blur(8px);
159
- transition: all 0.3s ease;
160
- }
161
-
162
- .step-card:hover {
163
- transform: translateY(-2px);
164
- box-shadow: 0 12px 48px rgba(249, 115, 22, 0.15);
165
- border-color: rgba(249, 115, 22, 0.4);
166
- }
167
-
168
- /* Enhanced primary buttons */
169
- .gr-button[variant="primary"] {
170
- background: linear-gradient(45deg, #f97316, #ef4444) !important;
171
- border: none !important;
172
- color: white !important;
173
- font-weight: 600 !important;
174
- padding: 12px 24px !important;
175
- border-radius: 12px !important;
176
- font-size: 1rem !important;
177
- transition: all 0.3s ease !important;
178
- box-shadow: 0 4px 16px rgba(249, 115, 22, 0.3) !important;
179
- }
180
-
181
- .gr-button[variant="primary"]:hover {
182
- background: linear-gradient(45deg, #ea580c, #dc2626) !important;
183
- transform: translateY(-2px) !important;
184
- box-shadow: 0 8px 24px rgba(239, 68, 68, 0.4) !important;
185
- }
186
-
187
- /* Enhanced secondary buttons */
188
- .gr-button[variant="secondary"] {
189
- background: rgba(255, 248, 230, 0.9) !important;
190
- border: 2px solid #f97316 !important;
191
- color: #f97316 !important;
192
- font-weight: 600 !important;
193
- padding: 10px 20px !important;
194
- border-radius: 10px !important;
195
- transition: all 0.3s ease !important;
196
- }
197
-
198
- .gr-button[variant="secondary"]:hover {
199
- background: linear-gradient(45deg, #f97316, #ef4444) !important;
200
- color: white !important;
201
- transform: translateY(-1px) !important;
202
- box-shadow: 0 4px 12px rgba(249, 115, 22, 0.3) !important;
203
- }
204
-
205
- /* Navigation buttons */
206
- .nav-button {
207
- background: linear-gradient(45deg, #f97316, #ef4444) !important;
208
- border: none !important;
209
- color: white !important;
210
- font-weight: 600 !important;
211
- padding: 8px 16px !important;
212
- border-radius: 8px !important;
213
- font-size: 0.9rem !important;
214
- min-width: 120px !important;
215
- }
216
-
217
- /* Input styling */
218
- .gr-textbox, .gr-dropdown {
219
- border: 2px solid rgba(249, 115, 22, 0.3) !important;
220
- border-radius: 12px !important;
221
- background: rgba(255, 255, 255, 0.95) !important;
222
- transition: all 0.3s ease !important;
223
- font-size: 1rem !important;
224
- }
225
-
226
- .gr-textbox:focus, .gr-dropdown:focus {
227
- border-color: #ef4444 !important;
228
- box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.1) !important;
229
- outline: none !important;
230
- }
231
-
232
- /* Audio player styling */
233
- .gr-audio {
234
- border: 2px solid rgba(249, 115, 22, 0.3) !important;
235
- border-radius: 12px !important;
236
- background: rgba(255, 255, 255, 0.95) !important;
237
- padding: 12px !important;
238
- }
239
-
240
- /* Progress indicators */
241
- .progress-text {
242
- background: linear-gradient(45deg, #f97316, #ef4444);
243
- -webkit-background-clip: text;
244
- -webkit-text-fill-color: transparent;
245
- background-clip: text;
246
- font-weight: 600;
247
- }
248
-
249
- /* Step numbers */
250
- .step-number {
251
- background: linear-gradient(45deg, #f97316, #ef4444);
252
- color: white;
253
- border-radius: 50%;
254
- width: 32px;
255
- height: 32px;
256
- display: inline-flex;
257
- align-items: center;
258
- justify-content: center;
259
- font-weight: bold;
260
- margin-right: 8px;
261
- }
262
-
263
- /* Section headers */
264
- .section-header {
265
- color: #f97316;
266
- font-weight: 700;
267
- font-size: 1.25rem;
268
- margin-bottom: 16px;
269
- display: flex;
270
- align-items: center;
271
- }
272
-
273
- /* Responsive design */
274
- @media (max-width: 768px) {
275
- .main-header {
276
- font-size: 2rem;
277
- }
278
- .step-card {
279
- padding: 16px;
280
- }
281
- }
282
-
283
- /* Loading animation */
284
- .loading {
285
- animation: pulse 2s infinite;
286
- }
287
-
288
- @keyframes pulse {
289
- 0% { opacity: 1; }
290
- 50% { opacity: 0.7; }
291
- 100% { opacity: 1; }
292
- }
293
- """
294
-
295
- # Define the enhanced Gradio interface
296
- with gr.Blocks(theme=custom_theme, title="DubIndic - AI Audio Dubbing", css=enhanced_css) as demo:
297
-
298
- # Main header
299
- gr.HTML('<div class="main-header">🎬 DubIndic - AI Audio Dubbing Pipeline</div>')
300
  gr.HTML('<div style="text-align: center; margin-bottom: 2rem; font-size: 1.1rem; color: #666;">Transform your audio into another Indian language with full editing control</div>')
301
-
302
- # Step 1: Upload & Configure
303
  with gr.Row():
304
  with gr.Column(scale=2):
305
- gr.HTML('<div class="step-card">')
306
- gr.HTML('<div class="section-header"><span class="step-number">1</span>πŸ“€ Upload & Configure</div>')
307
-
308
- with gr.Row():
309
- with gr.Column(scale=1):
310
- audio_input = gr.Audio(
311
- sources=["upload"],
312
- type="filepath",
313
- label="🎡 Upload Audio File",
314
- elem_classes=["upload-audio"]
315
- )
316
- with gr.Column(scale=1):
317
  lang_dropdown = gr.Dropdown(
318
  choices=["Assamese", "Bengali", "Gujarati", "Hindi", "Kannada", "Malayalam", "Marathi", "Odia", "Punjabi", "Tamil", "Telugu"],
319
- label="🌐 Target Language",
320
- value=None,
321
- elem_classes=["language-select"]
322
  )
323
-
324
- process_btn = gr.Button(
325
- "🎯 Start Processing",
326
- variant="primary",
327
- size="lg",
328
- elem_classes=["process-button"]
329
- )
330
-
331
- step1_output = gr.Textbox(
332
- label="πŸ“Š Processing Status",
333
- interactive=False,
334
- elem_classes=["status-output"]
335
- )
336
- gr.HTML('</div>')
337
-
338
- # Step 2: Edit & Generate (Initially Hidden)
339
- with gr.Column(visible=False, elem_classes=["step-card"]) as edit_section:
340
- gr.HTML('<div class="section-header"><span class="step-number">2</span>✏️ Edit, Generate & Finalize Chunks</div>')
341
-
342
- # Navigation controls
343
- with gr.Row():
344
- with gr.Column(scale=1):
345
- prev_btn = gr.Button("◀️ Previous", elem_classes=["nav-button"])
346
- with gr.Column(scale=1):
347
- next_btn = gr.Button("Next ▢️", elem_classes=["nav-button"])
348
-
349
- # Audio and text editing
350
- with gr.Row():
351
- with gr.Column(scale=1):
352
- original_audio = gr.Audio(
353
- label="🎡 Original Chunk Audio",
354
- type="filepath",
355
- interactive=False
356
- )
357
-
358
- with gr.Column(scale=1):
359
- transcription_text = gr.Textbox(
360
- label="πŸ“ Transcription (edit if needed)",
361
- lines=3,
362
- interactive=True,
363
- placeholder="Original transcription will appear here..."
364
- )
365
-
366
- translation_text = gr.Textbox(
367
- label="πŸ”„ Translation (edit if needed)",
368
- lines=3,
369
- interactive=True,
370
- placeholder="Translation will appear here..."
371
- )
372
-
373
- # Generate and finalize controls
374
- with gr.Row():
375
- with gr.Column(scale=1):
376
  generate_btn = gr.Button("πŸ”Š Generate Dubbed Chunk", variant="secondary")
377
- with gr.Column(scale=1):
378
  finalize_btn = gr.Button("βœ”οΈ Finalize Chunk", variant="secondary")
379
-
380
- dubbed_audio = gr.Audio(
381
- label="🎀 Dubbed Chunk Audio",
382
- type="filepath",
383
- interactive=False
384
- )
385
-
386
- progress_text = gr.Textbox(
387
- label="πŸ“ˆ Progress",
388
- interactive=False,
389
- elem_classes=["progress-text"]
390
- )
391
-
392
- # Step 3: Final Merge (Initially Hidden)
393
- with gr.Column(visible=False, elem_classes=["step-card"]) as merge_section:
394
- gr.HTML('<div class="section-header"><span class="step-number">3</span>🏁 Merge Final Audio</div>')
395
-
396
- merge_btn = gr.Button(
397
- "πŸš€ Merge All Finalized Chunks",
398
- variant="primary",
399
- size="lg"
400
- )
401
-
402
- with gr.Row():
403
- with gr.Column(scale=1):
404
- final_output = gr.Textbox(
405
- label="πŸŽ‰ Final Results",
406
- interactive=False,
407
- elem_classes=["final-status"]
408
- )
409
- with gr.Column(scale=1):
410
- output_audio = gr.Audio(
411
- label="πŸ”Š Final Dubbed Audio",
412
- type="filepath",
413
- interactive=False
414
- )
415
 
416
  # Connect functions to UI components
417
  process_btn.click(
@@ -419,49 +166,41 @@ def create_DubIndic_interface():
419
  inputs=[audio_input, lang_dropdown],
420
  outputs=[step1_output, original_audio, transcription_text, translation_text, dubbed_audio, progress_text, edit_section, merge_section]
421
  )
422
-
423
  prev_btn.click(
424
  fn=lambda t, tr: navigate_chunk(t, tr, "prev"),
425
  inputs=[transcription_text, translation_text],
426
  outputs=[original_audio, transcription_text, translation_text, dubbed_audio, progress_text]
427
  )
428
-
429
  next_btn.click(
430
  fn=lambda t, tr: navigate_chunk(t, tr, "next"),
431
  inputs=[transcription_text, translation_text],
432
  outputs=[original_audio, transcription_text, translation_text, dubbed_audio, progress_text]
433
  )
434
-
435
  generate_btn.click(
436
  fn=generate_dubbed_chunk,
437
  inputs=[transcription_text, translation_text],
438
  outputs=[dubbed_audio]
439
  )
440
-
441
  finalize_btn.click(
442
  fn=finalize_current_chunk,
443
  inputs=[],
444
  outputs=[progress_text]
445
  )
446
-
447
  merge_btn.click(
448
  fn=merge_all_chunks,
449
  inputs=[],
450
  outputs=[final_output, output_audio]
451
  )
452
-
453
  return demo
454
 
455
  if __name__ == "__main__":
456
- DubIndic_interface = create_DubIndic_interface()
457
- if DubIndic_interface:
458
- DubIndic_interface.launch(
459
- show_error=True,
460
- share=False,
461
- server_name="0.0.0.0",
462
- server_port=7860,
463
- favicon_path=None,
464
- show_tips=True
465
  )
466
  else:
467
  logger.error("Failed to create the Gradio interface.")
 
11
  # It's recommended to set the HUGGINGFACE_TOKEN as an environment variable
12
  token = os.getenv("HUGGINGFACE_TOKEN")
13
 
14
+ def create_dubindic_interface():
15
  """
16
  Creates and configures the Gradio interface for the DubIndic application.
17
  """
 
26
  with gr.Blocks() as demo:
27
  gr.Markdown("# 🚨 DubIndic - Connection Error")
28
  gr.Markdown(f"**Error Details:** {str(e)}")
29
+ gr.Markdown("Please check your Hugging Face token and ensure the Space 'Tamiloneto8/Test1' is running.")
30
  return demo
31
 
32
  # Define wrapper functions to call the API endpoints
33
  def start_processing(audio_file, target_language):
34
  if not audio_file or not target_language:
35
+ gr.Warning("Please provide both an audio file and select a target language.")
36
  return (
37
+ "⚠️ Waiting for input...", None, "", "", None, "",
 
38
  gr.update(visible=False), gr.update(visible=False)
39
  )
40
  try:
 
45
  api_name="/process_audio_pipeline_step1"
46
  )
47
  logger.info("Received result from step 1: %s", result)
48
+ gr.Info("Processing started! First chunk is ready for editing.")
 
 
49
  return (
50
  f"βœ… {result[0]}", result[2], result[3], result[4], result[5], result[6],
51
  gr.update(visible=True), gr.update(visible=True)
52
  )
53
  except Exception as e:
54
  logger.error("Error in start_processing: %s", e, exc_info=True)
55
+ gr.Error(f"Error starting process: {e}")
56
  return (
57
+ f"❌ Error: {str(e)}", None, "", "", None, "",
 
58
  gr.update(visible=False), gr.update(visible=False)
59
  )
60
 
 
62
  api_to_call = "/lambda" if direction == "prev" else "/lambda_1"
63
  try:
64
  logger.info("Calling %s to navigate.", api_to_call)
65
+ result = client.predict(t=transcription, tr=translation, api_name=api_to_call)
 
 
 
 
66
  logger.info("Received result from navigation: %s", result)
67
  return result[1], result[2], result[3], result[4], result[5]
68
  except Exception as e:
69
  logger.error("Error navigating chunks: %s", e, exc_info=True)
70
+ gr.Warning(f"Navigation error: {e}")
71
+ return gr.update(), gr.update(), gr.update(), gr.update(), gr.update()
72
 
73
  def generate_dubbed_chunk(transcription, translation):
74
  if not transcription and not translation:
75
+ gr.Warning("Cannot generate audio from empty text fields.")
76
  return None
77
  try:
78
  logger.info("Calling /generate_dubbed_chunk.")
79
+ gr.Info("Generating dubbed audio for the current chunk...")
80
  dubbed_path = client.predict(
81
  transcription=transcription,
82
  translation=translation,
83
  api_name="/generate_dubbed_chunk"
84
  )
85
  logger.info("Received dubbed chunk: %s", dubbed_path)
86
+ gr.Info("Dubbed chunk generated successfully!")
87
  return dubbed_path
88
  except Exception as e:
89
  logger.error("Error generating dubbed chunk: %s", e, exc_info=True)
90
+ gr.Error(f"Error generating audio: {e}")
91
  return None
92
 
93
  def finalize_current_chunk():
 
95
  logger.info("Calling /finalize_current_chunk.")
96
  progress = client.predict(api_name="/finalize_current_chunk")
97
  logger.info("Received finalization progress: %s", progress)
98
+ gr.Info("Chunk finalized!")
99
  return f"βœ… {progress}"
100
  except Exception as e:
101
  logger.error("Error finalizing chunk: %s", e, exc_info=True)
102
+ gr.Error(f"Error finalizing chunk: {e}")
103
  return f"❌ Error finalizing: {str(e)}"
104
 
105
  def merge_all_chunks():
106
  try:
107
  logger.info("Calling /merge_audio_files.")
108
+ gr.Info("Merging all finalized chunks. This may take a moment...")
109
  final_status, final_audio = client.predict(api_name="/merge_audio_files")
110
  logger.info("Received final merged audio.")
111
+ gr.Info("Merge complete! Final audio is ready.")
112
  return f"πŸŽ‰ {final_status}", final_audio
113
  except Exception as e:
114
  logger.error("Error merging audio files: %s", e, exc_info=True)
115
+ gr.Error(f"Merge error: {e}")
116
  return f"❌ Merge error: {str(e)}", None
117
 
118
+ # Create custom theme
119
+ custom_theme = gr_themes.Soft(primary_hue="orange", secondary_hue="red", neutral_hue="slate")
 
 
 
 
120
 
121
+ # Define the Gradio interface
122
+ with gr.Blocks(theme=custom_theme, title="DubIndic - AI Audio Dubbing") as demo:
123
+ gr.HTML('<div style="text-align: center; font-size: 2.5rem; font-weight: 800; margin-bottom: 1rem;">🎬 DubIndic - AI Audio Dubbing Pipeline</div>')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  gr.HTML('<div style="text-align: center; margin-bottom: 2rem; font-size: 1.1rem; color: #666;">Transform your audio into another Indian language with full editing control</div>')
125
+
 
126
  with gr.Row():
127
  with gr.Column(scale=2):
128
+ with gr.Box():
129
+ gr.Markdown("### <span style='color: #f97316;'>πŸ“€ Step 1: Upload & Configure</span>")
130
+ with gr.Row():
131
+ audio_input = gr.Audio(sources=["upload"], type="filepath", label="🎡 Upload Audio File")
 
 
 
 
 
 
 
 
132
  lang_dropdown = gr.Dropdown(
133
  choices=["Assamese", "Bengali", "Gujarati", "Hindi", "Kannada", "Malayalam", "Marathi", "Odia", "Punjabi", "Tamil", "Telugu"],
134
+ label="🌐 Target Language"
 
 
135
  )
136
+ process_btn = gr.Button("🎯 Start Processing", variant="primary")
137
+ step1_output = gr.Textbox(label="πŸ“Š Processing Status", interactive=False)
138
+
139
+ with gr.Column(visible=False) as edit_section:
140
+ with gr.Box():
141
+ gr.Markdown("### <span style='color: #f97316;'>✏️ Step 2: Edit, Generate & Finalize</span>")
142
+ with gr.Row():
143
+ prev_btn = gr.Button("◀️ Previous")
144
+ next_btn = gr.Button("Next ▢️")
145
+ with gr.Row():
146
+ original_audio = gr.Audio(label="🎡 Original Chunk Audio", type="filepath", interactive=False)
147
+ dubbed_audio = gr.Audio(label="🎀 Dubbed Chunk Audio", type="filepath", interactive=False)
148
+ transcription_text = gr.Textbox(label="πŸ“ Transcription (edit if needed)", lines=3, interactive=True)
149
+ translation_text = gr.Textbox(label="πŸ”„ Translation (edit if needed)", lines=3, interactive=True)
150
+ with gr.Row():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  generate_btn = gr.Button("πŸ”Š Generate Dubbed Chunk", variant="secondary")
 
152
  finalize_btn = gr.Button("βœ”οΈ Finalize Chunk", variant="secondary")
153
+ progress_text = gr.Textbox(label="πŸ“ˆ Progress", interactive=False)
154
+
155
+ with gr.Column(visible=False) as merge_section:
156
+ with gr.Box():
157
+ gr.Markdown("### <span style='color: #f97316;'>🏁 Step 3: Merge Final Audio</span>")
158
+ merge_btn = gr.Button("πŸš€ Merge All Finalized Chunks", variant="primary")
159
+ with gr.Row():
160
+ final_output = gr.Textbox(label="πŸŽ‰ Final Results", interactive=False)
161
+ output_audio = gr.Audio(label="πŸ”Š Final Dubbed Audio", type="filepath", interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
  # Connect functions to UI components
164
  process_btn.click(
 
166
  inputs=[audio_input, lang_dropdown],
167
  outputs=[step1_output, original_audio, transcription_text, translation_text, dubbed_audio, progress_text, edit_section, merge_section]
168
  )
 
169
  prev_btn.click(
170
  fn=lambda t, tr: navigate_chunk(t, tr, "prev"),
171
  inputs=[transcription_text, translation_text],
172
  outputs=[original_audio, transcription_text, translation_text, dubbed_audio, progress_text]
173
  )
 
174
  next_btn.click(
175
  fn=lambda t, tr: navigate_chunk(t, tr, "next"),
176
  inputs=[transcription_text, translation_text],
177
  outputs=[original_audio, transcription_text, translation_text, dubbed_audio, progress_text]
178
  )
 
179
  generate_btn.click(
180
  fn=generate_dubbed_chunk,
181
  inputs=[transcription_text, translation_text],
182
  outputs=[dubbed_audio]
183
  )
 
184
  finalize_btn.click(
185
  fn=finalize_current_chunk,
186
  inputs=[],
187
  outputs=[progress_text]
188
  )
 
189
  merge_btn.click(
190
  fn=merge_all_chunks,
191
  inputs=[],
192
  outputs=[final_output, output_audio]
193
  )
 
194
  return demo
195
 
196
  if __name__ == "__main__":
197
+ dubindic_interface = create_dubindic_interface()
198
+ if dubindic_interface:
199
+ dubindic_interface.launch(
200
+ show_error=True,
201
+ share=False,
202
+ server_name="0.0.0.0",
203
+ server_port=7860
 
 
204
  )
205
  else:
206
  logger.error("Failed to create the Gradio interface.")