euiia commited on
Commit
c5484dc
ยท
verified ยท
1 Parent(s): b954723

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -138
app.py CHANGED
@@ -2,7 +2,7 @@
2
  #
3
  # Copyright (C) August 4, 2025 Carlos Rodrigues dos Santos
4
  #
5
- # Version: 2.0.0
6
  #
7
  # Contact:
8
  # Carlos Rodrigues dos Santos
@@ -82,12 +82,12 @@ try:
82
  i18n = json.load(f)
83
  except Exception as e:
84
  logger.error(f"Error loading i18n.json: {e}")
85
- i18n = {"๐Ÿ‡ง๐Ÿ‡ท": {}, "๐Ÿ‡บ๐Ÿ‡ธ": {}, "๐Ÿ‡จ๐Ÿ‡ณ": {}}
86
 
87
  # Fallback for missing languages
88
- if '๐Ÿ‡ง๐Ÿ‡ท' not in i18n: i18n['๐Ÿ‡ง๐Ÿ‡ท'] = i18n.get('๐Ÿ‡บ๐Ÿ‡ธ', {})
89
- if '๐Ÿ‡บ๐Ÿ‡ธ' not in i18n: i18n['๐Ÿ‡บ๐Ÿ‡ธ'] = {}
90
- if '๐Ÿ‡จ๐Ÿ‡ณ' not in i18n: i18n['๐Ÿ‡จ๐Ÿ‡ณ'] = i18n.get('๐Ÿ‡บ๐Ÿ‡ธ', {})
91
 
92
  # Initialize the main orchestrator from the configuration file
93
  try:
@@ -105,10 +105,6 @@ except Exception as e:
105
  # the UI state after each operation.
106
 
107
  def run_pre_production_wrapper(prompt, num_keyframes, ref_files, resolution_str, duration_per_fragment, progress=gr.Progress()):
108
- """
109
- Wrapper for Pre-Production (Steps 1 & 2): Generates storyboard and keyframes.
110
- This corresponds to the "Art Director Mode".
111
- """
112
  if not ref_files:
113
  raise gr.Error("Please provide at least one reference image.")
114
 
@@ -119,10 +115,9 @@ def run_pre_production_wrapper(prompt, num_keyframes, ref_files, resolution_str,
119
 
120
  resolution = int(resolution_str.split('x')[0])
121
 
122
- # Callback factory to create progress updates for keyframe generation
123
  def cb_factory(scene_index, total_scenes):
124
  start_time = time.time()
125
- total_steps = 12 # Standard steps for Flux model
126
  def callback(pipe_self, step, timestep, callback_kwargs):
127
  elapsed = time.time() - start_time
128
  current_step = step + 1
@@ -138,14 +133,9 @@ def run_pre_production_wrapper(prompt, num_keyframes, ref_files, resolution_str,
138
 
139
  final_keyframes = aduc.task_generate_keyframes(storyboard, initial_ref_path, prompt, resolution, cb_factory)
140
 
141
- # Make the next step (Production) visible
142
  return gr.update(value=storyboard), gr.update(value=final_keyframes), gr.update(visible=True, open=True)
143
 
144
  def run_pre_production_photo_wrapper(prompt, num_keyframes, ref_files, progress=gr.Progress()):
145
- """
146
- Wrapper for Pre-Production (Steps 1 & 2) in "Photographer Mode".
147
- Generates a storyboard and selects the best matching keyframes from a user-provided pool.
148
- """
149
  if not ref_files or len(ref_files) < 2:
150
  raise gr.Error("Photographer Mode requires at least 2 images: one base and one for the scene pool.")
151
 
@@ -165,19 +155,15 @@ def run_original_production_wrapper(keyframes, prompt, duration,
165
  guidance_scale, stg_scale, inference_steps,
166
  video_resolution,
167
  progress=gr.Progress()):
168
- """
169
- Wrapper for Step 3: Production. Generates the original master video using LTX.
170
- Yields UI updates to show progress and final output.
171
- """
172
  yield {
173
  original_video_output: gr.update(value=None, visible=True, label="๐ŸŽฌ Producing your original master video... Please wait."),
174
  final_video_output: gr.update(value=None, visible=True, label="๐ŸŽฌ Production in progress..."),
175
- step4_accordion: gr.update(visible=False) # Hide post-production until this is done
176
  }
177
 
178
  resolution = int(video_resolution.split('x')[0])
179
 
180
- # The orchestrator now returns the paths to the generated artifacts
181
  result = aduc.task_produce_original_movie(
182
  keyframes, prompt, duration,
183
  int(trim_percent), handler_strength, destination_convergence_strength,
@@ -191,17 +177,14 @@ def run_original_production_wrapper(keyframes, prompt, duration,
191
  yield {
192
  original_video_output: gr.update(value=original_video, label="โœ… Original Master Video"),
193
  final_video_output: gr.update(value=original_video, label="Final Film (Result of the Last Step)"),
194
- step4_accordion: gr.update(visible=True, open=True), # Show post-production tools
195
- # Update state for the next steps
196
  original_latents_paths_state: original_latents,
197
  original_video_path_state: original_video,
198
  current_source_video_state: original_video,
199
  }
200
 
201
  def run_upscaler_wrapper(latent_paths, chunk_size, progress=gr.Progress()):
202
- """
203
- Wrapper for Post-Production Step 4A: Latent Upscaler.
204
- """
205
  if not latent_paths:
206
  raise gr.Error("Cannot run Upscaler. No original latents found. Please complete Step 3 first.")
207
 
@@ -210,22 +193,19 @@ def run_upscaler_wrapper(latent_paths, chunk_size, progress=gr.Progress()):
210
  final_video_output: gr.update(label="Post-Production in progress: Latent Upscaling...")
211
  }
212
 
213
- upscaled_video_path = aduc.task_run_latent_upscaler(
214
- latent_paths, int(chunk_size), progress=progress
215
- )
216
 
217
  yield {
218
- upscaler_video_output: gr.update(value=upscaled_video_path, label="โœ… Latent Upscale Complete"),
219
- final_video_output: gr.update(value=upscaled_video_path),
220
- # Update states for subsequent steps
221
- upscaled_video_path_state: upscaled_video_path,
222
- current_source_video_state: upscaled_video_path,
223
  }
224
 
225
- def run_hd_wrapper(source_video, model_version, steps, progress=gr.Progress()):
226
- """
227
- Wrapper for Post-Production Step 4B: HD Mastering.
228
- """
229
  if not source_video:
230
  raise gr.Error("Cannot run HD Mastering. No source video found. Please complete a previous step first.")
231
 
@@ -234,21 +214,19 @@ def run_hd_wrapper(source_video, model_version, steps, progress=gr.Progress()):
234
  final_video_output: gr.update(label="Post-Production in progress: HD Mastering...")
235
  }
236
 
237
- hd_video_path = aduc.task_run_hd_mastering(
238
- source_video, model_version, int(steps), progress=progress
239
- )
240
 
241
  yield {
242
- hd_video_output: gr.update(value=hd_video_path, label="โœ… HD Mastering Complete"),
243
- final_video_output: gr.update(value=hd_video_path),
244
- hd_video_path_state: hd_video_path,
245
- current_source_video_state: hd_video_path,
246
  }
247
 
248
  def run_audio_wrapper(source_video, audio_prompt, global_prompt, progress=gr.Progress()):
249
- """
250
- Wrapper for Post-Production Step 4C: Audio Generation.
251
- """
252
  if not source_video:
253
  raise gr.Error("Cannot run Audio Generation. No source video found. Please complete a previous step first.")
254
 
@@ -257,42 +235,32 @@ def run_audio_wrapper(source_video, audio_prompt, global_prompt, progress=gr.Pro
257
  final_video_output: gr.update(label="Post-Production in progress: Audio Generation...")
258
  }
259
 
260
- # Use the specific audio prompt if provided, otherwise fall back to the global prompt
261
  final_audio_prompt = audio_prompt if audio_prompt and audio_prompt.strip() else global_prompt
262
 
263
- video_with_audio_path = aduc.task_run_audio_generation(
264
- source_video, final_audio_prompt, progress=progress
265
- )
266
 
267
  yield {
268
- audio_video_output: gr.update(value=video_with_audio_path, label="โœ… Audio Generation Complete"),
269
- final_video_output: gr.update(value=video_with_audio_path),
270
  }
271
 
272
  def get_log_content():
273
- """
274
- Reads and returns the content of the log file for display in the UI.
275
- """
276
  try:
277
  with open(LOG_FILE_PATH, "r", encoding="utf-8") as f:
278
  return f.read()
279
  except FileNotFoundError:
280
  return "Log file not yet created. Start a generation."
281
 
282
- def update_ui_language(lang_code):
283
- """
284
- Updates all text components in the UI to the selected language.
285
- It fetches the translation map from the `i18n` dictionary.
286
- """
287
  lang_map = i18n.get(lang_code, i18n.get('en', {}))
288
- # This dictionary maps each UI component variable to its new value from the language map.
289
  return {
290
- # General
291
  title_md: gr.update(value=f"# {lang_map.get('app_title')}"),
292
  subtitle_md: gr.update(value=lang_map.get('app_subtitle')),
293
  lang_selector: gr.update(label=lang_map.get('lang_selector_label')),
294
-
295
- # Step 1: Pre-Production
296
  step1_accordion: gr.update(label=lang_map.get('step1_accordion')),
297
  prompt_input: gr.update(label=lang_map.get('prompt_label')),
298
  ref_image_input: gr.update(label=lang_map.get('ref_images_label')),
@@ -303,11 +271,10 @@ def update_ui_language(lang_code):
303
  step1_mode_b_info_md: gr.update(value=f"*{lang_map.get('step1_mode_b_info')}*"),
304
  storyboard_output: gr.update(label=lang_map.get('storyboard_output_label')),
305
  keyframe_gallery: gr.update(label=lang_map.get('keyframes_gallery_label')),
306
-
307
- # Step 3: Production
308
  step3_accordion: gr.update(label=lang_map.get('step3_accordion')),
309
  step3_description_md: gr.update(value=lang_map.get('step3_description')),
310
  produce_original_button: gr.update(value=lang_map.get('produce_original_button')),
 
311
  causality_accordion: gr.update(label=lang_map.get('causality_controls_title')),
312
  trim_percent_slider: gr.update(label=lang_map.get('trim_percent_label'), info=lang_map.get('trim_percent_info')),
313
  forca_guia_slider: gr.update(label=lang_map.get('forca_guia_label'), info=lang_map.get('forca_guia_info')),
@@ -316,8 +283,6 @@ def update_ui_language(lang_code):
316
  guidance_scale_slider: gr.update(label=lang_map.get('guidance_scale_label'), info=lang_map.get('guidance_scale_info')),
317
  stg_scale_slider: gr.update(label=lang_map.get('stg_scale_label'), info=lang_map.get('stg_scale_info')),
318
  inference_steps_slider: gr.update(label=lang_map.get('steps_label'), info=lang_map.get('steps_info')),
319
-
320
- # Step 4: Post-Production
321
  step4_accordion: gr.update(label=lang_map.get('step4_accordion')),
322
  step4_description_md: gr.update(value=lang_map.get('step4_description')),
323
  sub_step_a_accordion: gr.update(label=lang_map.get('sub_step_a_upscaler')),
@@ -336,8 +301,6 @@ def update_ui_language(lang_code):
336
  audio_options_accordion: gr.update(label=lang_map.get('audio_options')),
337
  audio_prompt_input: gr.update(label=lang_map.get('audio_prompt_label'), info=lang_map.get('audio_prompt_info')),
338
  run_audio_button: gr.update(value=lang_map.get('run_audio_button')),
339
-
340
- # Final Outputs & Logs
341
  final_video_output: gr.update(label=lang_map.get('final_video_label')),
342
  log_accordion: gr.update(label=lang_map.get('log_accordion_label')),
343
  log_display: gr.update(label=lang_map.get('log_display_label')),
@@ -346,25 +309,23 @@ def update_ui_language(lang_code):
346
 
347
  # --- 3. GRADIO UI DEFINITION ---
348
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
349
- # Initialize UI with default language (Portuguese)
350
  default_lang = i18n.get('pt', {})
351
-
352
- # State components to manage the pipeline artifacts
353
  original_latents_paths_state = gr.State(value=None)
354
  original_video_path_state = gr.State(value=None)
355
  upscaled_video_path_state = gr.State(value=None)
356
  hd_video_path_state = gr.State(value=None)
357
- current_source_video_state = gr.State(value=None) # Tracks the latest video for post-production steps
358
 
359
- # --- UI Header ---
360
  title_md = gr.Markdown(f"# {default_lang.get('app_title')}")
361
  subtitle_md = gr.Markdown(default_lang.get('app_subtitle'))
362
-
363
  with gr.Row():
364
- lang_selector = gr.Radio(["๐Ÿ‡ง๐Ÿ‡ท", "๐Ÿ‡บ๐Ÿ‡ธ", "๐Ÿ‡จ๐Ÿ‡ณ"], value="pt", label=default_lang.get('lang_selector_label'))
365
  resolution_selector = gr.Radio(["480x480", "720x720", "960x960"], value="480x480", label="Base Resolution")
366
 
367
- # --- Step 1 & 2: Pre-Production ---
368
  with gr.Accordion(default_lang.get('step1_accordion'), open=True) as step1_accordion:
369
  prompt_input = gr.Textbox(label=default_lang.get('prompt_label'), value="A majestic lion walks across the savanna, sits down, and then roars at the setting sun.")
370
  ref_image_input = gr.File(label=default_lang.get('ref_images_label'), file_count="multiple", file_types=["image"])
@@ -378,112 +339,75 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
378
  storyboard_output = gr.JSON(label=default_lang.get('storyboard_output_label'))
379
  keyframe_gallery = gr.Gallery(label=default_lang.get('keyframes_gallery_label'), visible=True, object_fit="contain", height="auto", type="filepath")
380
 
381
- # --- Step 3: Production ---
382
  with gr.Accordion(default_lang.get('step3_accordion'), open=False, visible=False) as step3_accordion:
383
  step3_description_md = gr.Markdown(default_lang.get('step3_description'))
384
-
385
  with gr.Accordion(default_lang.get('ltx_advanced_options'), open=False) as ltx_advanced_options_accordion:
386
  with gr.Accordion(default_lang.get('causality_controls_title'), open=True) as causality_accordion:
387
  trim_percent_slider = gr.Slider(minimum=10, maximum=90, value=50, step=5, label=default_lang.get('trim_percent_label'), info=default_lang.get('trim_percent_info'))
388
  with gr.Row():
389
  forca_guia_slider = gr.Slider(label=default_lang.get('forca_guia_label'), minimum=0.0, maximum=1.0, value=0.5, step=0.05, info=default_lang.get('forca_guia_info'))
390
  convergencia_destino_slider = gr.Slider(label=default_lang.get('convergencia_final_label'), minimum=0.0, maximum=1.0, value=0.75, step=0.05, info=default_lang.get('convergencia_final_info'))
391
-
392
  with gr.Accordion(default_lang.get('ltx_pipeline_options'), open=True) as ltx_pipeline_accordion:
393
  with gr.Row():
394
  guidance_scale_slider = gr.Slider(minimum=1.0, maximum=10.0, value=2.0, step=0.1, label=default_lang.get('guidance_scale_label'), info=default_lang.get('guidance_scale_info'))
395
  stg_scale_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.025, step=0.005, label=default_lang.get('stg_scale_label'), info=default_lang.get('stg_scale_info'))
396
  inference_steps_slider = gr.Slider(minimum=10, maximum=50, value=20, step=1, label=default_lang.get('steps_label'), info=default_lang.get('steps_info'))
397
-
398
  produce_original_button = gr.Button(default_lang.get('produce_original_button'), variant="primary")
399
- original_video_output = gr.Video(label="Original Master Video", visible=False)
400
 
401
- # --- Step 4: Post-Production ---
402
  with gr.Accordion(default_lang.get('step4_accordion'), open=False, visible=False) as step4_accordion:
403
  step4_description_md = gr.Markdown(default_lang.get('step4_description'))
404
-
405
- # Sub-Step 4A: Latent Upscaler
406
  with gr.Accordion(default_lang.get('sub_step_a_upscaler'), open=True) as sub_step_a_accordion:
407
  upscaler_description_md = gr.Markdown(default_lang.get('upscaler_description'))
408
  with gr.Accordion(default_lang.get('upscaler_options'), open=False) as upscaler_options_accordion:
409
- upscaler_chunk_size_slider = gr.Slider(minimum=1, maximum=10, value=4, step=1, label=default_lang.get('upscaler_chunk_size_label'), info=default_lang.get('upscaler_chunk_size_info'))
410
  run_upscaler_button = gr.Button(default_lang.get('run_upscaler_button'), variant="secondary")
411
- upscaler_video_output = gr.Video(label="Upscaled Video", visible=False)
412
-
413
- # Sub-Step 4B: HD Mastering
414
  with gr.Accordion(default_lang.get('sub_step_b_hd'), open=True) as sub_step_b_accordion:
415
  hd_description_md = gr.Markdown(default_lang.get('hd_description'))
416
  with gr.Accordion(default_lang.get('hd_options'), open=False) as hd_options_accordion:
417
- hd_model_radio = gr.Radio(["3B", "7B"], value="3B", label=default_lang.get('hd_model_label'))
418
- hd_steps_slider = gr.Slider(minimum=20, maximum=150, value=50, step=5, label=default_lang.get('hd_steps_label'), info=default_lang.get('hd_steps_info'))
419
  run_hd_button = gr.Button(default_lang.get('run_hd_button'), variant="secondary")
420
- hd_video_output = gr.Video(label="HD Mastered Video", visible=False)
421
-
422
- # Sub-Step 4C: Audio Generation
423
  with gr.Accordion(default_lang.get('sub_step_c_audio'), open=True) as sub_step_c_accordion:
424
  audio_description_md = gr.Markdown(default_lang.get('audio_description'))
425
  with gr.Accordion(default_lang.get('audio_options'), open=False) as audio_options_accordion:
426
  audio_prompt_input = gr.Textbox(label=default_lang.get('audio_prompt_label'), info=default_lang.get('audio_prompt_info'), lines=3)
427
  run_audio_button = gr.Button(default_lang.get('run_audio_button'), variant="secondary")
428
- audio_video_output = gr.Video(label="Video with Audio", visible=False)
429
-
430
- # --- Final Output & Logs ---
431
- final_video_output = gr.Video(label=default_lang.get('final_video_label'), visible=False)
432
 
 
 
433
  with gr.Accordion(default_lang.get('log_accordion_label'), open=False) as log_accordion:
434
  log_display = gr.Textbox(label=default_lang.get('log_display_label'), lines=20, interactive=False, autoscroll=True)
435
  update_log_button = gr.Button(default_lang.get('update_log_button'))
436
 
437
  # --- 4. UI EVENT CONNECTIONS ---
438
- # Collect all UI components that need language updates
439
- all_ui_components = list(update_ui_language('pt').keys())
440
  lang_selector.change(fn=update_ui_language, inputs=lang_selector, outputs=all_ui_components)
441
 
442
- # Pre-Production Button Clicks
443
- storyboard_and_keyframes_button.click(
444
- fn=run_pre_production_wrapper,
445
- inputs=[prompt_input, num_keyframes_slider, ref_image_input, resolution_selector, duration_per_fragment_slider],
446
- outputs=[storyboard_output, keyframe_gallery, step3_accordion]
447
- )
448
-
449
- storyboard_from_photos_button.click(
450
- fn=run_pre_production_photo_wrapper,
451
- inputs=[prompt_input, num_keyframes_slider, ref_image_input],
452
- outputs=[storyboard_output, keyframe_gallery, step3_accordion]
453
- )
454
 
455
- # Production Button Click
456
  produce_original_button.click(
457
  fn=run_original_production_wrapper,
458
- inputs=[
459
- keyframe_gallery, prompt_input, duration_per_fragment_slider,
460
- trim_percent_slider, forca_guia_slider, convergencia_destino_slider,
461
- guidance_scale_slider, stg_scale_slider, inference_steps_slider,
462
- resolution_selector
463
- ],
464
- outputs=[
465
- original_video_output, final_video_output, step4_accordion,
466
- original_latents_paths_state, original_video_path_state, current_source_video_state
467
- ]
468
  )
469
 
470
- # Post-Production Button Clicks
471
  run_upscaler_button.click(
472
  fn=run_upscaler_wrapper,
473
  inputs=[original_latents_paths_state, upscaler_chunk_size_slider],
474
- outputs=[
475
- upscaler_video_output, final_video_output,
476
- upscaled_video_path_state, current_source_video_state
477
- ]
478
  )
479
 
480
  run_hd_button.click(
481
  fn=run_hd_wrapper,
482
- inputs=[current_source_video_state, hd_model_radio, hd_steps_slider],
483
- outputs=[
484
- hd_video_output, final_video_output,
485
- hd_video_path_state, current_source_video_state
486
- ]
487
  )
488
 
489
  run_audio_button.click(
@@ -492,7 +416,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
492
  outputs=[audio_video_output, final_video_output]
493
  )
494
 
495
- # Log Button Click
496
  update_log_button.click(fn=get_log_content, inputs=[], outputs=[log_display])
497
 
498
  # --- 5. APPLICATION LAUNCH ---
 
2
  #
3
  # Copyright (C) August 4, 2025 Carlos Rodrigues dos Santos
4
  #
5
+ # Version: 2.0.1
6
  #
7
  # Contact:
8
  # Carlos Rodrigues dos Santos
 
82
  i18n = json.load(f)
83
  except Exception as e:
84
  logger.error(f"Error loading i18n.json: {e}")
85
+ i18n = {"pt": {}, "en": {}, "zh": {}}
86
 
87
  # Fallback for missing languages
88
+ if 'pt' not in i18n: i18n['pt'] = i18n.get('en', {})
89
+ if 'en' not in i18n: i18n['en'] = {}
90
+ if 'zh' not in i18n: i18n['zh'] = i18n.get('en', {})
91
 
92
  # Initialize the main orchestrator from the configuration file
93
  try:
 
105
  # the UI state after each operation.
106
 
107
  def run_pre_production_wrapper(prompt, num_keyframes, ref_files, resolution_str, duration_per_fragment, progress=gr.Progress()):
 
 
 
 
108
  if not ref_files:
109
  raise gr.Error("Please provide at least one reference image.")
110
 
 
115
 
116
  resolution = int(resolution_str.split('x')[0])
117
 
 
118
  def cb_factory(scene_index, total_scenes):
119
  start_time = time.time()
120
+ total_steps = 12
121
  def callback(pipe_self, step, timestep, callback_kwargs):
122
  elapsed = time.time() - start_time
123
  current_step = step + 1
 
133
 
134
  final_keyframes = aduc.task_generate_keyframes(storyboard, initial_ref_path, prompt, resolution, cb_factory)
135
 
 
136
  return gr.update(value=storyboard), gr.update(value=final_keyframes), gr.update(visible=True, open=True)
137
 
138
  def run_pre_production_photo_wrapper(prompt, num_keyframes, ref_files, progress=gr.Progress()):
 
 
 
 
139
  if not ref_files or len(ref_files) < 2:
140
  raise gr.Error("Photographer Mode requires at least 2 images: one base and one for the scene pool.")
141
 
 
155
  guidance_scale, stg_scale, inference_steps,
156
  video_resolution,
157
  progress=gr.Progress()):
158
+ """Wrapper for Step 3: Production. Correctly handles the return dictionary."""
 
 
 
159
  yield {
160
  original_video_output: gr.update(value=None, visible=True, label="๐ŸŽฌ Producing your original master video... Please wait."),
161
  final_video_output: gr.update(value=None, visible=True, label="๐ŸŽฌ Production in progress..."),
162
+ step4_accordion: gr.update(visible=False)
163
  }
164
 
165
  resolution = int(video_resolution.split('x')[0])
166
 
 
167
  result = aduc.task_produce_original_movie(
168
  keyframes, prompt, duration,
169
  int(trim_percent), handler_strength, destination_convergence_strength,
 
177
  yield {
178
  original_video_output: gr.update(value=original_video, label="โœ… Original Master Video"),
179
  final_video_output: gr.update(value=original_video, label="Final Film (Result of the Last Step)"),
180
+ step4_accordion: gr.update(visible=True, open=True),
 
181
  original_latents_paths_state: original_latents,
182
  original_video_path_state: original_video,
183
  current_source_video_state: original_video,
184
  }
185
 
186
  def run_upscaler_wrapper(latent_paths, chunk_size, progress=gr.Progress()):
187
+ """Wrapper for Step 4A: Latent Upscaler. Correctly handles the generator."""
 
 
188
  if not latent_paths:
189
  raise gr.Error("Cannot run Upscaler. No original latents found. Please complete Step 3 first.")
190
 
 
193
  final_video_output: gr.update(label="Post-Production in progress: Latent Upscaling...")
194
  }
195
 
196
+ final_path = None
197
+ for path in aduc.task_run_latent_upscaler(latent_paths, int(chunk_size), progress=progress):
198
+ final_path = path['final_path']
199
 
200
  yield {
201
+ upscaler_video_output: gr.update(value=final_path, label="โœ… Latent Upscale Complete"),
202
+ final_video_output: gr.update(value=final_path),
203
+ upscaled_video_path_state: final_path,
204
+ current_source_video_state: final_path,
 
205
  }
206
 
207
+ def run_hd_wrapper(source_video, model_version, steps, global_prompt, progress=gr.Progress()):
208
+ """Wrapper for Step 4B: HD Mastering. Correctly handles the generator."""
 
 
209
  if not source_video:
210
  raise gr.Error("Cannot run HD Mastering. No source video found. Please complete a previous step first.")
211
 
 
214
  final_video_output: gr.update(label="Post-Production in progress: HD Mastering...")
215
  }
216
 
217
+ final_path = None
218
+ for path in aduc.task_run_hd_mastering(source_video, model_version, int(steps), global_prompt, progress=progress):
219
+ final_path = path['final_path']
220
 
221
  yield {
222
+ hd_video_output: gr.update(value=final_path, label="โœ… HD Mastering Complete"),
223
+ final_video_output: gr.update(value=final_path),
224
+ hd_video_path_state: final_path,
225
+ current_source_video_state: final_path,
226
  }
227
 
228
  def run_audio_wrapper(source_video, audio_prompt, global_prompt, progress=gr.Progress()):
229
+ """Wrapper for Step 4C: Audio Generation. Correctly handles the generator."""
 
 
230
  if not source_video:
231
  raise gr.Error("Cannot run Audio Generation. No source video found. Please complete a previous step first.")
232
 
 
235
  final_video_output: gr.update(label="Post-Production in progress: Audio Generation...")
236
  }
237
 
 
238
  final_audio_prompt = audio_prompt if audio_prompt and audio_prompt.strip() else global_prompt
239
 
240
+ final_path = None
241
+ for path in aduc.task_run_audio_generation(source_video, final_audio_prompt, progress=progress):
242
+ final_path = path['final_path']
243
 
244
  yield {
245
+ audio_video_output: gr.update(value=final_path, label="โœ… Audio Generation Complete"),
246
+ final_video_output: gr.update(value=final_path),
247
  }
248
 
249
  def get_log_content():
 
 
 
250
  try:
251
  with open(LOG_FILE_PATH, "r", encoding="utf-8") as f:
252
  return f.read()
253
  except FileNotFoundError:
254
  return "Log file not yet created. Start a generation."
255
 
256
+ def update_ui_language(lang_emoji):
257
+ lang_code_map = {"๐Ÿ‡ง๐Ÿ‡ท": "pt", "๐Ÿ‡บ๐Ÿ‡ธ": "en", "๐Ÿ‡จ๐Ÿ‡ณ": "zh"}
258
+ lang_code = lang_code_map.get(lang_emoji, "en")
 
 
259
  lang_map = i18n.get(lang_code, i18n.get('en', {}))
 
260
  return {
 
261
  title_md: gr.update(value=f"# {lang_map.get('app_title')}"),
262
  subtitle_md: gr.update(value=lang_map.get('app_subtitle')),
263
  lang_selector: gr.update(label=lang_map.get('lang_selector_label')),
 
 
264
  step1_accordion: gr.update(label=lang_map.get('step1_accordion')),
265
  prompt_input: gr.update(label=lang_map.get('prompt_label')),
266
  ref_image_input: gr.update(label=lang_map.get('ref_images_label')),
 
271
  step1_mode_b_info_md: gr.update(value=f"*{lang_map.get('step1_mode_b_info')}*"),
272
  storyboard_output: gr.update(label=lang_map.get('storyboard_output_label')),
273
  keyframe_gallery: gr.update(label=lang_map.get('keyframes_gallery_label')),
 
 
274
  step3_accordion: gr.update(label=lang_map.get('step3_accordion')),
275
  step3_description_md: gr.update(value=lang_map.get('step3_description')),
276
  produce_original_button: gr.update(value=lang_map.get('produce_original_button')),
277
+ ltx_advanced_options_accordion: gr.update(label=lang_map.get('ltx_advanced_options')),
278
  causality_accordion: gr.update(label=lang_map.get('causality_controls_title')),
279
  trim_percent_slider: gr.update(label=lang_map.get('trim_percent_label'), info=lang_map.get('trim_percent_info')),
280
  forca_guia_slider: gr.update(label=lang_map.get('forca_guia_label'), info=lang_map.get('forca_guia_info')),
 
283
  guidance_scale_slider: gr.update(label=lang_map.get('guidance_scale_label'), info=lang_map.get('guidance_scale_info')),
284
  stg_scale_slider: gr.update(label=lang_map.get('stg_scale_label'), info=lang_map.get('stg_scale_info')),
285
  inference_steps_slider: gr.update(label=lang_map.get('steps_label'), info=lang_map.get('steps_info')),
 
 
286
  step4_accordion: gr.update(label=lang_map.get('step4_accordion')),
287
  step4_description_md: gr.update(value=lang_map.get('step4_description')),
288
  sub_step_a_accordion: gr.update(label=lang_map.get('sub_step_a_upscaler')),
 
301
  audio_options_accordion: gr.update(label=lang_map.get('audio_options')),
302
  audio_prompt_input: gr.update(label=lang_map.get('audio_prompt_label'), info=lang_map.get('audio_prompt_info')),
303
  run_audio_button: gr.update(value=lang_map.get('run_audio_button')),
 
 
304
  final_video_output: gr.update(label=lang_map.get('final_video_label')),
305
  log_accordion: gr.update(label=lang_map.get('log_accordion_label')),
306
  log_display: gr.update(label=lang_map.get('log_display_label')),
 
309
 
310
  # --- 3. GRADIO UI DEFINITION ---
311
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
 
312
  default_lang = i18n.get('pt', {})
313
+
314
+ # State components
315
  original_latents_paths_state = gr.State(value=None)
316
  original_video_path_state = gr.State(value=None)
317
  upscaled_video_path_state = gr.State(value=None)
318
  hd_video_path_state = gr.State(value=None)
319
+ current_source_video_state = gr.State(value=None)
320
 
321
+ # UI Header
322
  title_md = gr.Markdown(f"# {default_lang.get('app_title')}")
323
  subtitle_md = gr.Markdown(default_lang.get('app_subtitle'))
 
324
  with gr.Row():
325
+ lang_selector = gr.Radio(["๐Ÿ‡ง๐Ÿ‡ท", "๐Ÿ‡บ๐Ÿ‡ธ", "๐Ÿ‡จ๐Ÿ‡ณ"], value="๐Ÿ‡ง๐Ÿ‡ท", label=default_lang.get('lang_selector_label'))
326
  resolution_selector = gr.Radio(["480x480", "720x720", "960x960"], value="480x480", label="Base Resolution")
327
 
328
+ # Step 1 & 2: Pre-Production
329
  with gr.Accordion(default_lang.get('step1_accordion'), open=True) as step1_accordion:
330
  prompt_input = gr.Textbox(label=default_lang.get('prompt_label'), value="A majestic lion walks across the savanna, sits down, and then roars at the setting sun.")
331
  ref_image_input = gr.File(label=default_lang.get('ref_images_label'), file_count="multiple", file_types=["image"])
 
339
  storyboard_output = gr.JSON(label=default_lang.get('storyboard_output_label'))
340
  keyframe_gallery = gr.Gallery(label=default_lang.get('keyframes_gallery_label'), visible=True, object_fit="contain", height="auto", type="filepath")
341
 
342
+ # Step 3: Production
343
  with gr.Accordion(default_lang.get('step3_accordion'), open=False, visible=False) as step3_accordion:
344
  step3_description_md = gr.Markdown(default_lang.get('step3_description'))
 
345
  with gr.Accordion(default_lang.get('ltx_advanced_options'), open=False) as ltx_advanced_options_accordion:
346
  with gr.Accordion(default_lang.get('causality_controls_title'), open=True) as causality_accordion:
347
  trim_percent_slider = gr.Slider(minimum=10, maximum=90, value=50, step=5, label=default_lang.get('trim_percent_label'), info=default_lang.get('trim_percent_info'))
348
  with gr.Row():
349
  forca_guia_slider = gr.Slider(label=default_lang.get('forca_guia_label'), minimum=0.0, maximum=1.0, value=0.5, step=0.05, info=default_lang.get('forca_guia_info'))
350
  convergencia_destino_slider = gr.Slider(label=default_lang.get('convergencia_final_label'), minimum=0.0, maximum=1.0, value=0.75, step=0.05, info=default_lang.get('convergencia_final_info'))
 
351
  with gr.Accordion(default_lang.get('ltx_pipeline_options'), open=True) as ltx_pipeline_accordion:
352
  with gr.Row():
353
  guidance_scale_slider = gr.Slider(minimum=1.0, maximum=10.0, value=2.0, step=0.1, label=default_lang.get('guidance_scale_label'), info=default_lang.get('guidance_scale_info'))
354
  stg_scale_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.025, step=0.005, label=default_lang.get('stg_scale_label'), info=default_lang.get('stg_scale_info'))
355
  inference_steps_slider = gr.Slider(minimum=10, maximum=50, value=20, step=1, label=default_lang.get('steps_label'), info=default_lang.get('steps_info'))
 
356
  produce_original_button = gr.Button(default_lang.get('produce_original_button'), variant="primary")
357
+ original_video_output = gr.Video(label="Original Master Video", visible=False, interactive=False)
358
 
359
+ # Step 4: Post-Production
360
  with gr.Accordion(default_lang.get('step4_accordion'), open=False, visible=False) as step4_accordion:
361
  step4_description_md = gr.Markdown(default_lang.get('step4_description'))
 
 
362
  with gr.Accordion(default_lang.get('sub_step_a_upscaler'), open=True) as sub_step_a_accordion:
363
  upscaler_description_md = gr.Markdown(default_lang.get('upscaler_description'))
364
  with gr.Accordion(default_lang.get('upscaler_options'), open=False) as upscaler_options_accordion:
365
+ upscaler_chunk_size_slider = gr.Slider(minimum=1, maximum=10, value=2, step=1, label=default_lang.get('upscaler_chunk_size_label'), info=default_lang.get('upscaler_chunk_size_info'))
366
  run_upscaler_button = gr.Button(default_lang.get('run_upscaler_button'), variant="secondary")
367
+ upscaler_video_output = gr.Video(label="Upscaled Video", visible=False, interactive=False)
 
 
368
  with gr.Accordion(default_lang.get('sub_step_b_hd'), open=True) as sub_step_b_accordion:
369
  hd_description_md = gr.Markdown(default_lang.get('hd_description'))
370
  with gr.Accordion(default_lang.get('hd_options'), open=False) as hd_options_accordion:
371
+ hd_model_radio = gr.Radio(["3B", "7B"], value="7B", label=default_lang.get('hd_model_label'))
372
+ hd_steps_slider = gr.Slider(minimum=20, maximum=150, value=100, step=5, label=default_lang.get('hd_steps_label'), info=default_lang.get('hd_steps_info'))
373
  run_hd_button = gr.Button(default_lang.get('run_hd_button'), variant="secondary")
374
+ hd_video_output = gr.Video(label="HD Mastered Video", visible=False, interactive=False)
 
 
375
  with gr.Accordion(default_lang.get('sub_step_c_audio'), open=True) as sub_step_c_accordion:
376
  audio_description_md = gr.Markdown(default_lang.get('audio_description'))
377
  with gr.Accordion(default_lang.get('audio_options'), open=False) as audio_options_accordion:
378
  audio_prompt_input = gr.Textbox(label=default_lang.get('audio_prompt_label'), info=default_lang.get('audio_prompt_info'), lines=3)
379
  run_audio_button = gr.Button(default_lang.get('run_audio_button'), variant="secondary")
380
+ audio_video_output = gr.Video(label="Video with Audio", visible=False, interactive=False)
 
 
 
381
 
382
+ # Final Output & Logs
383
+ final_video_output = gr.Video(label=default_lang.get('final_video_label'), visible=False, interactive=False)
384
  with gr.Accordion(default_lang.get('log_accordion_label'), open=False) as log_accordion:
385
  log_display = gr.Textbox(label=default_lang.get('log_display_label'), lines=20, interactive=False, autoscroll=True)
386
  update_log_button = gr.Button(default_lang.get('update_log_button'))
387
 
388
  # --- 4. UI EVENT CONNECTIONS ---
389
+ all_ui_components = list(update_ui_language('๐Ÿ‡ง๐Ÿ‡ท').keys())
 
390
  lang_selector.change(fn=update_ui_language, inputs=lang_selector, outputs=all_ui_components)
391
 
392
+ storyboard_and_keyframes_button.click(fn=run_pre_production_wrapper, inputs=[prompt_input, num_keyframes_slider, ref_image_input, resolution_selector, duration_per_fragment_slider], outputs=[storyboard_output, keyframe_gallery, step3_accordion])
393
+ storyboard_from_photos_button.click(fn=run_pre_production_photo_wrapper, inputs=[prompt_input, num_keyframes_slider, ref_image_input], outputs=[storyboard_output, keyframe_gallery, step3_accordion])
 
 
 
 
 
 
 
 
 
 
394
 
 
395
  produce_original_button.click(
396
  fn=run_original_production_wrapper,
397
+ inputs=[keyframe_gallery, prompt_input, duration_per_fragment_slider, trim_percent_slider, forca_guia_slider, convergencia_destino_slider, guidance_scale_slider, stg_scale_slider, inference_steps_slider, resolution_selector],
398
+ outputs=[original_video_output, final_video_output, step4_accordion, original_latents_paths_state, original_video_path_state, current_source_video_state]
 
 
 
 
 
 
 
 
399
  )
400
 
 
401
  run_upscaler_button.click(
402
  fn=run_upscaler_wrapper,
403
  inputs=[original_latents_paths_state, upscaler_chunk_size_slider],
404
+ outputs=[upscaler_video_output, final_video_output, upscaled_video_path_state, current_source_video_state]
 
 
 
405
  )
406
 
407
  run_hd_button.click(
408
  fn=run_hd_wrapper,
409
+ inputs=[current_source_video_state, hd_model_radio, hd_steps_slider, prompt_input],
410
+ outputs=[hd_video_output, final_video_output, hd_video_path_state, current_source_video_state]
 
 
 
411
  )
412
 
413
  run_audio_button.click(
 
416
  outputs=[audio_video_output, final_video_output]
417
  )
418
 
 
419
  update_log_button.click(fn=get_log_content, inputs=[], outputs=[log_display])
420
 
421
  # --- 5. APPLICATION LAUNCH ---