testando ui otimista
Deploy / Deploy (push) Successful in 38s Details

This commit is contained in:
JotaChina 2026-03-26 19:48:02 -03:00
parent db9bbada25
commit 42a902afc6
1 changed files with 55 additions and 6 deletions

View File

@ -905,17 +905,65 @@ function downloadFile(content, fileName) {
URL.revokeObjectURL(url);
}
// Função para buscar os samples curtos (batidas) e guardá-los no ZIP
async function applyInstrumentsToZip(zip) {
const pathMap = getSamplePathMap();
const tracks = appState.pattern.tracks || [];
for (const track of tracks) {
if (track.type === "bassline") continue; // Ignora as linhas de montagem
// Só avança se for um sampler
const isSampler = track.type === "sampler" || track.samplePath || track.filePath || track.sampleName;
if (!isSampler) continue;
const rawSrc = track.samplePath || track.filePath || track.sampleName || track.name || "";
if (!rawSrc) continue;
const fileName = String(rawSrc).split(/[\\/]/).pop();
const zipPath = `samples/${fileName}`;
// Se já adicionamos este ficheiro no zip (ex: se usar o mesmo kick 2x), salta
if (zip.file(zipPath)) continue;
try {
// Tenta achar a URL real do áudio no servidor
let fetchUrl = track.samplePath || track.filePath;
// Se não tem caminho direto, tenta pelo manifest
if (!fetchUrl) {
fetchUrl = resolveSamplePath(fileName, pathMap);
}
// Fallback final usando a sua variável SAMPLE_SRC
if (!fetchUrl) {
fetchUrl = `${SAMPLE_SRC}/${fileName}`;
}
// Faz o download silencioso e insere no ZIP usando a sua cache
const arrayBuffer = await _fetchArrayBufferCached(fetchUrl);
zip.file(zipPath, arrayBuffer);
} catch (err) {
console.warn(`[Export] Não foi possível incluir o sample ${fileName} no zip:`, err);
}
}
}
async function generateAndDownloadMmpz(baseName) {
initializeAudioContext();
const baseXmlString = generateXmlFromState(); // seu método atual (patterns OK)
const baseXmlString = generateXmlFromState();
const xmlDoc = new DOMParser().parseFromString(baseXmlString, "application/xml");
// JSZip precisa existir (você já usa pra abrir mmpz)
const zip = new JSZip();
// 1. Empacota as pistas de áudio (Timeline)
await applySampleTracksToXmlAndZip(xmlDoc, zip);
// 2. 🔥 NOVO: Empacota as amostras da bateria (Kicks, Snares...)
await applyInstrumentsToZip(zip);
const finalXml = new XMLSerializer().serializeToString(xmlDoc);
zip.file(`${baseName}.mmp`, finalXml);
@ -926,24 +974,25 @@ async function generateAndDownloadMmpz(baseName) {
const blob = await zip.generateAsync({ type: "blob", compression: "DEFLATE" });
downloadBlob(blob, `${baseName}.zip`);
}
export async function buildRenderPackageBlob(baseName = "projeto") {
initializeAudioContext();
const baseXmlString = generateXmlFromState(); // patterns
const baseXmlString = generateXmlFromState();
const xmlDoc = new DOMParser().parseFromString(baseXmlString, "application/xml");
const zip = new JSZip();
await applySampleTracksToXmlAndZip(xmlDoc, zip); // ✅ coloca sampletco + samples/*.wav
await applySampleTracksToXmlAndZip(xmlDoc, zip);
// 🔥 NOVO: Garante que o servidor recebe os samples da bateria para a renderização final!
await applyInstrumentsToZip(zip);
const finalXml = new XMLSerializer().serializeToString(xmlDoc);
zip.file(`${baseName}.mmp`, finalXml);
const blob = await zip.generateAsync({ type: "blob", compression: "DEFLATE" });
// pode ser .mmpz (LMMS costuma aceitar) ou .zip (você já usa)
return { blob, fileName: `${baseName}.mmpz` };
}