feat: try lipsinck
This commit is contained in:
+41
-6
@@ -259,7 +259,7 @@ ${structureTags || fallbackStructureTags}
|
||||
0. ${languageInstruction}
|
||||
1. Génère un **Titre** percutant (moins de 6 mots).
|
||||
2. Pour chaque section <SECTION>, écris le contenu adapté :
|
||||
- Si c'est "Instrumental" ou "Solo" : laisse le champ 'lyrics' vide ou mets une brève indication d'ambiance entre parenthèses ex: "(Solo de guitare déchirant)".
|
||||
- Si c'est "Instrumental", "Intro", "Pont" ou "Solo" : le champ 'lyrics' doit être strictement vide. N'ajoute aucune indication entre parenthèses.
|
||||
- Si c'est "Couplet/Refrain" : Écris 4 à 12 vers.
|
||||
3. **IMPORTANT** : Le style est "${style}". Assure-toi que le vocabulaire et le rythme collent parfaitement à ce genre.
|
||||
</CONSIGNES_GENERATION>
|
||||
@@ -428,15 +428,16 @@ async function getSunoTimestamps(projectId) {
|
||||
const docSnap = await refList.projects.doc(projectId).get()
|
||||
if (!docSnap.exists) throw new Error('Projet introuvable')
|
||||
|
||||
const { sunoTaskId, songIndex } = docSnap.data()
|
||||
if (!sunoTaskId) throw new Error('TaskId manquant')
|
||||
const { songSunoTaskId, sunoAudioId, songIndex } = docSnap.data()
|
||||
if (!songSunoTaskId) throw new Error('TaskId de la piste manquant')
|
||||
if (!sunoAudioId) throw new Error('AudioId Suno manquant')
|
||||
if (songIndex === undefined || songIndex < 0) throw new Error('musicIndex invalide')
|
||||
|
||||
console.log('🔎 getSunoTimestamps', { sunoTaskId, songIndex })
|
||||
console.log('🔎 getSunoTimestamps', { songSunoTaskId, sunoAudioId, songIndex })
|
||||
|
||||
const response = await axios.post(
|
||||
`${SUNO_API_BASE}${SUNO_TIMESTAMPED_LYRICS_PATH}`,
|
||||
{ taskId: sunoTaskId, musicIndex: songIndex },
|
||||
{ taskId: songSunoTaskId, audioId: sunoAudioId },
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -446,11 +447,32 @@ async function getSunoTimestamps(projectId) {
|
||||
}
|
||||
)
|
||||
|
||||
const dataToReturn = response.data?.data || response.data || {}
|
||||
if (response.data?.code !== 200) {
|
||||
throw new Error(response.data?.msg || 'Récupération des timestamps refusée par Suno')
|
||||
}
|
||||
|
||||
const dataToReturn = response.data?.data
|
||||
if (!Array.isArray(dataToReturn?.alignedWords) || dataToReturn.alignedWords.length === 0) {
|
||||
throw new Error('Aucune parole synchronisée retournée par Suno')
|
||||
}
|
||||
const failedWordCount = dataToReturn.alignedWords.filter(
|
||||
(word) => word?.success === false
|
||||
).length
|
||||
const hootCer = Number(dataToReturn.hootCer)
|
||||
|
||||
await refList.projects.doc(projectId).set(
|
||||
{
|
||||
musicTimestamps: { [songIndex]: dataToReturn },
|
||||
lyricsSyncStatus: 'READY',
|
||||
lyricsSyncError: FieldValue.delete(),
|
||||
lyricsSyncDiagnostics: {
|
||||
alignedWordCount: dataToReturn.alignedWords.length,
|
||||
failedWordCount,
|
||||
successfulWordRatio:
|
||||
(dataToReturn.alignedWords.length - failedWordCount) /
|
||||
dataToReturn.alignedWords.length,
|
||||
hootCer: Number.isFinite(hootCer) ? hootCer : null,
|
||||
},
|
||||
updatedAt: FieldValue.serverTimestamp(),
|
||||
},
|
||||
{ merge: true }
|
||||
@@ -459,6 +481,19 @@ async function getSunoTimestamps(projectId) {
|
||||
return { success: true }
|
||||
} catch (error) {
|
||||
console.error('❌ getSunoTimestamps Error:', error.message)
|
||||
if (projectId) {
|
||||
await refList.projects
|
||||
.doc(projectId)
|
||||
.set(
|
||||
{
|
||||
lyricsSyncStatus: 'FAILED',
|
||||
lyricsSyncError: error.message,
|
||||
updatedAt: FieldValue.serverTimestamp(),
|
||||
},
|
||||
{ merge: true }
|
||||
)
|
||||
.catch(() => {})
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
error: { message: error.message, type: 'INTERNAL_ERROR' },
|
||||
|
||||
Reference in New Issue
Block a user