Surn commited on
Commit
0790175
·
1 Parent(s): 0c47e86

Allow Melody in MCP call

Browse files
Files changed (3) hide show
  1. app.py +13 -4
  2. modules/file_utils.py +33 -0
  3. requirements.txt +3 -1
app.py CHANGED
@@ -33,7 +33,7 @@ import librosa
33
  import modules.user_history
34
  from modules.version_info import versions_html, commit_hash, get_xformers_version
35
  from modules.gradio import *
36
- from modules.file_utils import get_file_parts, get_filename_from_filepath, convert_title_to_filename, get_unique_file_path, delete_file, download_and_save_image
37
  from modules.constants import IS_SHARED_SPACE, HF_REPO_ID, TMPDIR, HF_API_TOKEN
38
  from modules.storage import upload_files_to_repo
39
 
@@ -294,11 +294,17 @@ def predict(model, text, melody_filepath = None, duration=10, dimension=2, topk=
294
  if melody_filepath in ["None", ""]:
295
  melody_filepath = None
296
 
 
 
 
 
 
 
297
  #if background is a url string, download it using download_and_save_image
298
  if background is None or background in ["None", ""]:
299
  background = load_background_filepath(video_orientation)
300
 
301
- if background.startswith("http://") or background.startswith("https://"):
302
  username = profile if isinstance(profile, str) else profile.value.username if hasattr(profile.value, 'username') else "default_user" if (profile is None) else profile
303
  background = download_and_save_image(background, Path(TMPDIR) / str(username), HF_API_TOKEN)
304
 
@@ -615,13 +621,14 @@ def fix_path(path: str) -> str:
615
  return "./" + path[index:].replace("\\", "/")
616
  return path
617
  # Add this wrapper function above the gr.api definitions
618
- def predict_simple(model: str, text: str, duration: int = 10, dimension: int = 2, topk: int = 200, topp: float = 0.01, temperature: float = 1.0, cfg_coef: float = 4.0, background: str = "./assets/background.png", title: str = "UnlimitedMusicGen", settings_font: str = "./assets/arial.ttf", settings_font_color: str = "#c87f05", seed: int = -1, overlap: int = 1, prompt_index: int = -1, include_title: bool = True, include_settings: bool = True, profile: str = "Satoshi Nakamoto", segment_length: int = 30, settings_font_size: int = 28, settings_animate_waveform: bool = False, video_orientation: str = "Landscape", return_history_json: bool = False) -> tp.List[tp.Tuple[str, str, str]]:
619
  """
620
  Generate music and video based on the provided parameters and model.
621
 
622
  Args:
623
  model (str): Model name to use for generation.
624
  text (str): Prompt describing the music.
 
625
  duration (int): Total duration in seconds.
626
  dimension (int): Audio stacking/concatenation dimension.
627
  topk (int): Top-k sampling value.
@@ -637,6 +644,7 @@ def predict_simple(model: str, text: str, duration: int = 10, dimension: int = 2
637
  prompt_index (int, optional): Melody segment index. Default to -1.
638
  include_title (bool, optional): Whether to add title to video. Default to True.
639
  include_settings (bool, optional): Whether to add settings to video. Default to True.
 
640
  profile (str, optional): User profile.
641
  segment_length (int, optional): Segment length in seconds.
642
  settings_font_size (int, optional): Font size for settings text.
@@ -664,7 +672,7 @@ def predict_simple(model: str, text: str, duration: int = 10, dimension: int = 2
664
  elif isinstance(actual_profile_data, str) and actual_profile_data: # string username
665
  profile_username_to_send = actual_profile_data
666
 
667
- UMG_result = predict(model, text, melody_filepath=None, duration=duration, dimension=dimension, topk=topk, topp=topp, temperature=temperature, cfg_coef=cfg_coef, background=background, title=title, settings_font=settings_font, settings_font_color=settings_font_color, seed=seed, overlap=overlap, prompt_index=prompt_index, include_title=include_title, include_settings=include_settings, harmony_only=False, profile=profile, segment_length=segment_length, settings_font_size=settings_font_size, settings_animate_waveform=settings_animate_waveform, video_orientation=video_orientation, excerpt_duration=3.5, return_history_json=return_history_json)
668
 
669
  # upload to storage and return urls
670
  folder_name = f"user_uploads/{convert_title_to_filename(profile_username_to_send)}/{convert_title_to_filename(title)}"
@@ -868,6 +876,7 @@ def ui(**kwargs):
868
  launch_kwargs['allowed_paths'] = ["assets", "./assets", "images", "./images", 'e:/TMP']
869
  launch_kwargs['favicon_path'] = "./assets/favicon.ico"
870
  launch_kwargs['mcp_server'] = True
 
871
 
872
  gr.api(ping, api_name="ping")
873
  gr.api(predict_simple)
 
33
  import modules.user_history
34
  from modules.version_info import versions_html, commit_hash, get_xformers_version
35
  from modules.gradio import *
36
+ from modules.file_utils import get_file_parts, get_filename_from_filepath, convert_title_to_filename, get_unique_file_path, delete_file, download_and_save_image, download_and_save_file
37
  from modules.constants import IS_SHARED_SPACE, HF_REPO_ID, TMPDIR, HF_API_TOKEN
38
  from modules.storage import upload_files_to_repo
39
 
 
294
  if melody_filepath in ["None", ""]:
295
  melody_filepath = None
296
 
297
+
298
+ # if melody_filepath is a url string, download it using download_and_save_file
299
+ if melody_filepath and melody_filepath.startswith(("http://", "https://")):
300
+ username = profile if isinstance(profile, str) else profile.value.username if hasattr(profile.value, 'username') else "default_user" if (profile is None) else profile
301
+ melody_filepath = download_and_save_file(melody_filepath, Path(TMPDIR) / str(username), HF_API_TOKEN)
302
+
303
  #if background is a url string, download it using download_and_save_image
304
  if background is None or background in ["None", ""]:
305
  background = load_background_filepath(video_orientation)
306
 
307
+ if background.startswith(("http://", "https://")):
308
  username = profile if isinstance(profile, str) else profile.value.username if hasattr(profile.value, 'username') else "default_user" if (profile is None) else profile
309
  background = download_and_save_image(background, Path(TMPDIR) / str(username), HF_API_TOKEN)
310
 
 
621
  return "./" + path[index:].replace("\\", "/")
622
  return path
623
  # Add this wrapper function above the gr.api definitions
624
+ def predict_simple(model: str, text: str, melody_filepath: str = None, duration: int = 10, dimension: int = 2, topk: int = 200, topp: float = 0.01, temperature: float = 1.0, cfg_coef: float = 4.0, background: str = "./assets/background.png", title: str = "UnlimitedMusicGen", settings_font: str = "./assets/arial.ttf", settings_font_color: str = "#c87f05", seed: int = -1, overlap: int = 1, prompt_index: int = -1, include_title: bool = True, include_settings: bool = True, harmony_only: bool = False, profile: str = "Satoshi Nakamoto", segment_length: int = 30, settings_font_size: int = 28, settings_animate_waveform: bool = False, video_orientation: str = "Landscape", return_history_json: bool = False) -> tp.List[tp.Tuple[str, str, str]]:
625
  """
626
  Generate music and video based on the provided parameters and model.
627
 
628
  Args:
629
  model (str): Model name to use for generation.
630
  text (str): Prompt describing the music.
631
+ melody_filepath (str, optional): Path to melody conditioning file. Default to None.
632
  duration (int): Total duration in seconds.
633
  dimension (int): Audio stacking/concatenation dimension.
634
  topk (int): Top-k sampling value.
 
644
  prompt_index (int, optional): Melody segment index. Default to -1.
645
  include_title (bool, optional): Whether to add title to video. Default to True.
646
  include_settings (bool, optional): Whether to add settings to video. Default to True.
647
+ harmony_only (bool, optional): Whether to use harmony only. Default to False.
648
  profile (str, optional): User profile.
649
  segment_length (int, optional): Segment length in seconds.
650
  settings_font_size (int, optional): Font size for settings text.
 
672
  elif isinstance(actual_profile_data, str) and actual_profile_data: # string username
673
  profile_username_to_send = actual_profile_data
674
 
675
+ UMG_result = predict(model, text, melody_filepath=melody_filepath, duration=duration, dimension=dimension, topk=topk, topp=topp, temperature=temperature, cfg_coef=cfg_coef, background=background, title=title, settings_font=settings_font, settings_font_color=settings_font_color, seed=seed, overlap=overlap, prompt_index=prompt_index, include_title=include_title, include_settings=include_settings, harmony_only=harmony_only, profile=profile, segment_length=segment_length, settings_font_size=settings_font_size, settings_animate_waveform=settings_animate_waveform, video_orientation=video_orientation, excerpt_duration=3.5, return_history_json=return_history_json)
676
 
677
  # upload to storage and return urls
678
  folder_name = f"user_uploads/{convert_title_to_filename(profile_username_to_send)}/{convert_title_to_filename(title)}"
 
876
  launch_kwargs['allowed_paths'] = ["assets", "./assets", "images", "./images", 'e:/TMP']
877
  launch_kwargs['favicon_path'] = "./assets/favicon.ico"
878
  launch_kwargs['mcp_server'] = True
879
+ launch_kwargs['ssr_mode'] = False
880
 
881
  gr.api(ping, api_name="ping")
882
  gr.api(predict_simple)
modules/file_utils.py CHANGED
@@ -153,4 +153,37 @@ def download_and_save_image(url: str, dst_folder: Path, token: str = None) -> Pa
153
  dst = Path(unique_filepath_str)
154
  dst_folder.mkdir(parents=True, exist_ok=True)
155
  pil_image.save(dst)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  return dst
 
153
  dst = Path(unique_filepath_str)
154
  dst_folder.mkdir(parents=True, exist_ok=True)
155
  pil_image.save(dst)
156
+ return dst
157
+
158
+ def download_and_save_file(url: str, dst_folder: Path, token: str = None) -> Path:
159
+ """
160
+ Downloads a binary file (e.g., audio or video) from a URL with authentication if a token is provided,
161
+ and saves it in dst_folder with a unique filename.
162
+
163
+ Args:
164
+ url (str): The file URL.
165
+ dst_folder (Path): The destination folder for the file.
166
+ token (str, optional): A valid Bearer token.
167
+
168
+ Returns:
169
+ Path: The saved file's path.
170
+ """
171
+ headers = {}
172
+ if token:
173
+ headers["Authorization"] = f"Bearer {token}"
174
+
175
+ response = requests.get(url, headers=headers)
176
+ response.raise_for_status()
177
+
178
+ parsed_url = urlparse(url)
179
+ original_filename = os.path.basename(parsed_url.path)
180
+ base, ext = os.path.splitext(original_filename)
181
+
182
+ unique_filepath_str = get_unique_file_path(str(dst_folder), base, ext)
183
+ dst = Path(unique_filepath_str)
184
+ dst_folder.mkdir(parents=True, exist_ok=True)
185
+
186
+ with open(dst, "wb") as f:
187
+ f.write(response.content)
188
+
189
  return dst
requirements.txt CHANGED
@@ -38,4 +38,6 @@ spacy==3.7.6
38
  sentencepiece
39
  num2words
40
  numpy<1.26.4
41
- matplotlib
 
 
 
38
  sentencepiece
39
  num2words
40
  numpy<1.26.4
41
+ matplotlib
42
+ fastapi>=0.115.0
43
+ starlette>=0.40.0