feat: genre field in DetailPanel and ID3 TCON tag
- Added genre column to clips table (auto-migration) - Genre field in DetailPanel metadata section (between Album and Comment) - Genre saved via PATCH /api/clips/:id/metadata - Genre embedded in ID3 TCON tag on download - Placeholder text: 'e.g. Hardcore Techno, Phonk, Dark Ambient...'
This commit is contained in:
1 parent
1903d8bd2a
commit
bef707f9a4
5 files changed
+29
-12
No files matched your search
@@ -98,6 +98,11 @@ async def init_db():
|
||||
await db.execute("ALTER TABLE clips ADD COLUMN comment TEXT")
|
||||
except Exception:
|
||||
pass # Column already exists
|
||||
# Migration: add genre column if it doesn't exist
|
||||
try:
|
||||
await db.execute("ALTER TABLE clips ADD COLUMN genre TEXT")
|
||||
except Exception:
|
||||
pass # Column already exists
|
||||
await db.commit()
|
||||
|
||||
async def create_clip(prompt: str, model: str, duration: int, prompt_structure: str = None) -> str:
|
||||
@@ -176,11 +181,11 @@ async def rename_clip(clip_id: str, title: str):
|
||||
)
|
||||
await db.commit()
|
||||
|
||||
async def update_metadata(clip_id: str, artist: str = None, album: str = None, comment: str = None):
|
||||
async def update_metadata(clip_id: str, artist: str = None, album: str = None, comment: str = None, genre: str = None):
|
||||
async with aiosqlite.connect(DB_PATH) as db:
|
||||
await db.execute(
|
||||
"UPDATE clips SET artist = ?, album = ?, comment = ? WHERE id = ?",
|
||||
(artist, album, comment, clip_id)
|
||||
"UPDATE clips SET artist = ?, album = ?, comment = ?, genre = ? WHERE id = ?",
|
||||
(artist, album, comment, genre, clip_id)
|
||||
)
|
||||
await db.commit()
|
||||
|
||||
|
||||
+6
-2
@@ -135,7 +135,7 @@ async def stream_audio(clip_id: str):
|
||||
return FileResponse(file_path, media_type="audio/mpeg", filename=clip["filename"])
|
||||
|
||||
from mutagen.mp3 import MP3
|
||||
from mutagen.id3 import ID3, TIT1, TIT2, TPE1, TALB, COMM, TBPM, TKEY, APIC, PictureType
|
||||
from mutagen.id3 import ID3, TIT1, TIT2, TPE1, TALB, COMM, TBPM, TKEY, APIC, PictureType, TCON
|
||||
|
||||
@app.get("/api/clips/{clip_id}/download")
|
||||
async def download_clip(clip_id: str):
|
||||
@@ -197,6 +197,10 @@ async def download_clip(clip_id: str):
|
||||
if clip.get("key"):
|
||||
audio.tags["TKEY"] = TKEY(encoding=3, text=clip["key"])
|
||||
|
||||
# Genre
|
||||
if clip.get("genre"):
|
||||
audio.tags["TCON"] = TCON(encoding=3, text=clip["genre"])
|
||||
|
||||
# Album art
|
||||
if clip.get("artwork_filename"):
|
||||
artwork_path = ARTWORK_DIR / clip["artwork_filename"]
|
||||
@@ -496,7 +500,7 @@ async def update_clip_metadata(clip_id: str, request: MetadataRequest):
|
||||
clip = await get_clip(clip_id)
|
||||
if not clip:
|
||||
raise HTTPException(status_code=404, detail="Clip not found")
|
||||
await update_metadata(clip_id, request.artist, request.album, request.comment)
|
||||
await update_metadata(clip_id, request.artist, request.album, request.comment, request.genre)
|
||||
updated = await get_clip(clip_id)
|
||||
return updated
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ class MetadataRequest(BaseModel):
|
||||
artist: Optional[str] = None
|
||||
album: Optional[str] = None
|
||||
comment: Optional[str] = None
|
||||
genre: Optional[str] = None
|
||||
|
||||
class GenerateArtworkRequest(BaseModel):
|
||||
prompt: str
|
||||
|
||||
Reference in new issue
Block a user