Files
musicland/functions/helpers/prompts.js
T
2025-12-10 09:46:07 +01:00

138 lines
4.8 KiB
JavaScript

exports.generatePicturePrompt = (project = {}) => {
const {
title = "",
lyrics: lyricsRaw,
musicConfig = {},
coverStyle: coverStyleRaw = "",
artistName: artistNameRaw = "",
} = project || {};
// --- 1. Nettoyage et Normalisation ---
const sanitizeInline = (value = "") => {
if (typeof value !== "string") return "";
return value
.replace(/[\r\n]+/g, " ")
.replace(/[<>]/g, "")
.trim();
};
const titleForPrompt = sanitizeInline(title) || "Sans titre";
const artistName =
sanitizeInline(artistNameRaw) || sanitizeInline(project?.userName || "");
const hasArtistName = artistName.length > 0;
const {
genres = [],
tempo = "",
mood = "",
instruments = [],
} = musicConfig || {};
const userStyle = sanitizeInline(coverStyleRaw);
// --- 2. Intelligence Visuelle (Mapping) ---
// Détermination de l'énergie visuelle
const isEnergetic =
tempo &&
/\b(rapid|fast|vite|agité|upbeat|energ|dance|rock|metal)\b/i.test(
String(tempo),
);
const isDark =
mood &&
/\b(sombre|triste|dark|sad|mélancoli|nuit|night|eerie)\b/i.test(
String(mood),
);
// Construction de la Palette & Lumière
let visualAtmosphere = "";
if (isDark) {
visualAtmosphere =
"Atmosphere: Cinematic atmosphere, moody shadows, deep contrast. Palette: Midnight blue, obsidian, deep purple, metallic accents.";
} else if (isEnergetic) {
visualAtmosphere =
"Atmosphere: Dynamic atmosphere, high energy, vibrant saturation. Palette: Neon colors, electric blue, magenta, bright yellow, high contrast.";
} else {
visualAtmosphere =
"Atmosphere: Soft atmosphere, harmonious and ethereal. Palette: Pastel tones, warm gold, soft coral, balanced and elegant colors.";
}
// Définition du Style de Rendu (Si l'utilisateur est vague, on renforce)
let renderingStyle = userStyle
? `Art Style: ${userStyle}`
: "Art Style: Digital Art, Mixed Media";
if (
userStyle.toLowerCase().includes("realist") ||
userStyle.toLowerCase().includes("photo")
) {
renderingStyle +=
", 8k resolution, highly detailed texture, photorealistic, cinematic depth of field, raytracing.";
} else if (
userStyle.toLowerCase().includes("illu") ||
userStyle.toLowerCase().includes("dessin")
) {
renderingStyle +=
", vector art, clean lines, professional illustration, flat design or detailed painting.";
} else {
// Style par défaut "Album Cover" qui marche bien
renderingStyle +=
", abstract surrealism, conceptual album art, high fidelity, masterpiece.";
}
// --- 3. Extraction de l'Inspiration (Lyrics) ---
// On cherche le REFRAIN en priorité pour l'image, car c'est le cœur visuel
const sections = Array.isArray(lyricsRaw) ? lyricsRaw : [];
const chorus = sections.find(
(s) => s.type === "refrain" || s.type === "chorus",
);
const verse = sections.find(
(s) => s.type === "couplet" || s.type === "verse",
);
// On prend 2 lignes max du refrain, ou du premier couplet
const visualHook = (chorus?.lyrics || verse?.lyrics || "")
.split("\n")
.filter((l) => l.length > 10) // On évite les lignes trop courtes
.slice(0, 2)
.join(". ");
const imageryPrompt = visualHook
? `Visual Inspiration: An interpretation of these lyrics: "${visualHook}".`
: "Visual Inspiration: Abstract visual representation of the song's mood.";
// --- 4. Construction du Prompt Final (Structure Optimisée Imagen 3) ---
const promptParts = [
// Rôle
"Design a professional, high-quality music album cover.",
// 1. Le Texte (Crucial pour Imagen 3 - Doit être au début ou très clair)
`**Typography & Text:**`,
`The song title "${titleForPrompt}" must be the CENTERPIECE. Write it in a distinct font that matches the mood.`,
hasArtistName
? `The artist name "${artistName}" must appear smaller, elegant, and legible near the bottom or top.`
: "",
"Ensure perfect spelling. The text should be integrated into the artwork (e.g., metallic texture, neon glow, or bold cut-out), not just pasted on top.",
// 2. Le Visuel
`**Visuals:**`,
renderingStyle,
imageryPrompt,
`Subject: A central visual element that represents the song. ${isEnergetic ? "Dynamic composition." : "Balanced, centered composition."}`,
// 3. L'Atmosphère (Context from music config)
`**Mood & Color:**`,
visualAtmosphere,
genres.length > 0 ? `Musical Vibe Reference: ${genres.join(", ")}.` : "",
// 4. Contraintes Négatives (Phrasées positivement pour l'IA)
"**Constraints:**",
"Use a square 1:1 aspect ratio.",
"Do NOT depict literal musical instruments (like guitars or microphones) unless they are part of a surreal abstract composition.",
"No blurry text. No messy borders. No watermarks.",
];
return promptParts.filter(Boolean).join("\n\n");
};