auto timestamp lyricks when song selected

This commit is contained in:
Thomas Demirdjian
2025-09-09 13:51:20 +02:00
parent 9a9de33ef2
commit ea9bfb0f05
7 changed files with 158 additions and 181 deletions
+98 -5
View File
@@ -1,6 +1,14 @@
const { onCall } = require("firebase-functions/v2/https");
const { z } = require("genkit");
const { generateAI, analyseLyrics } = require("../helpers/gemini");
const {
SUNO_API_BASE,
SUNO_TIMESTAMPED_LYRICS_PATH,
} = require("../config/suno");
const { SUNO_API_KEY } = require("../config/keys");
const axios = require("axios");
const admin = require("firebase-admin");
const { refList } = require("../index");
exports.generateLyrics = onCall({}, async ({ auth = {}, data = {} }) => {
try {
@@ -101,14 +109,25 @@ exports.analyseLyricsToxicity = onCall({}, async ({ data = {} }) => {
lyrics: z
.union([
z.string(),
z.object({ couplet: z.string().optional(), refrain: z.string().optional() }),
z.array(z.object({ type: z.string().optional(), lyrics: z.string().optional() })),
z.object({
couplet: z.string().optional(),
refrain: z.string().optional(),
}),
z.array(
z.object({
type: z.string().optional(),
lyrics: z.string().optional(),
}),
),
])
.describe("Paroles à analyser (formats supportés)"),
});
const parsed = requestSchema.parse(data || {});
const result = await analyseLyrics({ title: parsed.title || "", lyrics: parsed.lyrics });
const result = await analyseLyrics({
title: parsed.title || "",
lyrics: parsed.lyrics,
});
// Prépare un message lisible pour le front
const highCats = Object.entries(result.categories || {})
@@ -140,8 +159,82 @@ exports.analyseLyricsToxicity = onCall({}, async ({ data = {} }) => {
return {
success: false,
errorCode: "ANALYSE_FAILED",
message:
"Erreur lors de l'analyse de la toxicité. Réessayez plus tard.",
message: "Erreur lors de l'analyse de la toxicité. Réessayez plus tard.",
};
}
});
/**
* Récupère les timestamps (aligned words) pour une génération Suno
* Attend: { projectId: string }
*/
async function getSunoTimestamps(projectId) {
try {
const { sunoTaskId, songIndex } = (
await refList.projects.doc(projectId).get()
).data();
if (!sunoTaskId) {
throw new Error("TaskId manquant");
}
if (songIndex < 0) {
throw new Error("musicIndex invalide");
}
if (!projectId || typeof projectId !== "string" || !projectId.trim()) {
throw new Error("projectId manquant ou invalide");
}
console.log("🔎 Récupération des timestamps Suno", {
sunoTaskId,
songIndex,
});
let response;
let parsed;
response = await axios.post(
`${SUNO_API_BASE}${SUNO_TIMESTAMPED_LYRICS_PATH}`,
{ taskId: sunoTaskId, musicIndex: songIndex },
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${SUNO_API_KEY}`,
},
timeout: 30000,
},
);
parsed = response.data;
console.log("📊 Réponse timestamps Suno API:", parsed?.code, parsed?.msg);
const dataToReturn = parsed?.data || parsed || {};
await refList.projects.doc(projectId).set(
{
musicTimestamps: {
[songIndex]: dataToReturn,
},
updatedAt: admin.firestore.FieldValue.serverTimestamp(),
},
{ merge: true },
);
console.log("💾 Timestamps sauvegardés dans Firestore", {
projectId,
songIndex,
});
return {
success: true,
};
} catch (error) {
console.error("❌ Erreur interne getSunoTimestamps:", error);
return {
success: false,
error: {
message: error.message,
type: "INTERNAL_ERROR",
},
};
}
}
exports.getSunoTimestamps = getSunoTimestamps;