feat: Estudio Musical para criacao de cantigas personalizadas
This commit is contained in:
+186
@@ -3256,6 +3256,192 @@ const initApp = () => {
|
||||
printWindow.document.close();
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// ESTÚDIO MUSICAL (Criação de música cantada com MiniMax)
|
||||
// ============================================================
|
||||
const estudioMusicalModal = document.getElementById('estudioMusicalModal');
|
||||
const btnCloseEstudioModal = document.getElementById('btnCloseEstudioModal');
|
||||
const sidebarBtnEstudio = document.getElementById('sidebarBtnEstudio');
|
||||
const welcomeCardEstudio = document.getElementById('welcomeCardEstudio');
|
||||
|
||||
const btnGenerateStudioMusic = document.getElementById('btnGenerateStudioMusic');
|
||||
const musicTemaInput = document.getElementById('musicTemaInput');
|
||||
const musicGenerateLoader = document.getElementById('musicGenerateLoader');
|
||||
const musicLoaderText = document.getElementById('musicLoaderText');
|
||||
const musicResultArea = document.getElementById('musicResultArea');
|
||||
const musicStudioAudioPlayer = document.getElementById('musicStudioAudioPlayer');
|
||||
const musicStudioDownloadBtn = document.getElementById('musicStudioDownloadBtn');
|
||||
const musicStudioLyricsArea = document.getElementById('musicStudioLyricsArea');
|
||||
const btnCopyMusicLyrics = document.getElementById('btnCopyMusicLyrics');
|
||||
const btnDownloadMusicLyrics = document.getElementById('btnDownloadMusicLyrics');
|
||||
|
||||
let selectedVoice = 'mulher';
|
||||
let selectedRhythm = 'roda';
|
||||
let selectedDuration = '30s';
|
||||
|
||||
// Toggle classes active para botões de opções
|
||||
document.querySelectorAll('.btn-music-option').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
document.querySelectorAll('.btn-music-option').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
selectedVoice = btn.dataset.voice;
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.btn-music-rhythm').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
document.querySelectorAll('.btn-music-rhythm').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
selectedRhythm = btn.dataset.rhythm;
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.btn-music-duration').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
document.querySelectorAll('.btn-music-duration').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
selectedDuration = btn.dataset.duration;
|
||||
});
|
||||
});
|
||||
|
||||
// Abrir e fechar modal
|
||||
const openEstudioModal = () => {
|
||||
estudioMusicalModal.style.display = 'flex';
|
||||
musicTemaInput.value = '';
|
||||
musicResultArea.style.display = 'none';
|
||||
musicStudioAudioPlayer.src = '';
|
||||
musicStudioLyricsArea.textContent = '';
|
||||
if (musicGenerateLoader) musicGenerateLoader.style.display = 'none';
|
||||
btnGenerateStudioMusic.disabled = false;
|
||||
};
|
||||
|
||||
if (sidebarBtnEstudio) {
|
||||
sidebarBtnEstudio.addEventListener('click', openEstudioModal);
|
||||
}
|
||||
|
||||
if (welcomeCardEstudio) {
|
||||
welcomeCardEstudio.addEventListener('click', openEstudioModal);
|
||||
}
|
||||
|
||||
if (btnCloseEstudioModal) {
|
||||
btnCloseEstudioModal.addEventListener('click', () => {
|
||||
estudioMusicalModal.style.display = 'none';
|
||||
musicStudioAudioPlayer.pause();
|
||||
});
|
||||
}
|
||||
|
||||
// Fechar modal clicando fora
|
||||
window.addEventListener('click', (e) => {
|
||||
if (e.target === estudioMusicalModal) {
|
||||
estudioMusicalModal.style.display = 'none';
|
||||
musicStudioAudioPlayer.pause();
|
||||
}
|
||||
});
|
||||
|
||||
// Ação de gerar música no estúdio
|
||||
if (btnGenerateStudioMusic) {
|
||||
btnGenerateStudioMusic.addEventListener('click', async () => {
|
||||
const tema = musicTemaInput.value.trim();
|
||||
if (!tema) {
|
||||
alert('Por favor, digite um tema para a música.');
|
||||
return;
|
||||
}
|
||||
|
||||
btnGenerateStudioMusic.disabled = true;
|
||||
musicGenerateLoader.style.display = 'flex';
|
||||
musicResultArea.style.display = 'none';
|
||||
|
||||
const statusInterval = setInterval(() => {
|
||||
const statusMessages = [
|
||||
'Compondo a letra pedagógica...',
|
||||
'Ajustando a métrica e as rimas...',
|
||||
'Gerando o arranjo musical...',
|
||||
'Adicionando os vocais cantados...',
|
||||
'Quase pronto, finalizando o áudio...'
|
||||
];
|
||||
const randomMsg = statusMessages[Math.floor(Math.random() * statusMessages.length)];
|
||||
musicLoaderText.textContent = randomMsg;
|
||||
}, 5000);
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/music/generate', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
tema,
|
||||
voz: selectedVoice,
|
||||
ritmo: selectedRhythm,
|
||||
duracao: selectedDuration
|
||||
})
|
||||
});
|
||||
|
||||
clearInterval(statusInterval);
|
||||
|
||||
if (!response.ok) {
|
||||
const errData = await response.json();
|
||||
throw new Error(errData.error || 'Erro na geração de áudio');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// Exibir resultados
|
||||
musicStudioLyricsArea.textContent = data.lyrics;
|
||||
musicStudioAudioPlayer.src = data.audioUrl;
|
||||
musicStudioDownloadBtn.href = data.audioUrl;
|
||||
|
||||
musicGenerateLoader.style.display = 'none';
|
||||
musicResultArea.style.display = 'flex';
|
||||
|
||||
} catch (err) {
|
||||
clearInterval(statusInterval);
|
||||
console.error('Erro ao gerar música no estúdio:', err);
|
||||
alert('Erro ao gerar música: ' + err.message);
|
||||
musicGenerateLoader.style.display = 'none';
|
||||
btnGenerateStudioMusic.disabled = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Copiar letra
|
||||
if (btnCopyMusicLyrics) {
|
||||
btnCopyMusicLyrics.addEventListener('click', () => {
|
||||
const lyrics = musicStudioLyricsArea.textContent;
|
||||
if (lyrics) {
|
||||
navigator.clipboard.writeText(lyrics)
|
||||
.then(() => {
|
||||
btnCopyMusicLyrics.textContent = '✅ Copiado!';
|
||||
setTimeout(() => {
|
||||
btnCopyMusicLyrics.textContent = '📋 Copiar Letra';
|
||||
}, 2000);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Falha ao copiar:', err);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Baixar letra em arquivo de texto (TXT)
|
||||
if (btnDownloadMusicLyrics) {
|
||||
btnDownloadMusicLyrics.addEventListener('click', () => {
|
||||
const lyrics = musicStudioLyricsArea.textContent;
|
||||
const tema = musicTemaInput.value.trim() || 'cantiga';
|
||||
if (lyrics) {
|
||||
const blob = new Blob([lyrics], { type: 'text/plain;charset=utf-8' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `letra_${tema.replace(/\s+/g, '_').toLowerCase()}.txt`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Player de áudio personalizado global para as mídias geradas
|
||||
|
||||
Reference in New Issue
Block a user