diff --git a/app/api/v1/plugins.py b/app/api/v1/plugins.py index 5b0e655..69c20ea 100644 --- a/app/api/v1/plugins.py +++ b/app/api/v1/plugins.py @@ -207,6 +207,7 @@ async def list_plugins(current_user: dict = Depends(get_current_user)): fx_paths = set() unknown_paths = set() fx_norm_names = set() + unknown_norm_names = set() try: from app.core.vst_engine import get_plugin_manager for e in get_plugin_manager().list_scan_all(): @@ -214,8 +215,11 @@ async def list_plugins(current_user: dict = Depends(get_current_user)): if e.get("is_fx"): fx_paths.add(path) fx_norm_names.add(_norm_plugin_name(e.get("name") or "")) + fx_norm_names.add(_norm_path_stem(e.get("path") or "")) elif e.get("is_unknown"): unknown_paths.add(path) + unknown_norm_names.add(_norm_plugin_name(e.get("name") or "")) + unknown_norm_names.add(_norm_path_stem(e.get("path") or "")) except Exception: pass blocked = fx_paths | unknown_paths @@ -226,6 +230,12 @@ async def list_plugins(current_user: dict = Depends(get_current_user)): # EQ.vst3...) nhưng path .dll ≠ path .vst3 → block theo path KHÔNG trúng. # Loại theo TÊN normalized (bỏ prefix iZ, lowercase alnum) — VST2 thật # (DSK Asian DreamZ, Kong Audio...) không trùng tên FX → vẫn giữ. + # Ngoài is_fx còn loại entry UNKNOWN theo TÊN: bridge timeout khi + # introspect VST3 (vd Ozone Pro.vst3, Tonal Balance Control Pro.vst3 — + # module treo 12s → skip) nên không vào fx_norm_names, nhưng VST2 legacy + # .dll CÙNG TÊN (Ozone Pro.dll) vẫn lọt vào nút Synth → load FX như + # instrument → không ra tiếng. UNKNOWN = không xác định loại → cũng + # không hiện là instrument (cùng chính sách block theo path ở trên). name = v.get("name") or "" if name.startswith("iZ") and "izotope" in ((v.get("path") or "").lower()): # iZotope KHÔNG sản xuất VST instrument — mọi module .dll/VST2 của @@ -233,9 +243,12 @@ async def list_plugins(current_user: dict = Depends(get_current_user)): # VST2 legacy không introspect được → bridge không đánh is_fx → lọt # vào nút Synth (iZOzonePro, iZRXProMusicRebalance, iZTonalBalanceControlPro). return True - if not fx_norm_names: + if not fx_norm_names and not unknown_norm_names: return False - return _norm_plugin_name(name) in fx_norm_names + nm_name = _norm_plugin_name(name) + nm_stem = _norm_path_stem(v.get("path") or "") + return (nm_name in fx_norm_names or nm_stem in fx_norm_names + or nm_name in unknown_norm_names or nm_stem in unknown_norm_names) if blocked: avail["vst_instruments"] = [v for v in avail["vst_instruments"] @@ -269,6 +282,16 @@ def _norm_plugin_name(name: str) -> str: s = s[2:] return s +def _norm_path_stem(path: str) -> str: + """Chuẩn hóa TÊN FILE (không phần mở rộng) của path — dùng cho entry UNKNOWN + mà bridge chỉ report filename kèm đuôi ('Ozone Pro.vst3') vì timeout khi + introspect: stem 'Ozone Pro' khớp VST2 legacy 'Ozone Pro.dll' cùng tên.""" + base = os.path.basename((path or "").replace("\\", "/")) + s = "".join(ch for ch in os.path.splitext(base)[0].lower() if ch.isalnum()) + if s.startswith("iz") and len(s) > 2: + s = s[2:] + return s + def _scan_soundfonts_in_dirs(dirs: list) -> list: """Walk các thư mục (plugin_dirs user) → danh sách soundfont .sf2/.sf3