RafaG commited on
Commit
9b22111
·
verified ·
1 Parent(s): 78c6d3d

Update webui/app.py

Browse files
Files changed (1) hide show
  1. webui/app.py +32 -12
webui/app.py CHANGED
@@ -130,7 +130,7 @@ def apply_experimental_preset(preset_name):
130
  # Subtitle logic moved to subtitle_handler.py
131
 
132
 
133
- def run_viral_cutter(input_source, project_name, url, video_file, segments, viral, themes, min_duration, max_duration, model, ai_backend, api_key, ai_model_name, chunk_size, workflow, face_model, face_mode, face_detect_interval,
134
  face_filter_thresh, face_two_thresh, face_conf_thresh, face_dead_zone, focus_active_speaker, active_speaker_mar, active_speaker_score_diff, include_motion, active_speaker_motion_threshold, active_speaker_motion_sensitivity, active_speaker_decay,
135
  use_custom_subs, font_name, font_size, font_color, highlight_color, outline_color, outline_thickness, shadow_color, shadow_size, is_bold, is_italic, is_uppercase, vertical_pos, alignment,
136
  h_size, w_block, gap, mode, under, strike, border_s, remove_punc, video_quality, use_youtube_subs, translate_target):
@@ -203,6 +203,7 @@ def run_viral_cutter(input_source, project_name, url, video_file, segments, vira
203
  cmd.extend(["--face-model", face_model])
204
  cmd.extend(["--face-mode", face_mode])
205
  if face_detect_interval: cmd.extend(["--face-detect-interval", str(face_detect_interval)])
 
206
 
207
  # New Face Params
208
  if face_filter_thresh is not None: cmd.extend(["--face-filter-threshold", str(face_filter_thresh)])
@@ -334,7 +335,7 @@ with gr.Blocks(title=i18n("ViralCutter WebUI"), theme=gr.themes.Default(primary_
334
  with gr.Tab(i18n("Create New")):
335
  with gr.Row():
336
  with gr.Column(scale=1):
337
- input_source = gr.Radio([(i18n("YouTube URL"), "YouTube URL"), (i18n("Existing Project"), "Existing Project"), (i18n("Upload Video"), "Upload Video")], label=i18n("Input Source"), value="Upload Video")
338
 
339
  url_input = gr.Textbox(label=i18n("YouTube URL"), placeholder="https://www.youtube.com/watch?v=...", visible=False)
340
  video_upload = gr.File(label=i18n("Upload Video"), file_count="single", file_types=["video"], visible=True)
@@ -348,9 +349,9 @@ with gr.Blocks(title=i18n("ViralCutter WebUI"), theme=gr.themes.Default(primary_
348
 
349
  def on_source_change(source):
350
  if source == "YouTube URL":
351
- return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(value="Full")
352
  elif source == "Upload Video":
353
- return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(value="Full")
354
  else:
355
  # Load projects
356
  projs = library.get_existing_projects()
@@ -367,7 +368,7 @@ with gr.Blocks(title=i18n("ViralCutter WebUI"), theme=gr.themes.Default(primary_
367
  max_dur_input = gr.Number(label=i18n("Max Duration (s)"), value=90)
368
  with gr.Column(scale=1):
369
  with gr.Row():
370
- ai_backend_input = gr.Dropdown(choices=[(i18n("Gemini"), "gemini"), (i18n("G4F"), "g4f"), (i18n("Local (GGUF)"), "local"), (i18n("Manual"), "manual")], label=i18n("AI Backend"), value="gemini", scale=2)
371
  api_key_input = gr.Textbox(label=i18n("Gemini API Key"), type="password", scale=3)
372
 
373
  # New Dynamic Inputs
@@ -389,16 +390,16 @@ with gr.Blocks(title=i18n("ViralCutter WebUI"), theme=gr.themes.Default(primary_
389
  if backend == "gemini":
390
  new_choices = GEMINI_MODELS
391
  new_val = GEMINI_MODELS[1]
392
- new_chunk = 20000
393
  elif backend == "g4f":
394
  new_choices = G4F_MODELS
395
- new_val = G4F_MODELS[0]
396
- new_chunk = 3000
397
  elif backend == "local":
398
  models = get_local_models()
399
  new_choices = models if models else [i18n("No models found")]
400
  new_val = new_choices[0]
401
- new_chunk = 15000
402
  else: # Manual
403
  pass
404
 
@@ -424,6 +425,7 @@ with gr.Blocks(title=i18n("ViralCutter WebUI"), theme=gr.themes.Default(primary_
424
  with gr.Row():
425
  face_mode_input = gr.Dropdown(choices=[(i18n("Auto"), "auto"), ("1", "1"), ("2", "2")], label=i18n("Face Mode"), value="auto")
426
  face_detect_interval_input = gr.Textbox(label=i18n("Face Det. Interval"), value="0.17,1.0")
 
427
 
428
 
429
  # Update listeners now that all components are defined
@@ -540,7 +542,25 @@ with gr.Blocks(title=i18n("ViralCutter WebUI"), theme=gr.themes.Default(primary_
540
  function() {
541
  var ta = document.querySelector('#logs_output textarea');
542
  if(ta) {
543
- ta.scrollTop = ta.scrollHeight;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
544
  }
545
  }
546
  """)
@@ -550,7 +570,7 @@ with gr.Blocks(title=i18n("ViralCutter WebUI"), theme=gr.themes.Default(primary_
550
  start_btn.click(run_viral_cutter, inputs=[
551
  input_source, project_selector, url_input, video_upload, segments_input, viral_input, themes_input, min_dur_input, max_dur_input,
552
  model_input, ai_backend_input, api_key_input, ai_model_input, chunk_size_input,
553
- workflow_input, face_model_input, face_mode_input, face_detect_interval_input,
554
  face_filter_thresh_input, face_two_thresh_input, face_conf_thresh_input, face_dead_zone_input, focus_active_speaker_input,
555
  active_speaker_mar_input, active_speaker_score_diff_input, include_motion_input, active_speaker_motion_threshold_input, active_speaker_motion_sensitivity_input, active_speaker_decay_input,
556
  use_custom_subs,
@@ -748,7 +768,7 @@ with gr.Blocks(title=i18n("ViralCutter WebUI"), theme=gr.themes.Default(primary_
748
  {i18n('Apoie o projeto, qualquer valor é bem-vindo:')}
749
  <a href='https://nubank.com.br/pagar/1ls6a4/0QpSSbWBSq' target='_blank'><strong>{i18n('Apoiar via PIX')}</strong></a>
750
  <br>
751
- {i18n('100% local • open source • sem assinatura')}
752
  </p>
753
  </div>
754
  """)
 
130
  # Subtitle logic moved to subtitle_handler.py
131
 
132
 
133
+ def run_viral_cutter(input_source, project_name, url, video_file, segments, viral, themes, min_duration, max_duration, model, ai_backend, api_key, ai_model_name, chunk_size, workflow, face_model, face_mode, face_detect_interval, no_face_mode,
134
  face_filter_thresh, face_two_thresh, face_conf_thresh, face_dead_zone, focus_active_speaker, active_speaker_mar, active_speaker_score_diff, include_motion, active_speaker_motion_threshold, active_speaker_motion_sensitivity, active_speaker_decay,
135
  use_custom_subs, font_name, font_size, font_color, highlight_color, outline_color, outline_thickness, shadow_color, shadow_size, is_bold, is_italic, is_uppercase, vertical_pos, alignment,
136
  h_size, w_block, gap, mode, under, strike, border_s, remove_punc, video_quality, use_youtube_subs, translate_target):
 
203
  cmd.extend(["--face-model", face_model])
204
  cmd.extend(["--face-mode", face_mode])
205
  if face_detect_interval: cmd.extend(["--face-detect-interval", str(face_detect_interval)])
206
+ if no_face_mode: cmd.extend(["--no-face-mode", no_face_mode])
207
 
208
  # New Face Params
209
  if face_filter_thresh is not None: cmd.extend(["--face-filter-threshold", str(face_filter_thresh)])
 
335
  with gr.Tab(i18n("Create New")):
336
  with gr.Row():
337
  with gr.Column(scale=1):
338
+ input_source = gr.Radio([(i18n("YouTube URL | Off HF"), "YouTube URL"), (i18n("Existing Project"), "Existing Project"), (i18n("Upload Video"), "Upload Video")], label=i18n("Input Source"), value="Upload Video")
339
 
340
  url_input = gr.Textbox(label=i18n("YouTube URL"), placeholder="https://www.youtube.com/watch?v=...", visible=False)
341
  video_upload = gr.File(label=i18n("Upload Video"), file_count="single", file_types=["video"], visible=True)
 
349
 
350
  def on_source_change(source):
351
  if source == "YouTube URL":
352
+ return gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(value="Full")
353
  elif source == "Upload Video":
354
+ return gr.update(visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(value="Full")
355
  else:
356
  # Load projects
357
  projs = library.get_existing_projects()
 
368
  max_dur_input = gr.Number(label=i18n("Max Duration (s)"), value=90)
369
  with gr.Column(scale=1):
370
  with gr.Row():
371
+ ai_backend_input = gr.Dropdown(choices=[(i18n("Gemini"), "gemini"), (i18n("G4F"), "g4f"), (i18n("Local (GGUF) (Off HF)"), "local"), (i18n("Manual"), "manual")], label=i18n("AI Backend"), value="gemini", scale=2)
372
  api_key_input = gr.Textbox(label=i18n("Gemini API Key"), type="password", scale=3)
373
 
374
  # New Dynamic Inputs
 
390
  if backend == "gemini":
391
  new_choices = GEMINI_MODELS
392
  new_val = GEMINI_MODELS[1]
393
+ new_chunk = 70000
394
  elif backend == "g4f":
395
  new_choices = G4F_MODELS
396
+ new_val = G4F_MODELS[5]
397
+ new_chunk = 70000
398
  elif backend == "local":
399
  models = get_local_models()
400
  new_choices = models if models else [i18n("No models found")]
401
  new_val = new_choices[0]
402
+ new_chunk = 30000
403
  else: # Manual
404
  pass
405
 
 
425
  with gr.Row():
426
  face_mode_input = gr.Dropdown(choices=[(i18n("Auto"), "auto"), ("1", "1"), ("2", "2")], label=i18n("Face Mode"), value="auto")
427
  face_detect_interval_input = gr.Textbox(label=i18n("Face Det. Interval"), value="0.17,1.0")
428
+ no_face_mode_input = gr.Dropdown(choices=[(i18n("Padding (9:16)"), "padding"), (i18n("Zoom (Center)"), "zoom")], label=i18n("No Face Fallback"), value="zoom")
429
 
430
 
431
  # Update listeners now that all components are defined
 
542
  function() {
543
  var ta = document.querySelector('#logs_output textarea');
544
  if(ta) {
545
+ // Setup scroll listener once to track user intent
546
+ if (!ta._scrollerSetup) {
547
+ ta._isSticky = true; // Default to sticky
548
+ ta.addEventListener('scroll', function() {
549
+ var diff = ta.scrollHeight - ta.scrollTop - ta.clientHeight;
550
+ // If near bottom (<50px), enable sticky. Else disable.
551
+ if (diff <= 50) {
552
+ ta._isSticky = true;
553
+ } else {
554
+ ta._isSticky = false;
555
+ }
556
+ });
557
+ ta._scrollerSetup = true;
558
+ }
559
+
560
+ // Apply scroll only if sticky
561
+ if(ta._isSticky === undefined || ta._isSticky === true) {
562
+ ta.scrollTop = ta.scrollHeight;
563
+ }
564
  }
565
  }
566
  """)
 
570
  start_btn.click(run_viral_cutter, inputs=[
571
  input_source, project_selector, url_input, video_upload, segments_input, viral_input, themes_input, min_dur_input, max_dur_input,
572
  model_input, ai_backend_input, api_key_input, ai_model_input, chunk_size_input,
573
+ workflow_input, face_model_input, face_mode_input, face_detect_interval_input, no_face_mode_input,
574
  face_filter_thresh_input, face_two_thresh_input, face_conf_thresh_input, face_dead_zone_input, focus_active_speaker_input,
575
  active_speaker_mar_input, active_speaker_score_diff_input, include_motion_input, active_speaker_motion_threshold_input, active_speaker_motion_sensitivity_input, active_speaker_decay_input,
576
  use_custom_subs,
 
768
  {i18n('Apoie o projeto, qualquer valor é bem-vindo:')}
769
  <a href='https://nubank.com.br/pagar/1ls6a4/0QpSSbWBSq' target='_blank'><strong>{i18n('Apoiar via PIX')}</strong></a>
770
  <br>
771
+ {i18n('100% local • open source • no subscription required')}
772
  </p>
773
  </div>
774
  """)