r3gm commited on
Commit
fb1dec2
·
verified ·
1 Parent(s): b2b2815

Update and #26

Browse files
Files changed (1) hide show
  1. app.py +111 -36
app.py CHANGED
@@ -29,9 +29,11 @@ import sys
29
  import torch
30
  import fairseq
31
  from picklescan.scanner import scan_file_path
 
32
 
33
 
34
  ALLOWED_DOMAINS = {"huggingface.co", "hf.co"}
 
35
 
36
  parser = argparse.ArgumentParser(description="Run the app with optional sharing")
37
  parser.add_argument(
@@ -109,6 +111,14 @@ def check_model_safety(file_path: str):
109
  print(f"Integrity check skipped for {file_path}: {e}")
110
 
111
 
 
 
 
 
 
 
 
 
112
  async def get_voices_list(proxy=None):
113
  """Print all available voices."""
114
  from edge_tts import list_voices
@@ -156,6 +166,26 @@ def find_my_model(a_, b_):
156
  check_model_safety(a_)
157
  return a_, b_
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  txt_files = []
160
  for base_file in [a_, b_]:
161
  if base_file is not None and base_file.endswith(".txt"):
@@ -200,6 +230,9 @@ def find_my_model(a_, b_):
200
  if not index:
201
  gr.Warning("Index not found")
202
 
 
 
 
203
  return model, index
204
 
205
 
@@ -471,7 +504,6 @@ def run(
471
  audio_effects,
472
  type_output,
473
  steps,
474
- play_audio=False,
475
  ):
476
  if not audio_files:
477
  raise ValueError("The audio pls")
@@ -487,7 +519,7 @@ def run(
487
 
488
  if file_m is not None and (file_m.endswith(".txt") or file_m.endswith(".zip")):
489
  file_m, file_index = find_my_model(file_m, file_index)
490
- print(file_m, file_index)
491
 
492
  random_tag = "USER_"+str(random.randint(10000000, 99999999))
493
 
@@ -513,9 +545,37 @@ def run(
513
  if audio_effects:
514
  result = add_audio_effects(result, type_output)
515
 
516
- player_audio = result[0] if (play_audio and result and len(result) > 0) else None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517
 
518
- return result, player_audio
 
 
 
 
 
 
 
519
 
520
 
521
  def audio_conf():
@@ -623,15 +683,6 @@ def output_conf():
623
  )
624
 
625
 
626
- def active_tts_conf():
627
- return gr.Checkbox(
628
- False,
629
- label="TTS",
630
- # info="",
631
- container=False,
632
- )
633
-
634
-
635
  def tts_voice_conf():
636
  return gr.Dropdown(
637
  label="tts voice",
@@ -730,16 +781,21 @@ def infer_tts_audio(tts_voice, tts_text, play_audio):
730
  return [out_path], player_audio
731
 
732
 
733
- def show_components_tts(value_active):
734
- return gr.update(
735
- visible=value_active
736
- ), gr.update(
737
- visible=value_active
738
- ), gr.update(
739
- visible=value_active
740
  )
741
 
742
 
 
 
 
 
 
 
743
  def down_active_conf():
744
  return gr.Checkbox(
745
  False,
@@ -787,7 +843,7 @@ def get_gui(theme):
787
  gr.Markdown(title)
788
  gr.Markdown(description)
789
 
790
- active_tts = active_tts_conf()
791
  with gr.Row():
792
  with gr.Column(scale=1):
793
  tts_text = tts_text_conf()
@@ -799,15 +855,22 @@ def get_gui(theme):
799
 
800
  tts_button = tts_button_conf()
801
 
802
- active_tts.change(
803
- fn=show_components_tts,
804
- inputs=[active_tts],
805
- outputs=[tts_voice, tts_text, tts_button],
806
- )
807
-
808
  aud = audio_conf()
809
  # gr.HTML("<hr>")
810
 
 
 
 
 
 
 
 
 
 
 
 
 
811
  down_active_gui = down_active_conf()
812
  down_info = gr.Markdown(
813
  f"Provide a link to a zip file, like this one: `https://huggingface.co/MrDawg/ToothBrushing/resolve/main/ToothBrushing.zip?download=true`, or separate links with a comma for the .pth and .index files, like this: `{test_model}`",
@@ -885,9 +948,17 @@ def get_gui(theme):
885
  effects_gui,
886
  format_out,
887
  steps_gui,
888
- player_gui,
889
  ],
890
- outputs=[output_base, player_audio],
 
 
 
 
 
 
 
 
 
891
  )
892
 
893
  gr.Examples(
@@ -939,7 +1010,7 @@ def get_gui(theme):
939
  envel_r,
940
  const,
941
  ],
942
- outputs=[output_base, player_audio],
943
  cache_examples=False,
944
  )
945
  gr.Markdown(RESOURCES)
@@ -948,12 +1019,16 @@ def get_gui(theme):
948
 
949
 
950
  if __name__ == "__main__":
951
- tts_voice_list = asyncio.new_event_loop().run_until_complete(get_voices_list(proxy=None))
952
- voices = sorted([
953
- (" - ".join(reversed(v["FriendlyName"].split("-"))).replace("Microsoft ", "").replace("Online (Natural)", f"({v['Gender']})").strip(), f"{v['ShortName']}-{v['Gender']}")
954
- for v in tts_voice_list
955
- ])
956
-
 
 
 
 
957
  app = get_gui(theme)
958
 
959
  app.queue(default_concurrency_limit=40)
 
29
  import torch
30
  import fairseq
31
  from picklescan.scanner import scan_file_path
32
+ import hashlib
33
 
34
 
35
  ALLOWED_DOMAINS = {"huggingface.co", "hf.co"}
36
+ MODEL_CACHE = {}
37
 
38
  parser = argparse.ArgumentParser(description="Run the app with optional sharing")
39
  parser.add_argument(
 
111
  print(f"Integrity check skipped for {file_path}: {e}")
112
 
113
 
114
+ def get_file_hash(file_path: str) -> str:
115
+ hasher = hashlib.sha256()
116
+ with open(file_path, "rb") as f:
117
+ while chunk := f.read(65536):
118
+ hasher.update(chunk)
119
+ return hasher.hexdigest()
120
+
121
+
122
  async def get_voices_list(proxy=None):
123
  """Print all available voices."""
124
  from edge_tts import list_voices
 
166
  check_model_safety(a_)
167
  return a_, b_
168
 
169
+ input_hash = None
170
+ if a_ and os.path.exists(a_):
171
+ input_hash = get_file_hash(a_)
172
+ if b_ and os.path.exists(b_):
173
+ input_hash += "_" + get_file_hash(b_)
174
+
175
+ if input_hash and input_hash in MODEL_CACHE:
176
+ cached_model, cached_index = MODEL_CACHE[input_hash]
177
+ model_exists = cached_model and os.path.exists(cached_model)
178
+ index_exists = (cached_index is None) or os.path.exists(cached_index)
179
+
180
+ if model_exists and index_exists:
181
+ check_model_safety(cached_model)
182
+ gr.Info(f"Model found: {cached_model}")
183
+ if cached_index:
184
+ gr.Info(f"Index found: {cached_index}")
185
+ return cached_model, cached_index
186
+ else:
187
+ del MODEL_CACHE[input_hash]
188
+
189
  txt_files = []
190
  for base_file in [a_, b_]:
191
  if base_file is not None and base_file.endswith(".txt"):
 
230
  if not index:
231
  gr.Warning("Index not found")
232
 
233
+ if model and input_hash:
234
+ MODEL_CACHE[input_hash] = (model, index)
235
+
236
  return model, index
237
 
238
 
 
504
  audio_effects,
505
  type_output,
506
  steps,
 
507
  ):
508
  if not audio_files:
509
  raise ValueError("The audio pls")
 
519
 
520
  if file_m is not None and (file_m.endswith(".txt") or file_m.endswith(".zip")):
521
  file_m, file_index = find_my_model(file_m, file_index)
522
+ # print(file_m, file_index)
523
 
524
  random_tag = "USER_"+str(random.randint(10000000, 99999999))
525
 
 
545
  if audio_effects:
546
  result = add_audio_effects(result, type_output)
547
 
548
+ return result
549
+
550
+
551
+ def clear_player():
552
+ return None
553
+
554
+
555
+ def load_first_audio(output_files, play_audio):
556
+ if not play_audio or not output_files:
557
+ return None
558
+ first_file = output_files[0]
559
+ if isinstance(first_file, dict):
560
+ first_file = first_file.get("name")
561
+ return first_file
562
+
563
+
564
+ def audio_source_conf():
565
+ return gr.Radio(
566
+ choices=["📁 Upload", "🗣️ TTS", "🎙️ Record"],
567
+ value="📁 Upload",
568
+ label="Audio Source",
569
+ )
570
 
571
+
572
+ def mic_conf():
573
+ return gr.Audio(
574
+ sources=["microphone"],
575
+ type="filepath",
576
+ label="Record Audio",
577
+ visible=False,
578
+ )
579
 
580
 
581
  def audio_conf():
 
683
  )
684
 
685
 
 
 
 
 
 
 
 
 
 
686
  def tts_voice_conf():
687
  return gr.Dropdown(
688
  label="tts voice",
 
781
  return [out_path], player_audio
782
 
783
 
784
+ def show_components_source(mode):
785
+ return (
786
+ gr.update(visible=(mode == "🗣️ TTS")),
787
+ gr.update(visible=(mode == "🗣️ TTS")),
788
+ gr.update(visible=(mode == "🗣️ TTS")),
789
+ gr.update(visible=(mode == "🎙️ Record")),
 
790
  )
791
 
792
 
793
+ def sync_mic_audio(mic_path):
794
+ if not mic_path:
795
+ return None
796
+ return [mic_path]
797
+
798
+
799
  def down_active_conf():
800
  return gr.Checkbox(
801
  False,
 
843
  gr.Markdown(title)
844
  gr.Markdown(description)
845
 
846
+ audio_source = audio_source_conf()
847
  with gr.Row():
848
  with gr.Column(scale=1):
849
  tts_text = tts_text_conf()
 
855
 
856
  tts_button = tts_button_conf()
857
 
858
+ mic_aud = mic_conf()
 
 
 
 
 
859
  aud = audio_conf()
860
  # gr.HTML("<hr>")
861
 
862
+ audio_source.change(
863
+ fn=show_components_source,
864
+ inputs=[audio_source],
865
+ outputs=[tts_voice, tts_text, tts_button, mic_aud],
866
+ )
867
+
868
+ mic_aud.change(
869
+ fn=sync_mic_audio,
870
+ inputs=[mic_aud],
871
+ outputs=[aud],
872
+ )
873
+
874
  down_active_gui = down_active_conf()
875
  down_info = gr.Markdown(
876
  f"Provide a link to a zip file, like this one: `https://huggingface.co/MrDawg/ToothBrushing/resolve/main/ToothBrushing.zip?download=true`, or separate links with a comma for the .pth and .index files, like this: `{test_model}`",
 
948
  effects_gui,
949
  format_out,
950
  steps_gui,
 
951
  ],
952
+ outputs=[output_base],
953
+ ).success(
954
+ clear_player,
955
+ inputs=None,
956
+ outputs=[player_audio],
957
+ queue=False,
958
+ ).success(
959
+ load_first_audio,
960
+ inputs=[output_base, player_gui],
961
+ outputs=[player_audio],
962
  )
963
 
964
  gr.Examples(
 
1010
  envel_r,
1011
  const,
1012
  ],
1013
+ outputs=[output_base],
1014
  cache_examples=False,
1015
  )
1016
  gr.Markdown(RESOURCES)
 
1019
 
1020
 
1021
  if __name__ == "__main__":
1022
+ try:
1023
+ tts_voice_list = asyncio.new_event_loop().run_until_complete(get_voices_list(proxy=None))
1024
+ voices = sorted([
1025
+ (" - ".join(reversed(v["FriendlyName"].split("-"))).replace("Microsoft ", "").replace("Online (Natural)", f"({v['Gender']})").strip(), f"{v['ShortName']}-{v['Gender']}")
1026
+ for v in tts_voice_list
1027
+ ])
1028
+ except Exception as e:
1029
+ print(f"Warning: Could not retrieve online voices ({e}). Using default preset.")
1030
+ voices = [("English (United States) - EmmaMultilingual (Female)", "en-US-EmmaMultilingualNeural-Female")]
1031
+
1032
  app = get_gui(theme)
1033
 
1034
  app.queue(default_concurrency_limit=40)