feat: removido o tamanho do modelo do seletor da tela Editar vídeo
- removido o tamanho do modelo do seletor da tela Editar vídeo - acelerada a transcrição do Scanner com inferência Whisper em lote e cache de hashes - garantido um resultado separado para cada clipe de áudio selecionado no Scanner - adicionado cancelamento do processamento do Scanner pela barra de progresso - exibido estado visual próprio para Scanner cancelado na barra de progresso - reorganizada a tela Scanner em blocos separados de imagem e som Resumo: - 7 arquivos alterados - 1 novos - 6 modificados - 0 removidos 6 files changed, 92 insertions(+), 40 deletions(-) Arquivos: - .jhonny/analises.db - code/cep-plugin/index.html - code/cep-plugin/main.js - code/cep-plugin/styles.css - code/engine/integracoes/whisper/provider_de_transcricao_local.py - code/engine/scanner/transcricao_da_timeline.py - code/engine/testes/test_provider_de_transcricao_local.py
This commit is contained in:
+30
-8
@@ -28,7 +28,7 @@ function log(msg, cls) {
|
||||
// Antes, tudo que rodava só aparecia como linhas no log lá embaixo e a pessoa
|
||||
// não sabia o que estava acontecendo. Agora todo processo longo abre um card
|
||||
// reposicionado na aba de origem com etapa atual, barra e tempo decorrido.
|
||||
var taskState = { active: false, startedAt: 0, timer: null, clearTimer: null, mirror: null, originTab: "silence", originPanelId: "tabSilence", errorText: "" };
|
||||
var taskState = { active: false, startedAt: 0, timer: null, clearTimer: null, mirror: null, cancel: null, canceled: false, originTab: "silence", originPanelId: "tabSilence", errorText: "" };
|
||||
|
||||
var TIPOS_VIDEO_CHAVE = "schedule_light_tipos_video";
|
||||
var tipoVideoAtualId = null;
|
||||
@@ -75,11 +75,13 @@ function taskMoveToOriginTab() {
|
||||
taskState.originPanelId = panel.id;
|
||||
}
|
||||
|
||||
function taskStart(title, stage, mirror) {
|
||||
function taskStart(title, stage, mirror, cancel) {
|
||||
if (taskState.clearTimer) { clearTimeout(taskState.clearTimer); taskState.clearTimer = null; }
|
||||
taskState.active = true;
|
||||
taskState.startedAt = Date.now();
|
||||
taskState.mirror = mirror || null;
|
||||
taskState.cancel = typeof cancel === "function" ? cancel : null;
|
||||
taskState.canceled = false;
|
||||
taskState.originTab = activeTab();
|
||||
taskState.errorText = "";
|
||||
taskMoveToOriginTab();
|
||||
@@ -96,6 +98,9 @@ function taskStart(title, stage, mirror) {
|
||||
taskEl("taskCopy").hidden = true;
|
||||
taskEl("taskErrorDetails").hidden = true;
|
||||
taskEl("taskErrorDetails").textContent = "";
|
||||
taskEl("taskCancel").hidden = !taskState.cancel;
|
||||
taskEl("taskCancel").disabled = false;
|
||||
taskEl("taskCancel").textContent = "Cancelar";
|
||||
hideToast();
|
||||
|
||||
if (taskState.timer) clearInterval(taskState.timer);
|
||||
@@ -127,12 +132,15 @@ function taskEnd(ok, message, technicalDetails) {
|
||||
taskState.active = false;
|
||||
|
||||
var dock = taskEl("taskDock");
|
||||
dock.setAttribute("data-result", ok ? "ok" : "err");
|
||||
var cancelado = taskState.canceled;
|
||||
dock.setAttribute("data-result", cancelado ? "cancelled" : (ok ? "ok" : "err"));
|
||||
taskEl("taskTrack").setAttribute("data-mode", "determinate");
|
||||
taskEl("taskFill").style.width = "100%";
|
||||
taskEl("taskStage").textContent = message || (ok ? "Concluído" : "Falhou");
|
||||
taskEl("taskStage").textContent = message || (cancelado ? "Cancelado" : (ok ? "Concluído" : "Falhou"));
|
||||
taskEl("taskPct").textContent = ok ? "100%" : "";
|
||||
if (!ok) {
|
||||
taskEl("taskCancel").hidden = true;
|
||||
taskEl("taskCancel").disabled = false;
|
||||
if (!ok && !cancelado) {
|
||||
taskState.errorText = String(technicalDetails || message || "Falha sem detalhes técnicos.");
|
||||
taskEl("taskCopy").hidden = false;
|
||||
taskEl("taskErrorDetails").textContent = taskState.errorText;
|
||||
@@ -141,6 +149,7 @@ function taskEnd(ok, message, technicalDetails) {
|
||||
}
|
||||
|
||||
taskState.mirror = null;
|
||||
taskState.cancel = null;
|
||||
// O próprio card já carrega o desfecho e fica na tela por alguns segundos —
|
||||
// repetir a mesma frase no toast só empilhava dois avisos idênticos.
|
||||
taskState.clearTimer = setTimeout(function () {
|
||||
@@ -148,6 +157,15 @@ function taskEnd(ok, message, technicalDetails) {
|
||||
}, ok ? 4000 : 9000);
|
||||
}
|
||||
|
||||
function taskCancel() {
|
||||
if (!taskState.active || typeof taskState.cancel !== "function") return;
|
||||
taskState.canceled = true;
|
||||
taskEl("taskCancel").disabled = true;
|
||||
taskEl("taskCancel").textContent = "Cancelando…";
|
||||
taskEl("taskStage").textContent = "Cancelando…";
|
||||
try { taskState.cancel(); } catch (erro) { taskEnd(false, "Falha ao cancelar", erro.message); }
|
||||
}
|
||||
|
||||
function taskCopyError() {
|
||||
var texto = taskState.errorText;
|
||||
if (!texto) return;
|
||||
@@ -1090,6 +1108,8 @@ var SCANNER_ALL_RESOURCES = ["faces", "qualidade_facial", "pessoas", "pose", "ma
|
||||
|
||||
var scannerTimeline = null;
|
||||
var scannerReportPath = null;
|
||||
var scannerProcesso = null;
|
||||
var scannerCancelSolicitado = false;
|
||||
var SCANNER_ENGINE_SCRIPT = "/Volumes/Merongo/SISTEMAS/GENIAL SISTEMAS/Jhonny/code/engine/executar_scanner.py";
|
||||
|
||||
// `path` e `os` são carregados mais abaixo, junto com o runtime Node do CEP.
|
||||
@@ -1180,10 +1200,12 @@ function scannerProcess() {
|
||||
var input=path.join(outputRoot,"pedido-"+stamp+".json");
|
||||
scannerReportPath=path.join(outputRoot,"relatorio-"+stamp+".json");
|
||||
fs.writeFileSync(input,JSON.stringify({perfil:profile,timeline:scannerTimeline},null,2),"utf-8");
|
||||
setBusy("btnScannerProcess",true); taskStart("Scanner", "Preparando análise", null);
|
||||
setBusy("btnScannerProcess",true);
|
||||
var spawnOptions={cwd:"/Volumes/Merongo/SISTEMAS/GENIAL SISTEMAS/Jhonny/code",stdio:["ignore","pipe","pipe"]};
|
||||
var huggingFaceEnvironment=hfSpawnOptions(); if(huggingFaceEnvironment&&huggingFaceEnvironment.env) spawnOptions.env=huggingFaceEnvironment.env;
|
||||
var child=childProcess.spawn(SCANNER_PYTHON_BIN,[SCANNER_ENGINE_SCRIPT,input,scannerReportPath],spawnOptions);
|
||||
scannerProcesso=child; scannerCancelSolicitado=false;
|
||||
taskStart("Scanner", "Preparando análise", null, function () { scannerCancelSolicitado=true; if (scannerProcesso) scannerProcesso.kill("SIGTERM"); });
|
||||
var stderr="", stdout="";
|
||||
child.stdout.on("data",function(chunk) {
|
||||
stdout += chunk.toString(); var lines=stdout.split("\n"); stdout=lines.pop();
|
||||
@@ -1191,7 +1213,7 @@ function scannerProcess() {
|
||||
});
|
||||
child.stderr.on("data",function(chunk){stderr+=chunk.toString();});
|
||||
child.on("error",function(error){setBusy("btnScannerProcess",false);taskEnd(false,"Scanner indisponível",error.stack||error.message);showToast("err",error.message);});
|
||||
child.on("close",function(code){setBusy("btnScannerProcess",false);if(code!==0||!fs.existsSync(scannerReportPath)){taskEnd(false,"Scanner falhou",stderr||"Não foi possível gerar o relatório.");showToast("err",stderr||"Não foi possível gerar o relatório.");return;}taskEnd(true,"Relatório JSON gerado");document.getElementById("scannerReportPath").textContent=scannerReportPath;document.getElementById("scannerReportCard").hidden=false;showToast("ok","Scanner concluído.");});
|
||||
child.on("close",function(code){var foiCancelado=scannerCancelSolicitado;scannerProcesso=null;setBusy("btnScannerProcess",false);if(foiCancelado){taskEnd(false,"Scanner cancelado");return;}if(code!==0||!fs.existsSync(scannerReportPath)){taskEnd(false,"Scanner falhou",stderr||"Não foi possível gerar o relatório.");showToast("err",stderr||"Não foi possível gerar o relatório.");return;}taskEnd(true,"Relatório JSON gerado");document.getElementById("scannerReportPath").textContent=scannerReportPath;document.getElementById("scannerReportCard").hidden=false;showToast("ok","Scanner concluído.");});
|
||||
}
|
||||
|
||||
function scannerOpenReport() { if (!scannerReportPath) return; childProcess.spawn("open",[scannerReportPath],{detached:true,stdio:"ignore"}).unref(); }
|
||||
@@ -3118,7 +3140,7 @@ function syncTranscribeModelSelect() {
|
||||
modelosDisponiveis.forEach(function (modelo) {
|
||||
var opt = document.createElement("option");
|
||||
opt.value = modelo.nome;
|
||||
opt.textContent = modelo.nome + " · " + formatMB(modelo.tamanho);
|
||||
opt.textContent = modelo.nome;
|
||||
select.appendChild(opt);
|
||||
});
|
||||
if (!modelosDisponiveis.length) {
|
||||
|
||||
Reference in New Issue
Block a user