abocha commited on
Commit
b7680b4
·
1 Parent(s): 8468afb
Files changed (2) hide show
  1. app.py +14 -27
  2. ui_layout.py +22 -23
app.py CHANGED
@@ -75,9 +75,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
75
  # When TTS model changes, update visibility of global speed/instructions & refresh dynamic UI
76
  tts_model_dropdown.change(
77
  fn=update_model_controls_visibility,
78
- inputs=[tts_model_dropdown, script_input, speaker_configs_state, speaker_configs_state], # Pass state component itself
79
- # The outputs list names the components that will be updated by the dictionary keys
80
- # returned by update_model_controls_visibility.
81
  outputs=[global_speed_input, global_instructions_input, dynamic_speaker_ui_area, speaker_configs_state]
82
  )
83
 
@@ -85,14 +83,13 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
85
  speaker_config_method_dropdown.change(
86
  fn=update_speaker_config_method_visibility,
87
  inputs=[speaker_config_method_dropdown],
88
- # The outputs list names the components that will be updated by the dictionary keys.
89
  outputs=[single_voice_group, detailed_per_speaker_ui_group]
90
  )
91
 
92
  # Button to load/refresh the detailed per-speaker UI configurations
93
  load_per_speaker_ui_button.click(
94
  fn=load_refresh_per_speaker_ui,
95
- inputs=[script_input, speaker_configs_state, tts_model_dropdown, speaker_configs_state], # Pass state comp
96
  outputs=[dynamic_speaker_ui_area, speaker_configs_state]
97
  )
98
 
@@ -106,8 +103,9 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
106
  # Generate audio button
107
  # Use functools.partial to pass fixed arguments like API key and client to the handler
108
  # Gradio inputs will be appended to these fixed arguments when the handler is called.
 
109
  generate_button.click(
110
- fn=partial(handle_script_processing, OPENAI_API_KEY, async_openai_client, NSFW_API_URL_TEMPLATE),
111
  inputs=[
112
  script_input, tts_model_dropdown, pause_input,
113
  speaker_config_method_dropdown, global_voice_dropdown,
@@ -118,38 +116,27 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
118
  )
119
 
120
  # --- Examples UI ---
121
- # Define inputs for examples (must match the structure in ui_layout.create_examples_ui)
122
- # This list should contain the Gradio component instances
123
  example_inputs_list = [
124
  script_input, tts_model_dropdown, pause_input,
125
  speaker_config_method_dropdown, global_voice_dropdown,
126
- speaker_configs_state, # This is a gr.State component, gr.Examples handles it
127
  global_speed_input, global_instructions_input
128
  ]
129
 
130
- # For examples to run the processing function, they need output components too.
131
  example_outputs_list = [individual_lines_zip_output, merged_dialogue_mp3_output, status_output]
132
 
133
- # Create examples UI - now passing the process_fn correctly
134
- # We need a wrapper for the process_fn if it uses partial for fixed args like the main button.
135
- # Or, examples can just load inputs, and user clicks "Generate".
136
- # For now, let's make examples only load inputs to simplify.
137
- # To make examples runnable:
138
- # example_process_fn = partial(handle_script_processing, OPENAI_API_KEY, async_openai_client, NSFW_API_URL_TEMPLATE)
139
- # Then use example_process_fn in create_examples_ui if it's set up to take `fn`.
140
- # The current create_examples_ui doesn't use `fn` for simplicity of fixing display.
141
 
142
- _ = create_examples_ui(inputs_for_examples=example_inputs_list, process_fn=None)
143
- # If you want examples to be clickable to run the generation directly:
144
- # 1. Modify `create_examples_ui` in `ui_layout.py` to accept and use `fn` and `outputs_for_examples`.
145
- # Its gr.Examples call would be:
146
- # `gr.Examples(..., fn=process_fn, outputs=outputs_for_examples, cache_examples=False)`
147
- # 2. In this file, define `example_process_fn` and pass it:
148
- # `example_process_fn = partial(handle_script_processing, OPENAI_API_KEY, async_openai_client, NSFW_API_URL_TEMPLATE)`
149
- # `_ = create_examples_ui(inputs_for_examples=example_inputs_list, outputs_for_examples=example_outputs_list, process_fn=example_process_fn)`
150
 
151
  # --- Launch ---
152
  if __name__ == "__main__":
153
  if os.name == 'nt':
154
  asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
155
- demo.queue().launch(debug=True, share=False) # .queue() is good for async operations
 
75
  # When TTS model changes, update visibility of global speed/instructions & refresh dynamic UI
76
  tts_model_dropdown.change(
77
  fn=update_model_controls_visibility,
78
+ inputs=[tts_model_dropdown, script_input, speaker_configs_state, speaker_configs_state],
 
 
79
  outputs=[global_speed_input, global_instructions_input, dynamic_speaker_ui_area, speaker_configs_state]
80
  )
81
 
 
83
  speaker_config_method_dropdown.change(
84
  fn=update_speaker_config_method_visibility,
85
  inputs=[speaker_config_method_dropdown],
 
86
  outputs=[single_voice_group, detailed_per_speaker_ui_group]
87
  )
88
 
89
  # Button to load/refresh the detailed per-speaker UI configurations
90
  load_per_speaker_ui_button.click(
91
  fn=load_refresh_per_speaker_ui,
92
+ inputs=[script_input, speaker_configs_state, tts_model_dropdown, speaker_configs_state],
93
  outputs=[dynamic_speaker_ui_area, speaker_configs_state]
94
  )
95
 
 
103
  # Generate audio button
104
  # Use functools.partial to pass fixed arguments like API key and client to the handler
105
  # Gradio inputs will be appended to these fixed arguments when the handler is called.
106
+ generate_button_fn = partial(handle_script_processing, OPENAI_API_KEY, async_openai_client, NSFW_API_URL_TEMPLATE)
107
  generate_button.click(
108
+ fn=generate_button_fn,
109
  inputs=[
110
  script_input, tts_model_dropdown, pause_input,
111
  speaker_config_method_dropdown, global_voice_dropdown,
 
116
  )
117
 
118
  # --- Examples UI ---
 
 
119
  example_inputs_list = [
120
  script_input, tts_model_dropdown, pause_input,
121
  speaker_config_method_dropdown, global_voice_dropdown,
122
+ speaker_configs_state,
123
  global_speed_input, global_instructions_input
124
  ]
125
 
 
126
  example_outputs_list = [individual_lines_zip_output, merged_dialogue_mp3_output, status_output]
127
 
128
+ # Make examples runnable
129
+ example_process_fn = partial(handle_script_processing, OPENAI_API_KEY, async_openai_client, NSFW_API_URL_TEMPLATE)
 
 
 
 
 
 
130
 
131
+ _ = create_examples_ui(
132
+ inputs_for_examples=example_inputs_list,
133
+ process_fn=example_process_fn if OPENAI_API_KEY else None, # Only make runnable if API key exists
134
+ outputs_for_examples=example_outputs_list if OPENAI_API_KEY else None
135
+ )
136
+
 
 
137
 
138
  # --- Launch ---
139
  if __name__ == "__main__":
140
  if os.name == 'nt':
141
  asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
142
+ demo.queue().launch(debug=True, share=False)
ui_layout.py CHANGED
@@ -97,22 +97,18 @@ def create_action_and_output_components():
97
  status_output = gr.Textbox(label="Status", interactive=False, lines=2, max_lines=5)
98
  return calculate_cost_button, generate_button, cost_output, individual_lines_zip_output, merged_dialogue_mp3_output, status_output
99
 
100
- def create_examples_ui(inputs_for_examples, process_fn):
101
  """Creates the examples section."""
102
  gr.Markdown("## Example Scripts")
103
  example_script_1 = "[Alice] Hello Bob, this is a test using the detailed configuration method.\n[Bob] Hi Alice! I'm Bob, and I'll have my own voice settings.\n[Alice] Let's see how this sounds."
104
  example_script_2 = "[Narrator] This is a short story.\n[CharacterA] Once upon a time...\n[Narrator] ...there was a Gradio app.\n[CharacterB] And it could talk!"
105
 
106
- # Ensure a valid default voice for examples if APP_AVAILABLE_VOICES is somehow empty
107
- # This is already handled by DEFAULT_GLOBAL_VOICE at the top of this file.
108
-
109
  examples_data = [
110
  [example_script_1, "tts-1-hd", 300, "Detailed Configuration (Per Speaker UI)", DEFAULT_GLOBAL_VOICE, {}, 1.0, ""],
111
  [example_script_2, "gpt-4o-mini-tts", 200, "Random per Speaker", DEFAULT_GLOBAL_VOICE, {}, 1.0, "Speak with a gentle, storytelling voice for the narrator."],
112
  ["[Solo] Just one line, using global voice and speed.", "tts-1", 0, "Single Voice (Global)", "fable", {}, 1.2, ""],
113
  ]
114
 
115
- # Check if the number of items in each example matches the number of input components
116
  num_inputs = len(inputs_for_examples)
117
  valid_examples_data = []
118
  for ex_data in examples_data:
@@ -123,22 +119,25 @@ def create_examples_ui(inputs_for_examples, process_fn):
123
 
124
  if not valid_examples_data:
125
  gr.Markdown("<p style='color: orange;'>No valid examples could be loaded due to configuration mismatch.</p>")
126
- return None # Or an empty Examples component if that's better
127
 
128
- return gr.Examples(
129
- examples=valid_examples_data,
130
- inputs=inputs_for_examples, # This list must match the structure of example_data items
131
- # Outputs for examples are not strictly necessary to pre-compute if cache_examples=False
132
- # but defining them can help Gradio understand the flow.
133
- # We can make the example click run the full processing.
134
- # outputs=[individual_lines_zip_output, merged_dialogue_mp3_output, status_output], # these components are not passed here
135
- # For examples to run the main function, the output components need to be part of the gr.Examples call.
136
- # However, the prompt is to make the list appear. Let's simplify for now.
137
- # If outputs are defined, they must be component instances.
138
- # For now, let's remove fn and outputs from gr.Examples just to ensure the list shows.
139
- # Later, we can wire them back if needed, ensuring the output components are correctly passed.
140
- # fn=process_fn, # Removed for debugging example list display
141
- # cache_examples=False
142
- label="Example Scripts (Click to Load Inputs)",
143
- samples_per_page=5 # Helps ensure it tries to render
144
- )
 
 
 
 
97
  status_output = gr.Textbox(label="Status", interactive=False, lines=2, max_lines=5)
98
  return calculate_cost_button, generate_button, cost_output, individual_lines_zip_output, merged_dialogue_mp3_output, status_output
99
 
100
+ def create_examples_ui(inputs_for_examples, process_fn, outputs_for_examples=None): # Added outputs_for_examples
101
  """Creates the examples section."""
102
  gr.Markdown("## Example Scripts")
103
  example_script_1 = "[Alice] Hello Bob, this is a test using the detailed configuration method.\n[Bob] Hi Alice! I'm Bob, and I'll have my own voice settings.\n[Alice] Let's see how this sounds."
104
  example_script_2 = "[Narrator] This is a short story.\n[CharacterA] Once upon a time...\n[Narrator] ...there was a Gradio app.\n[CharacterB] And it could talk!"
105
 
 
 
 
106
  examples_data = [
107
  [example_script_1, "tts-1-hd", 300, "Detailed Configuration (Per Speaker UI)", DEFAULT_GLOBAL_VOICE, {}, 1.0, ""],
108
  [example_script_2, "gpt-4o-mini-tts", 200, "Random per Speaker", DEFAULT_GLOBAL_VOICE, {}, 1.0, "Speak with a gentle, storytelling voice for the narrator."],
109
  ["[Solo] Just one line, using global voice and speed.", "tts-1", 0, "Single Voice (Global)", "fable", {}, 1.2, ""],
110
  ]
111
 
 
112
  num_inputs = len(inputs_for_examples)
113
  valid_examples_data = []
114
  for ex_data in examples_data:
 
119
 
120
  if not valid_examples_data:
121
  gr.Markdown("<p style='color: orange;'>No valid examples could be loaded due to configuration mismatch.</p>")
122
+ return None
123
 
124
+ # If process_fn and outputs_for_examples are provided, make examples runnable
125
+ if process_fn and outputs_for_examples:
126
+ return gr.Examples(
127
+ examples=valid_examples_data,
128
+ inputs=inputs_for_examples,
129
+ outputs=outputs_for_examples,
130
+ fn=process_fn,
131
+ cache_examples=False, # Caching can be complex with external API calls
132
+ examples_per_page=5, # Corrected parameter name
133
+ label="Example Scripts (Click to Load & Run)",
134
+ run_on_click=True # Make examples run when clicked
135
+ )
136
+ else: # Otherwise, just load inputs
137
+ return gr.Examples(
138
+ examples=valid_examples_data,
139
+ inputs=inputs_for_examples,
140
+ examples_per_page=5, # Corrected parameter name
141
+ label="Example Scripts (Click to Load Inputs)",
142
+ # No fn, outputs, or run_on_click if process_fn is None
143
+ )