UVRWUI Local (PATCH)
#11
by
Germanized
- opened
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
andimport wget
at the top of the file.- Base
webUI.py
importedwget
later in the main script block.
- Base
2. Class UVRWebUI
- Initialization (__init__
)
- Directory Creation:
- Base: Only creates
self.input_temp_dir
usingos.mkdir()
. Does not createself.export_path
. - Patched:
- Creates
self.input_temp_dir
usingos.makedirs(..., exist_ok=True)
. - Creates
self.export_path
usingos.makedirs(..., exist_ok=True)
. - Uses single quotes for directory path strings.
- Creates
- Base: Only creates
3. Class UVRWebUI
- Model URL Fetching (get_models_url
)
- Patched: Minor variable name changes in dictionary comprehension (e.g.,
model_name
vsmodel
,model_filename_part
vsmodel_path
). Logic remains identical. Uses single quotes for keys inzip
.
4. Class UVRWebUI
- Local Model Discovery (get_local_models
)
- Error Handling & Directory Management:
- Base:
- Raises
ValueError
ifarch
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).
- Raises
- Patched:
- Prints an error message to console and returns an empty list
[]
ifarch
is unknown (instead of raising an exception that stops Gradio). - Checks if
model_dir
exists. If not, creates it usingos.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()
.
- Prints an error message to console and returns an empty list
- Base:
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
andarch_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.
- Sets a specific
- Base: If
- 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.
- Base:
- 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
).
- Patched:
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
ormodel_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
).
- Handles
- Base: If
- 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 checksif not model_data_list: gr.Error(...)
, thenmodel = model_data_list[0]
. More robust to empty returns.
- Base:
- Error Handling:
- Base: Raises
gr.Error
ifmodel.model_status
is false. - Patched: Displays
gr.Error
ifmodel_data_list
is empty ormodel.model_status
is false, returning[None for _ in range(4)]
.
- Base: Raises
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 withinnew_onchange
and howcallback_i
interacts withroot
variables for all checkboxes might not be perfectly aligned with Gradio's update model for ensuring allroot
variables are correctly set. - Patched:
- The
set_checkboxes_exclusive
method, while defined, is not called indefine_layout
. - Instead, two dedicated handler functions (
make_exclusive_primary
andmake_exclusive_secondary
) are defined withindefine_layout
. - These handlers are directly assigned to the
.change
events ofself.primary_stem_only
andself.secondary_stem_only
respectively. - This approach is more typical for Gradio and directly updates the
root
variables and the other checkbox state.
- The
- Base: Implements a
8. Class UVRWebUI
- Processing Logic (process
)
- Gradio Progress:
- Base:
progress=gr.Progress()
.set_progress_func
callsprogress(progress_curr)
. - Patched:
progress=gr.Progress(track_tqdm=True)
.set_progress_func
is apass
statement (actual progress likely handled bytrack_tqdm
if backend uses tqdm).
- Base:
- 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 checksnp.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.
- More robust normalization: checks
- Base:
- Input Filename Handling:
- Base: Directly uses
input_filename
to forminput_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 creatinginput_path
for safety.
- Provides a default
- Base: Directly uses
- Temporary File Writing:
- Base:
soundfile.write(...)
directly. - Patched:
soundfile.write(...)
is wrapped in atry-except
block to catch errors.
- Base:
- Separator Object & Output Paths:
- Base: Typo
seperator = uvr.process(...)
. Assumesseperator
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
, andseparator.primary_stem
/secondary_stem
are notNone
. - Checks
if os.path.exists(...)
for primary/secondary stem WAV files before attempting to read them withsoundfile.read()
. - Appends specific error messages to the
msg
string if files are not found or separator data is missing.
- Correct spelling:
- Base: Typo
- Return Value:
- Base & Patched: Both return a 3-tuple. Patched version uses explicit parentheses
(primary_audio_out, secondary_audio_out, msg.strip())
.
- Base & Patched: Both return a 3-tuple. Patched version uses explicit parentheses
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 butchoices=[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)
(Specifiestype="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)"
- Base:
- "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"
.
- Base: Tab name
- "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).
- Base:
- Row Variants:
- Base: Uses
gr.Row(variant="panel")
for MDX and Demucs model download sections. - Patched:
variant="panel"
attribute removed from these rows.
- Base: Uses
- Dropdown Change Lambdas for URL Display:
- Base: e.g.,
lambda model: md_url(vr_models[model])
. This would fail ifmodel
is not invr_models
or ifmodel
isNone
. - 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 wheremodel
isNone
(e.g., dropdown cleared) by returning an empty string. Similar robustness added for MDX and Demucs.
- Base: e.g.,
- 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.
- Patched: Safely accesses items from
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)
This is a fundamental change to a more standard and reliable Gradio pattern for exclusive checkboxes.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])
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
andwget
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 usingos.system()
for downloads. - Explicitly ignores other categories (like Demucs) for this download method.
- Prints
- 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 usingos.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 byget_local_models
. - Includes more detailed INFO/ERROR print statements during download.
- Base:
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 ofwebui_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 ofwebui_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-nativewget
andshutil
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)