Patch Notes: UVR WebUI - LocalPatchByGermanized

Comparison Base: webUI.py
Patched Version: webUI(LocalPatchByGermanized).py
Author of Patch: Germanized


I. Core Functionality & Logic Changes

1. Imports

  • Patched: Added import shutil and import wget at the top of the file.
    • Base webUI.py imported wget later in the main script block.

2. Class UVRWebUI - Initialization (__init__)

  • Directory Creation:
    • Base: Only creates self.input_temp_dir using os.mkdir(). Does not create self.export_path.
    • Patched:
      • Creates self.input_temp_dir using os.makedirs(..., exist_ok=True).
      • Creates self.export_path using os.makedirs(..., exist_ok=True).
      • Uses single quotes for directory path strings.

3. Class UVRWebUI - Model URL Fetching (get_models_url)

  • Patched: Minor variable name changes in dictionary comprehension (e.g., model_name vs model, model_filename_part vs model_path). Logic remains identical. Uses single quotes for keys in zip.

4. Class UVRWebUI - Local Model Discovery (get_local_models)

  • Error Handling & Directory Management:
    • Base:
      • Raises ValueError if arch is unknown.
      • Assumes model directories exist; will fail if os.listdir(model_dir) is called on a non-existent path.
      • Returns an unsorted list.
      • Does not check if entries are files (could list subdirectories if they had the suffix).
    • Patched:
      • Prints an error message to console and returns an empty list [] if arch is unknown (instead of raising an exception that stops Gradio).
      • Checks if model_dir exists. If not, creates it using os.makedirs(..., exist_ok=True) and returns an empty list.
      • Includes a secondary check for model_dir existence with a warning.
      • Returns a sorted() list of model names.
      • Filters to ensure entries are files using os.path.isfile().

5. Class UVRWebUI - Architecture Selection Update (arch_select_update)

  • DEMUCS Architecture Handling:
    • Base: If DEMUCS_ARCH_TYPE is selected, raise gr.Error(f"{DEMUCS_ARCH_TYPE} not implempted").
    • Patched:
      • Sets a specific model_update_label for Demucs.
      • Updates arch_setting1 and arch_setting2 to be hidden (visible=False) and clears their choices/values, providing a cleaner UI when Demucs (which might not use these generic settings) is selected.
  • Unknown Architecture Handling:
    • Base: raise gr.Error(f"Unkown arch type: {arch}").
    • Patched: Displays a gr.Error() in the UI and returns default/empty updates for the components to prevent UI breakage.
  • UI Feedback & Labels:
    • Patched:
      • Prints a warning to console if no local models are found for the selected architecture.
      • Uses more specific labels for the model_choice dropdown based on the selected architecture (e.g., SELECT_VR_MODEL_MAIN_LABEL, CHOOSE_MDX_MODEL_MAIN_LABEL).

6. Class UVRWebUI - Model Selection Update (model_select_update)

  • Handling "Choose Model" / Empty Selection:
    • Base: If model_name == CHOOSE_MODEL, returns [None for _ in range(4)].
    • Patched:
      • Handles model_name == CHOOSE_MODEL or model_name is None (more robust).
      • If "Choose Model" is selected, returns specific gr.update() calls to reset the stem-related checkbox and output component labels to their defaults (e.g., PRIMARY_STEM only).
  • Model Data Assembly:
    • Base: model, = self.uvr.assemble_model_data(...) (assumes the method returns a list/tuple with exactly one item).
    • Patched: model_data_list = self.uvr.assemble_model_data(...), then checks if not model_data_list: gr.Error(...), then model = model_data_list[0]. More robust to empty returns.
  • Error Handling:
    • Base: Raises gr.Error if model.model_status is false.
    • Patched: Displays gr.Error if model_data_list is empty or model.model_status is false, returning [None for _ in range(4)].

7. Class UVRWebUI - Exclusive Checkbox Logic (set_checkboxes_exclusive vs. Direct Handlers)

  • Major Change:
    • Base: Implements a set_checkboxes_exclusive method which tries to manage exclusivity by passing all checkbox states to a handler. The logic within new_onchange and how callback_i interacts with root variables for all checkboxes might not be perfectly aligned with Gradio's update model for ensuring all root variables are correctly set.
    • Patched:
      • The set_checkboxes_exclusive method, while defined, is not called in define_layout.
      • Instead, two dedicated handler functions (make_exclusive_primary and make_exclusive_secondary) are defined within define_layout.
      • These handlers are directly assigned to the .change events of self.primary_stem_only and self.secondary_stem_only respectively.
      • This approach is more typical for Gradio and directly updates the root variables and the other checkbox state.

8. Class UVRWebUI - Processing Logic (process)

  • Gradio Progress:
    • Base: progress=gr.Progress(). set_progress_func calls progress(progress_curr).
    • Patched: progress=gr.Progress(track_tqdm=True). set_progress_func is a pass statement (actual progress likely handled by track_tqdm if backend uses tqdm).
  • Input Audio Handling & Normalization:
    • Base:
      • audio = (audio / np.iinfo(audio.dtype).max).astype(np.float32) (assumes integer input, could error on float).
      • if len(audio.shape) > 1: audio = librosa.to_mono(audio.transpose(1, 0)) (transposes then converts to mono).
    • Patched:
      • More robust normalization: checks np.issubdtype(audio_data.dtype, np.integer) then normalizes. Also checks np.issubdtype(audio_data.dtype, np.floating) and raises an error for unsupported types.
      • More robust mono conversion: Heuristic check for channel-first (audio_data.shape[0] > 5) before transposing, then converts to mono.
  • Input Filename Handling:
    • Base: Directly uses input_filename to form input_path.
    • Patched:
      • Provides a default input_filename if empty ('audio_input.wav').
      • Appends .wav extension if the provided filename doesn't have a common audio extension.
      • Uses os.path.basename(input_filename) when creating input_path for safety.
  • Temporary File Writing:
    • Base: soundfile.write(...) directly.
    • Patched: soundfile.write(...) is wrapped in a try-except block to catch errors.
  • Separator Object & Output Paths:
    • Base: Typo seperator = uvr.process(...). Assumes seperator object and its attributes are always valid when constructing output paths. No explicit checks for file existence before reading output stems.
    • Patched:
      • Correct spelling: separator = self.uvr.process(...).
      • Checks if separator is None: after processing and returns an error message.
      • Before constructing output paths, checks if separator.export_path, separator.audio_file_base, and separator.primary_stem/secondary_stem are not None.
      • Checks if os.path.exists(...) for primary/secondary stem WAV files before attempting to read them with soundfile.read().
      • Appends specific error messages to the msg string if files are not found or separator data is missing.
  • Return Value:
    • Base & Patched: Both return a 3-tuple. Patched version uses explicit parentheses (primary_audio_out, secondary_audio_out, msg.strip()).

II. User Interface (UI) - define_layout Method

1. Main Application Title

  • Base: gr.HTML("<h1> 🎵 Ultimate Vocal Remover WebUI 🎵 </h1>")
  • Patched: gr.HTML('<h1> 🎵 Ultimate Vocal Remover WebUI Local Patch By Germanized🎵 </h1>') (Title changed, single quotes)

2. Arch Choice Dropdown (self.arch_choice)

  • Base: Comment indicates DEMUCS_ARCH_TYPE was considered but choices=[VR_ARCH_TYPE, MDX_ARCH_TYPE] is active.
  • Patched: choices=[VR_ARCH_TYPE, MDX_ARCH_TYPE]. (Functionally same as base's active choices).

3. Input Filename Textbox (self.input_filename)

  • Base: label="Input filename"
  • Patched: label="Input filename (e.g., song.wav)" (More descriptive)

4. Input Audio Component (self.audio_in)

  • Base: gr.Audio(label="Input audio", interactive=True)
  • Patched: gr.Audio(label="Input audio", type="numpy", interactive=True) (Specifies type="numpy")

5. Output Message Textbox (self.out_message)

  • Base: show_progress=False explicitly set.
  • Patched: show_progress attribute removed (Gradio's default behavior applies).

6. "Settings" Tab

  • "Settings Guide" Tab Name:
    • Base: "Settings Guide"
    • Patched: "Settings Guide (Placeholder)"
  • "Additional Settings" Tab Name & Content:
    • Base: Tab name "Additional Settigns" (typo). wav_type label: "Wav Type". mp3_rate label: "MP3 Bitrate".
    • Patched: Tab name "Additional Settings" (corrected). wav_type label: "Wav Type Output". mp3_rate label: "MP3 Bitrate Output".
  • "Download models" Tab:
    • md_url Helper Function:
      • Base: return f"[{url}]({url})"
      • Patched: return f"[{text}]({url})" (allows different display text for the Markdown link).
    • Row Variants:
      • Base: Uses gr.Row(variant="panel") for MDX and Demucs model download sections.
      • Patched: variant="panel" attribute removed from these rows.
    • Dropdown Change Lambdas for URL Display:
      • Base: e.g., lambda model: md_url(vr_models[model]). This would fail if model is not in vr_models or if model is None.
      • Patched: e.g., lambda model: md_url(vr_models_for_dl.get(model, "URL not found")) if model else "". More robust: uses .get() for safe dictionary access, provides a default "URL not found", and handles the case where model is None (e.g., dropdown cleared) by returning an empty string. Similar robustness added for MDX and Demucs.
    • Demucs URL Display:
      • Patched: Safely accesses items from demucs_models_for_dl.get(model, {}).items() to prevent errors if a model has no downloadable files listed.

7. Exclusive Checkbox Event Handling (in define_layout)

  • Base:
    self.set_checkboxes_exclusive(
        [self.primary_stem_only, self.secondary_stem_only],
        [lambda value: root.is_primary_stem_only_var.set(value), lambda value: root.is_secondary_stem_only_var.set(value)])
    
  • Patched: (As detailed in Core Functionality section 7)
    def make_exclusive_primary(is_checked_primary): # ... logic ...
    def make_exclusive_secondary(is_checked_secondary): # ... logic ...
    
    self.primary_stem_only.change(make_exclusive_primary, inputs=self.primary_stem_only, outputs=[self.primary_stem_only, self.secondary_stem_only])
    self.secondary_stem_only.change(make_exclusive_secondary, inputs=self.secondary_stem_only, outputs=[self.primary_stem_only, self.secondary_stem_only])
    
    This is a fundamental change to a more standard and reliable Gradio pattern for exclusive checkboxes.

III. Main Script Execution Block (Outside Class)

1. Variable Names

  • Base: uvr, webui.
  • Patched: uvr_interface_instance, webui_instance.

2. Model Download Logic

  • Complete Overhaul:
    • Base:
      • Prints webui.models_url.
      • Imports os and wget locally within this block.
      • Iterates using hardcoded category names ('VR Arc', 'MDX-Net') and hardcoded paths ('models/VR_Models', 'models/MDX_Net_Models').
      • Does not create these model directories.
      • Constructs and executes aria2c command line calls using os.system() for downloads.
      • Explicitly ignores other categories (like Demucs) for this download method.
    • Patched:
      • Prints "INFO: Checking and downloading models if necessary...".
      • Uses VR_ARCH_TYPE, MDX_ARCH_TYPE, DEMUCS_ARCH_TYPE constants and corresponding *_MODELS_DIR constants.
      • Creates target_model_dir if it doesn't exist using os.makedirs(..., exist_ok=True).
      • Skips DEMUCS_ARCH_TYPE in this specific loop (notes it might be handled elsewhere or differently).
      • Determines expected local filename and path with correct suffix.
      • Uses Python's wget.download(model_full_url, out=target_model_dir) for downloading.
      • Compares downloaded filename with expected filename and uses shutil.move() to rename if necessary, ensuring the file is saved with the name expected by get_local_models.
      • Includes more detailed INFO/ERROR print statements during download.

3. WebUI Re-initialization after Downloads

  • Base: webui = UVRWebUI(uvr, online_data_path='models/download_checks.json') (Second instantiation).
  • Patched:
    • print("INFO: Re-initializing WebUI to pick up downloaded models for dropdowns...")
    • webui_instance = UVRWebUI(uvr_interface_instance, online_data_path='models/download_checks.json') (Second instantiation of webui_instance).
    • Note on Patched Script's Structure: The patched file has an additional (likely ineffective) attempt to update webui_instance.model_choice.choices before this final re-initialization, operating on the first instance of webui_instance. The crucial part for UI display is this second, final instantiation.

4. Code Style (Throughout the Patched File)

  • Consistent use of single quotes ('...') for string literals.
  • More explicit parentheses for tuples in return statements.

IV. Summary of Changes by Germanized

The "LocalPatchByGermanized" version introduces substantial improvements over the provided base webUI.py:

  • Greatly Enhanced Robustness: Improved error handling in model loading, processing, file operations, and UI updates. UI is less likely to break from unexpected conditions.
  • Modernized Model Downloading: Replaced aria2c CLI calls with a Python-native wget and shutil implementation, including better directory/filename management and error feedback.
  • Improved User Experience (UI & Feedback):
    • More descriptive labels and messages.
    • Better handling of Demucs architecture selection in the UI (hiding irrelevant settings).
    • Clearer feedback during model downloads and processing.
    • Corrected typos in UI text.
  • Refined UI Component Behavior: More standard and reliable implementation for exclusive checkboxes. Safer handling of dropdown changes in the "Download models" tab.
  • Code Maintainability: More consistent use of constants, better directory management practices.
  • Branding: Updated UI title to reflect the "Local Patch By Germanized".

Overall, the patched script is a significant step up in terms of stability, usability, and code quality.

Germanized changed pull request title from This (PATCH) replaced your kind of not so the best download logic with better logic and automatic downloading of models thats faster and more visual progress to UVRWUI Local (PATCH)
Ready to merge
This branch is ready to get merged automatically.

Sign up or log in to comment