CK-Explorer commited on
Commit
39b0aa8
·
1 Parent(s): efcefeb

feat: add merging modes to web UI

Browse files
Files changed (4) hide show
  1. assets/merging_mode_info.html +10 -0
  2. ui/constants.py +6 -3
  3. ui/events.py +17 -8
  4. ui/layout.py +43 -39
assets/merging_mode_info.html ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <div>
2
+ <p><strong>Merging Mode:</strong></p>
3
+ <ul>
4
+ <li><b>Synced</b> – all timestamps overlap (from the same cut)</li>
5
+ <li><b>Mixed</b> – some timestamps don't overlap (from the same cut)</li>
6
+ <li><b>Cuts</b> – different cuts (primary being extended or longer version)</li>
7
+ </ul>
8
+
9
+ <p>💡 For <strong>Mixed</strong> and <strong>Cuts</strong> modes, subtitles should <strong>not contain scene annotations </strong>if possible.</p>
10
+ </div>
ui/constants.py CHANGED
@@ -1,19 +1,22 @@
1
  """
2
  Constants used in the DuoSubs Hugging Face Web UI.
3
 
4
- This module defines file paths, supported subtitle formats, and default values for use
5
- in the UI and other components.
6
  """
7
 
8
  from pathlib import Path
9
 
10
- from duosubs import SubtitleFormat
11
 
12
  TITLE_HTML = Path(__file__).parent.parent / "assets" / "title.html"
 
13
 
14
  SUB_EXT_LIST: list[str] = [f.value for f in SubtitleFormat]
15
  SUB_EXT_LIST_WITH_DOT: list[str] = [f".{ext}" for ext in SUB_EXT_LIST]
16
 
 
 
17
  DEFAULT_SUB_EXT = SubtitleFormat.ASS.value
18
 
19
  MODEL_NAME_LIST = [
 
1
  """
2
  Constants used in the DuoSubs Hugging Face Web UI.
3
 
4
+ This module defines file paths, supported subtitle formats, merging mode options,
5
+ and default values for use in the UI and other components.
6
  """
7
 
8
  from pathlib import Path
9
 
10
+ from duosubs import MergingMode, SubtitleFormat
11
 
12
  TITLE_HTML = Path(__file__).parent.parent / "assets" / "title.html"
13
+ MERGING_MODE_INFO = Path(__file__).parent.parent / "assets" / "merging_mode_info.html"
14
 
15
  SUB_EXT_LIST: list[str] = [f.value for f in SubtitleFormat]
16
  SUB_EXT_LIST_WITH_DOT: list[str] = [f".{ext}" for ext in SUB_EXT_LIST]
17
 
18
+ MERGING_MODE_LIST: list[str] = [f.value.capitalize() for f in MergingMode]
19
+
20
  DEFAULT_SUB_EXT = SubtitleFormat.ASS.value
21
 
22
  MODEL_NAME_LIST = [
ui/events.py CHANGED
@@ -13,6 +13,7 @@ from duosubs import (
13
  LoadSubsError,
14
  MergeArgs,
15
  MergeSubsError,
 
16
  OmitFile,
17
  SaveSubsError,
18
  SubtitleFormat,
@@ -29,7 +30,7 @@ def start_merging(
29
  secondary_subtitles: str,
30
  model_name: str,
31
  batch_size: int,
32
- ignore_non_overlap: bool,
33
  retain_newline: bool,
34
  secondary_above_primary: bool,
35
  omit_subtitles: list[str],
@@ -50,14 +51,18 @@ def start_merging(
50
  secondary_subtitles (str): Path to secondary subtitle file.
51
  model_name (str): Name of the model to use.
52
  batch_size (int): Batch size for inference.
53
- ignore_non_overlap (bool): Whether to ignore non-overlapping subtitles.
54
  retain_newline (bool): Whether to retain newlines in output.
55
  secondary_above_primary (bool): Whether to place secondary subtitle above
56
  primary.
57
- omit_subtitles (list[str]): List of subtitle types to omit from output.
58
- combined_format (str): Format for combined subtitles.
59
- primary_format (str): Format for primary subtitles.
60
- secondary_format (str): Format for secondary subtitles.
 
 
 
 
61
  cancel_state (list[bool]): List tracking cancellation state.
62
  progress (gradio.Progress) : Gradio progress object (optional).
63
  Defaults to None.
@@ -75,7 +80,7 @@ def start_merging(
75
  primary=primary_subtitles,
76
  secondary=secondary_subtitles,
77
  batch_size=int(batch_size),
78
- ignore_non_overlap_filter=ignore_non_overlap,
79
  retain_newline=retain_newline,
80
  secondary_above=secondary_above_primary,
81
  omit=[OmitFile.EDIT],
@@ -114,7 +119,11 @@ def start_merging(
114
  def update_progress(current: int) -> None:
115
  progress(
116
  progress=current/100,
117
- desc= f"Stage 2 → Merging subtitles using {model_name}",
 
 
 
 
118
  total=100
119
  )
120
  merged_subs = merge_subtitles(
 
13
  LoadSubsError,
14
  MergeArgs,
15
  MergeSubsError,
16
+ MergingMode,
17
  OmitFile,
18
  SaveSubsError,
19
  SubtitleFormat,
 
30
  secondary_subtitles: str,
31
  model_name: str,
32
  batch_size: int,
33
+ merging_mode: str,
34
  retain_newline: bool,
35
  secondary_above_primary: bool,
36
  omit_subtitles: list[str],
 
51
  secondary_subtitles (str): Path to secondary subtitle file.
52
  model_name (str): Name of the model to use.
53
  batch_size (int): Batch size for inference.
54
+ merging_mode (str): Subttitle merging mode (based on the value of MergingMode).
55
  retain_newline (bool): Whether to retain newlines in output.
56
  secondary_above_primary (bool): Whether to place secondary subtitle above
57
  primary.
58
+ omit_subtitles (list[str]): List of subtitle types to omit from output (based
59
+ on the value of OmitFile).
60
+ combined_format (str): Format for combined subtitles (based on the value of
61
+ SubtitleFormat).
62
+ primary_format (str): Format for primary subtitles (based on the value of
63
+ SubtitleFormat).
64
+ secondary_format (str): Format for secondary subtitles (based on the value of
65
+ SubtitleFormat).
66
  cancel_state (list[bool]): List tracking cancellation state.
67
  progress (gradio.Progress) : Gradio progress object (optional).
68
  Defaults to None.
 
80
  primary=primary_subtitles,
81
  secondary=secondary_subtitles,
82
  batch_size=int(batch_size),
83
+ merging_mode=MergingMode(merging_mode.lower()),
84
  retain_newline=retain_newline,
85
  secondary_above=secondary_above_primary,
86
  omit=[OmitFile.EDIT],
 
119
  def update_progress(current: int) -> None:
120
  progress(
121
  progress=current/100,
122
+ desc= (
123
+ f"Stage 2 → Merging subtitles "
124
+ f"({args.merging_mode.value.capitalize()} mode, "
125
+ f"using {model_name})"
126
+ ),
127
  total=100
128
  )
129
  merged_subs = merge_subtitles(
ui/layout.py CHANGED
@@ -11,6 +11,8 @@ import gradio as gr
11
 
12
  from .constants import (
13
  DEFAULT_SUB_EXT,
 
 
14
  MODEL_NAME_LIST,
15
  SUB_EXT_LIST,
16
  SUB_EXT_LIST_WITH_DOT,
@@ -70,24 +72,22 @@ def create_main_gr_blocks_ui(
70
  ) = _create_subtitles_io_block()
71
  with gr.Column():
72
  gr.Markdown("### ⚙️ Configurations")
73
- with gr.Accordion("Basic"):
74
- with gr.Tab("Model Selection"):
75
- model_name = _create_model_configurations_block()
76
- with gr.Tab("Output Styling"):
77
- (
78
- retain_newline,
79
- secondary_above_primary
80
- ) = _create_output_styling_block()
81
- with gr.Tab("File Exports"):
82
- (
83
- omit_subtitles,
84
- combined_format,
85
- primary_format,
86
- secondary_format
87
- ) = _create_file_exports_block()
88
- with gr.Accordion("Advanced", open=False):
89
- with gr.Tab("Alignment Behavior"):
90
- ignore_non_overlap = _create_alignment_behaviour_block()
91
 
92
  omit_subtitles.change(
93
  fn=validate_excluded_subtitle_file,
@@ -104,7 +104,7 @@ def create_main_gr_blocks_ui(
104
  primary_file,
105
  secondary_file,
106
  model_name,
107
- ignore_non_overlap,
108
  retain_newline,
109
  secondary_above_primary,
110
  omit_subtitles,
@@ -188,26 +188,26 @@ def _create_model_configurations_block() -> gr.Dropdown:
188
  )
189
  return model_name
190
 
191
- def _create_alignment_behaviour_block() -> gr.Checkbox:
192
  """
193
  Creates alignment behavior UI components.
194
 
195
- This function sets up a checkbox for ignoring non-overlapping subtitles, in the
196
- merging process.
197
-
198
  Returns:
199
- gradio.Checkbox: Checkbox for alignment behavior.
200
  """
 
201
  with gr.Column():
202
- ignore_non_overlap = gr.Checkbox(
203
- label="Ignore Non-Overlap Filter",
204
- value=False,
205
- info=(
206
- "💡 Use only if both subtitles are **semantically identical** "
207
- "and contain **no added scenes or annotations**"
208
- )
209
  )
210
- return ignore_non_overlap
 
 
211
 
212
  def _create_output_styling_block() -> tuple[gr.Checkbox, gr.Checkbox]:
213
  """
@@ -280,7 +280,7 @@ def wrapped_start_merging(
280
  primary_subtitles: str,
281
  secondary_subtitles: str,
282
  model_name: str,
283
- ignore_non_overlap: bool,
284
  retain_newline: bool,
285
  secondary_above_primary: bool,
286
  omit_subtitles: list[str],
@@ -297,14 +297,18 @@ def wrapped_start_merging(
297
  primary_subtitles (str): Path to primary subtitle file.
298
  secondary_subtitles (str): Path to secondary subtitle file.
299
  model_name (str): Name of the model to use.
300
- ignore_non_overlap (bool): Whether to ignore non-overlapping subtitles.
301
  retain_newline (bool): Whether to retain newlines in output.
302
  secondary_above_primary (bool): Whether to place secondary subtitle above
303
  primary.
304
- omit_subtitles (list[str]): List of subtitle types to omit from output.
305
- combined_format (str): Format for combined subtitles.
306
- primary_format (str): Format for primary subtitles.
307
- secondary_format (str): Format for secondary subtitles.
 
 
 
 
308
  gpu_list (list[str]): List of available GPU names.
309
  loaded_model_device (list[str]): List tracking loaded model device.
310
  loaded_model_name (list[str]): List tracking loaded model name.
@@ -322,7 +326,7 @@ def wrapped_start_merging(
322
  secondary_subtitles,
323
  model_name,
324
  256,
325
- ignore_non_overlap,
326
  retain_newline,
327
  secondary_above_primary,
328
  omit_subtitles,
 
11
 
12
  from .constants import (
13
  DEFAULT_SUB_EXT,
14
+ MERGING_MODE_INFO,
15
+ MERGING_MODE_LIST,
16
  MODEL_NAME_LIST,
17
  SUB_EXT_LIST,
18
  SUB_EXT_LIST_WITH_DOT,
 
72
  ) = _create_subtitles_io_block()
73
  with gr.Column():
74
  gr.Markdown("### ⚙️ Configurations")
75
+ with gr.Tab("Model Selection"):
76
+ model_name = _create_model_configurations_block()
77
+ with gr.Tab("Alignment Behavior"):
78
+ merging_mode = _create_alignment_behaviour_block()
79
+ with gr.Tab("Output Styling"):
80
+ (
81
+ retain_newline,
82
+ secondary_above_primary
83
+ ) = _create_output_styling_block()
84
+ with gr.Tab("File Exports"):
85
+ (
86
+ omit_subtitles,
87
+ combined_format,
88
+ primary_format,
89
+ secondary_format
90
+ ) = _create_file_exports_block()
 
 
91
 
92
  omit_subtitles.change(
93
  fn=validate_excluded_subtitle_file,
 
104
  primary_file,
105
  secondary_file,
106
  model_name,
107
+ merging_mode,
108
  retain_newline,
109
  secondary_above_primary,
110
  omit_subtitles,
 
188
  )
189
  return model_name
190
 
191
+ def _create_alignment_behaviour_block() -> gr.Radio:
192
  """
193
  Creates alignment behavior UI components.
194
 
195
+ This function sets up a radio buttons for selecting the subtitles merging mode.
196
+
 
197
  Returns:
198
+ gradio.Radio: Radio buttons for merging mode.
199
  """
200
+ mode_content = open_html(MERGING_MODE_INFO)
201
  with gr.Column():
202
+ merging_mode = gr.Radio(
203
+ label="Merging Mode",
204
+ choices=MERGING_MODE_LIST,
205
+ value=MERGING_MODE_LIST[0],
206
+ info="Please refer to **ℹ️ Info** below for more information" # noqa: RUF001
 
 
207
  )
208
+ with gr.Accordion("ℹ️ Info"): # noqa: RUF001
209
+ gr.HTML(mode_content)
210
+ return merging_mode
211
 
212
  def _create_output_styling_block() -> tuple[gr.Checkbox, gr.Checkbox]:
213
  """
 
280
  primary_subtitles: str,
281
  secondary_subtitles: str,
282
  model_name: str,
283
+ merging_mode: str,
284
  retain_newline: bool,
285
  secondary_above_primary: bool,
286
  omit_subtitles: list[str],
 
297
  primary_subtitles (str): Path to primary subtitle file.
298
  secondary_subtitles (str): Path to secondary subtitle file.
299
  model_name (str): Name of the model to use.
300
+ merging_mode (str): Subttitle merging mode (based on the value of MergingMode).
301
  retain_newline (bool): Whether to retain newlines in output.
302
  secondary_above_primary (bool): Whether to place secondary subtitle above
303
  primary.
304
+ omit_subtitles (list[str]): List of subtitle types to omit from output (based
305
+ on the value of OmitFile).
306
+ combined_format (str): Format for combined subtitles (based on the value of
307
+ SubtitleFormat).
308
+ primary_format (str): Format for primary subtitles (based on the value of
309
+ SubtitleFormat).
310
+ secondary_format (str): Format for secondary subtitles (based on the value of
311
+ SubtitleFormat).
312
  gpu_list (list[str]): List of available GPU names.
313
  loaded_model_device (list[str]): List tracking loaded model device.
314
  loaded_model_name (list[str]): List tracking loaded model name.
 
326
  secondary_subtitles,
327
  model_name,
328
  256,
329
+ merging_mode,
330
  retain_newline,
331
  secondary_above_primary,
332
  omit_subtitles,