feat: definido projeto com uma sequência e múltiplos arquivos de m

- definido projeto com uma sequência e múltiplos arquivos de mídia
- criada persistência de projeto com uma sequência e seleções de faixas e clipes
- criada guia Projeto para selecionar sequência, faixas e clipes do Premiere
- adicionada gravação das seleções da guia Projeto no SQLite

Resumo:
- 10 arquivos alterados
- 4 novos
- 6 modificados
- 0 removidos

 6 files changed, 71 insertions(+), 2 deletions(-)

Arquivos:
  - .jhonny/analises.db
  - CONTEXT.md
  - code/cep-plugin/index.html
  - code/cep-plugin/main.js
  - code/engine/persistencia/__init__.py
  - code/engine/persistencia/esquema.py
  - code/cep-plugin/abas/
  - code/engine/persistencia/repositorio_de_projetos.py
  - code/engine/registrar_projeto_de_edicao.py
  - code/engine/testes/test_repositorio_de_projetos.py
This commit is contained in:
João Henrique
2026-09-10 13:22:15 -04:00
parent a9e5b5ff58
commit a4286bbd8a
10 changed files with 329 additions and 2 deletions
+100
View File
@@ -0,0 +1,100 @@
"use strict";
// A guia Projeto mantém a seleção da sequência, faixas e clipes fora das
// regras específicas de edição. O estado definitivo será persistido pelo
// repositório SQLite na próxima etapa da integração.
var projetoSequencias = [];
var projetoAtual = null;
function projetoListarSequencias() {
var botao = document.getElementById("btnProjetoCarregar");
if (botao) botao.disabled = true;
var select = document.getElementById("projetoSequenciaSelect");
var info = document.getElementById("projetoInfo");
info.textContent = "Lendo sequências, faixas e clipes do Premiere…";
cs.evalScript(
"(function(){try{" +
"if(!app.project)return JSON.stringify({ok:false,error:'Nenhum projeto aberto.'});" +
"var saida=[];" +
"for(var i=0;i<app.project.sequences.numSequences;i++){" +
"var s=app.project.sequences[i], faixas=[];" +
"for(var v=0;v<s.videoTracks.numTracks;v++){var tv=s.videoTracks[v],cv=[];for(var j=0;j<tv.clips.numItems;j++){var x=tv.clips[j];cv.push({id:String(x.nodeId),nome:String(x.name||''),inicio:Number(x.start.seconds),fim:Number(x.end.seconds)});}faixas.push({id:'video_'+v,nome:'Vídeo '+(v+1),tipo:'video',indice:v,clipes:cv});}" +
"for(var a=0;a<s.audioTracks.numTracks;a++){var ta=s.audioTracks[a],ca=[];for(var k=0;k<ta.clips.numItems;k++){var y=ta.clips[k];ca.push({id:String(y.nodeId),nome:String(y.name||''),inicio:Number(y.start.seconds),fim:Number(y.end.seconds)});}faixas.push({id:'audio_'+a,nome:'Áudio '+(a+1),tipo:'audio',indice:a,clipes:ca});}" +
"saida.push({id:String(s.sequenceID),nome:String(s.name||''),duracao:Number(s.end.seconds||0),largura:Number(s.frameSizeHorizontal||0),altura:Number(s.frameSizeVertical||0),ativa:!!(app.project.activeSequence&&s.sequenceID===app.project.activeSequence.sequenceID),faixas:faixas});" +
"}return JSON.stringify({ok:true,sequences:saida});}catch(e){return JSON.stringify({ok:false,error:String(e)});}}())",
function (raw) {
if (botao) botao.disabled = false;
var resposta;
try { resposta = JSON.parse(raw); } catch (erro) { resposta = {ok: false, error: "Resposta inválida do Premiere."}; }
if (!resposta.ok) { info.textContent = resposta.error; return; }
projetoSequencias = resposta.sequences || [];
select.innerHTML = "";
projetoSequencias.forEach(function (sequencia) {
var opcao = document.createElement("option");
opcao.value = sequencia.id;
opcao.textContent = sequencia.nome + (sequencia.ativa ? " · ativa" : "");
select.appendChild(opcao);
});
select.disabled = projetoSequencias.length === 0;
if (projetoSequencias.length) {
var ativa = projetoSequencias.findIndex(function (item) { return item.ativa; });
select.selectedIndex = ativa >= 0 ? ativa : 0;
projetoSelecionarSequencia();
} else {
info.textContent = "Nenhuma sequência encontrada no projeto do Premiere.";
}
}
);
}
function projetoSelecionarSequencia() {
var select = document.getElementById("projetoSequenciaSelect");
projetoAtual = projetoSequencias.find(function (item) { return item.id === select.value; }) || null;
if (!projetoAtual) return;
document.getElementById("projetoTimelineCard").hidden = false;
document.getElementById("projetoStatus").textContent = "Sequência selecionada";
document.getElementById("projetoTimelineStatus").textContent = projetoAtual.nome;
document.getElementById("projetoDuracao").textContent = formatSequenceDuration(projetoAtual.duracao);
document.getElementById("projetoResolucao").textContent = projetoAtual.largura && projetoAtual.altura ? projetoAtual.largura + " × " + projetoAtual.altura : "Não informada";
document.getElementById("projetoTotalFaixas").textContent = projetoAtual.faixas.length;
document.getElementById("projetoTotalClipes").textContent = projetoAtual.faixas.reduce(function (total, faixa) { return total + faixa.clipes.length; }, 0);
var container = document.getElementById("projetoFaixas");
container.innerHTML = "";
projetoAtual.faixas.forEach(function (faixa) {
var bloco = document.createElement("div");
bloco.className = "scanner-subsection";
bloco.innerHTML = '<label class="checkbox-field"><input type="checkbox" checked data-projeto-faixa="' + faixa.id + '"><span>' + faixa.nome + " · " + faixa.clipes.length + " clipe(s)</span></label>";
faixa.clipes.forEach(function (clipe) {
bloco.innerHTML += '<label class="checkbox-field" style="padding-left:24px"><input type="checkbox" checked data-projeto-clipe="' + clipe.id + '"><span>' + clipe.nome + " · " + formatSequenceDuration(clipe.fim - clipe.inicio) + "</span></label>";
});
container.appendChild(bloco);
});
document.getElementById("btnProjetoContinuar").disabled = false;
document.getElementById("btnProjetoSalvar").disabled = false;
document.getElementById("projetoInfo").textContent = "A sequência foi carregada. Selecione as faixas e clipes que participarão do plano.";
}
function projetoSalvar() {
if (!projetoAtual) return;
var faixas = Array.prototype.slice.call(document.querySelectorAll("[data-projeto-faixa]:checked")).map(function (item) { return item.getAttribute("data-projeto-faixa"); });
var clipes = Array.prototype.slice.call(document.querySelectorAll("[data-projeto-clipe]:checked")).map(function (item) { return item.getAttribute("data-projeto-clipe"); });
var pedido = path.join(os.tmpdir(), "pedido-projeto-edicao-" + Date.now() + ".json");
fs.writeFileSync(pedido, JSON.stringify({
nome: projetoAtual.nome, video_id: projetoAtual.id, faixas: faixas, clipes: clipes,
}, null, 2), "utf-8");
setBusy("btnProjetoSalvar", true);
runStreamed(SCANNER_PYTHON_BIN, [REGISTRAR_PROJETO_SCRIPT, pedido, "--banco", ANALISES_DB_PATH],
function (linha) { silenceLog(linha); },
function (codigo, ultimoErro) {
setBusy("btnProjetoSalvar", false);
if (codigo !== 0) { showToast("err", ultimoErro || "Não foi possível salvar o projeto."); return; }
document.getElementById("projetoStatus").textContent = "Projeto salvo no banco";
showToast("ok", "Projeto salvo com " + faixas.length + " faixa(s) e " + clipes.length + " clipe(s).");
});
}
function projetoContinuarEdicao() {
if (!projetoAtual) return;
switchTab("silence");
silenceListSequences();
}