feat: metadati AI detection + prompt/lyrics + pannello frame grezzi (v1.13.0)

Metadati tab estesa per audit e cleanup file AI-generated:

- Nuovi campi read/write: source_url (WOAS ID3), lyrics (USLT), plus
  \xa9lyr per M4A
- Badge AI con riconoscimento: Suno, Udio, Riffusion, Mubert, AIVA,
  Boomy, SoundRAW, Loudly + presenza C2PA manifest (GEOB frame)
- Pannello "Metadati avanzati" collapsable: tabella di tutti i frame
  ID3 grezzi (chiave, tipo text/binary, preview, size)
- Rimozione selettiva frame custom via bridge remove_metadata_frames:
  ID3.__delitem__() + save() per MP3, MP4.tags per M4A. Frame standard
  protetti (TIT2/TPE1/APIC ecc.) marcati 🔒 nella UI, si svuotano dai
  campi form
- Rilevamento AI riusabile via core.metadata._detect_ai(comment,
  source_url, extra) — case-insensitive, returns (is_ai, source_name)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
lucianoandClaude Opus 4.7 committed 2026-09-24 11:13:58 +02:00
1 parent 8432b2a592
commit 9644ffec35
6 files changed
+399 -1

No files matched your search

+15
View File
@@ -446,6 +446,21 @@ class Api:
except Exception as e:
return {"ok": False, "error": str(e)}
def remove_metadata_frames(self, path: str, frame_keys: list) -> dict:
"""Rimuove i frame ID3/atomi indicati dal file. Usato dal pannello
'Metadati avanzati' per pulire TXXX, GEOB (C2PA), USLT extra, ecc."""
if not path or not os.path.exists(path):
return {"ok": False, "error": "File non trovato"}
gate = self._gate("metadata")
if gate:
return gate
try:
from core.metadata import remove_frames
n = remove_frames(path, frame_keys or [])
return {"ok": True, "removed": n}
except Exception as e:
return {"ok": False, "error": str(e)}
def save_metadata(self, payload: dict) -> dict:
path = (payload.get("path") or "").strip()
if not path: