From becdc3afd5268d82dddd7f5a591b600253d888c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Henrique?= Date: Thu, 10 Sep 2026 10:00:06 -0400 Subject: [PATCH] feat: aprimorado o preview de falantes na tela Refinar para reprod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - aprimorado o preview de falantes na tela Refinar para reproduzir os trechos do vídeo - corrigida a leitura dos timestamps do preview de falantes usando os clipes do banco - alterado o preview de falantes para reproduzir diretamente na timeline ativa do Premiere - evitadas reinicializações concorrentes durante o monitoramento do preview na timeline - substituído o polling contínuo por temporização de cada trecho do preview - restaurado o preview de áudio dos falantes usando o WAV da transcrição Resumo: - 4 arquivos alterados - 0 novos - 4 modificados - 0 removidos 4 files changed, 29 insertions(+), 66 deletions(-) Arquivos: - .jhonny/analises.db - code/cep-plugin/index.html - code/cep-plugin/main.js - code/cep-plugin/styles.css --- .jhonny/analises.db | Bin 1069056 -> 1069056 bytes code/cep-plugin/index.html | 6 +-- code/cep-plugin/main.js | 86 ++++++++++++------------------------- code/cep-plugin/styles.css | 3 -- 4 files changed, 29 insertions(+), 66 deletions(-) diff --git a/.jhonny/analises.db b/.jhonny/analises.db index f3e0b50315e59265fecbae6e861612006bc0faa7..703e088ab2d79ceeff40e861a9d06e1050d2dc16 100644 GIT binary patch delta 83 zcmWN=yAeP@7=_V)t@m531({KR3bgPg`XIPD9c&Z2Q4DA19AQ1edX2+w<`Oe||IW-W g_cXixL^u%%FJh61RAeF-g(yWOYSD;RbPs*lK7z&PbgG@=!q=x>IwewpeQmH+?% diff --git a/code/cep-plugin/index.html b/code/cep-plugin/index.html index 16500c9..e1850c6 100755 --- a/code/cep-plugin/index.html +++ b/code/cep-plugin/index.html @@ -371,13 +371,9 @@

Identificar falantes

Nenhum falante carregado
-

Use o botão de reprodução para conferir a imagem e a voz de cada falante, informe um nome e escolha quem poderá aparecer no vídeo. A identificação será usada ao gerar o JSON de edição.

+

Use o botão de áudio para reconhecer a voz de cada falante, informe um nome e escolha quem poderá aparecer no vídeo. A identificação será usada ao gerar o JSON de edição.

Nenhum falante identificado

A análise carregada não possui diarização. Execute a diarização no Scanner para liberar esta etapa.

diff --git a/code/cep-plugin/main.js b/code/cep-plugin/main.js index 60181db..1a8f9cd 100755 --- a/code/cep-plugin/main.js +++ b/code/cep-plugin/main.js @@ -2322,20 +2322,6 @@ function silenceLoadScannerAnalysis() { var turnos = transcricao.segments.filter(function (segmento) { return segmento.falante; }).map(function (segmento) { return { speaker: segmento.falante, start: segmento.start, end: segmento.end }; }); - var intervalosDoBanco = silenceConsultarPreviewDeFalantes(silenceState.sequenceId); - if (intervalosDoBanco && intervalosDoBanco.length) { - turnos = intervalosDoBanco.map(function (intervalo) { - return { - speaker: intervalo.falante, - start: intervalo.inicio_na_timeline, - end: intervalo.fim_na_timeline, - timelineStart: intervalo.inicio_na_timeline, - timelineEnd: intervalo.fim_na_timeline, - mediaPath: intervalo.arquivo, - }; - }); - silenceState.mediaPath = intervalosDoBanco[0].arquivo || silenceState.mediaPath; - } renderSpeakerConfiguration(falantes, turnos); atualizarTelaRefinar(falantes, audioDoBanco); status.textContent = "Carregada"; @@ -2406,7 +2392,7 @@ function atualizarTelaRefinar(falantes, audioDoBanco) { var speakerAudioPlayer = null; var speakerAudioQueue = null; var speakerTimelineQueue = null; -var speakerTimelinePoll = null; +var speakerTimelineTimer = null; var speakerTimelineToken = 0; // ---- Central transcript cache ---- @@ -3014,12 +3000,11 @@ function renderSpeakerConfiguration(speakerIds, speakerTurns, alvo) { var play = document.createElement("button"); play.type = "button"; play.className = "button speaker-play-button"; - play.textContent = alvo.video ? "▶ vídeo" : "▶ áudio"; - play.title = (alvo.video ? "Ver" : "Ouvir") + " trechos de " + speaker.id; - play.setAttribute("aria-label", (alvo.video ? "Ver" : "Ouvir") + " trechos de " + speaker.id); + play.textContent = "▶ áudio"; + play.title = "Ouvir trechos de " + speaker.id; + play.setAttribute("aria-label", "Ouvir trechos de " + speaker.id); play.addEventListener("click", function () { - if (alvo.video) toggleSpeakerTimeline(speaker.id, play); - else toggleSpeakerAudio(speaker.id, play); + toggleSpeakerAudio(speaker.id, play); }); var input = document.createElement("input"); input.type = "text"; @@ -3055,7 +3040,7 @@ function renderSpeakerConfiguration(speakerIds, speakerTurns, alvo) { var refineConfig = document.getElementById("refinarSpeakerConfig"); if (refineConfig && config.id !== refineConfig.id) { renderSpeakerConfiguration(speakerIds, speakerTurns, { - config: "refinarSpeakerConfig", list: "refinarSpeakerList", count: "refinarSpeakerCount", video: true + config: "refinarSpeakerConfig", list: "refinarSpeakerList", count: "refinarSpeakerCount" }); } } @@ -3072,20 +3057,8 @@ function stopSpeakerAudio() { } speakerAudioPlayer = null; speakerAudioQueue = null; - var haviaPreviewNaTimeline = !!speakerTimelineQueue; - speakerTimelineToken += 1; - if (speakerTimelinePoll) { - clearTimeout(speakerTimelinePoll); - speakerTimelinePoll = null; - } - speakerTimelineQueue = null; - if (haviaPreviewNaTimeline) { - cs.evalScript("(function(){try{if(typeof qe!==\"undefined\"&&qe.stopPlayback)qe.stopPlayback();return \"ok\";}catch(e){return \"erro:\"+String(e);}}())", function () {}); - } - var videoPreview = document.getElementById("refinarSpeakerPreview"); - if (videoPreview) videoPreview.hidden = true; document.querySelectorAll(".speaker-play-button").forEach(function (button) { - button.textContent = button.closest("#refinarSpeakerList") ? "▶ vídeo" : "▶ áudio"; + button.textContent = "▶ áudio"; button.classList.remove("is-playing"); }); } @@ -3115,7 +3088,6 @@ function toggleSpeakerTimeline(speakerId, button) { index: 0, button: button, inicioPendente: false, - consultaPendente: false, }; preview.hidden = false; if (info) info.textContent = "Reproduzindo os trechos de " + speakerId + "."; @@ -3152,42 +3124,40 @@ function iniciarPreviewNaTimeline(token) { showToast("err", resultado.error || "Não foi possível iniciar o preview na timeline."); return; } - monitorarPreviewNaTimeline(token); + agendarFimDoTrechoNaTimeline(token, indiceDoTrecho, inicio, Number(range.end)); } ); } -function monitorarPreviewNaTimeline(token) { - if (!speakerTimelineQueue || token !== speakerTimelineToken || speakerTimelineQueue.consultaPendente) return; - var indiceDoTrecho = speakerTimelineQueue.index; - var range = speakerTimelineQueue.ranges[indiceDoTrecho]; - if (!range) { stopSpeakerAudio(); return; } - speakerTimelineQueue.consultaPendente = true; +function agendarFimDoTrechoNaTimeline(token, indiceDoTrecho, inicio, fim) { + if (!speakerTimelineQueue || token !== speakerTimelineToken || speakerTimelineQueue.index !== indiceDoTrecho) return; + var duracaoEmMilissegundos = Math.max(250, (fim - inicio) * 1000); + speakerTimelineTimer = setTimeout(function () { + speakerTimelineTimer = null; + if (!speakerTimelineQueue || token !== speakerTimelineToken || speakerTimelineQueue.index !== indiceDoTrecho) return; + pausarEAvancarPreviewNaTimeline(token); + }, duracaoEmMilissegundos); +} + +function pausarEAvancarPreviewNaTimeline(token) { + if (!speakerTimelineQueue || token !== speakerTimelineToken) return; cs.evalScript( - "(function(){try{var seq=app.project.activeSequence;return JSON.stringify({ok:!!seq,position:seq?Number(seq.getPlayerPosition().ticks)/254016000000:0});}catch(e){return JSON.stringify({ok:false,error:String(e)});}}())", + "(function(){try{if(typeof qe!==\"undefined\"&&qe.stopPlayback)qe.stopPlayback();return JSON.stringify({ok:true});}catch(e){return JSON.stringify({ok:false,error:String(e)});}}())", function (raw) { - if (!speakerTimelineQueue || token !== speakerTimelineToken || speakerTimelineQueue.index !== indiceDoTrecho) return; - speakerTimelineQueue.consultaPendente = false; + if (!speakerTimelineQueue || token !== speakerTimelineToken) return; var resultado; try { resultado = JSON.parse(raw); } catch (_) { resultado = { ok: false, error: "Resposta inválida do Premiere." }; } if (!resultado.ok) { stopSpeakerAudio(); - showToast("err", resultado.error || "Não foi possível consultar o playhead da timeline."); + showToast("err", resultado.error || "Não foi possível pausar o preview na timeline."); return; } - if (Number(resultado.position) >= Number(range.end)) { - speakerTimelineQueue.index += 1; - if (speakerTimelineQueue.index >= speakerTimelineQueue.ranges.length) { - stopSpeakerAudio(); - } else { - iniciarPreviewNaTimeline(token); - } - return; + speakerTimelineQueue.index += 1; + if (speakerTimelineQueue.index >= speakerTimelineQueue.ranges.length) { + stopSpeakerAudio(); + } else { + iniciarPreviewNaTimeline(token); } - speakerTimelinePoll = setTimeout(function () { - speakerTimelinePoll = null; - monitorarPreviewNaTimeline(token); - }, 250); } ); } diff --git a/code/cep-plugin/styles.css b/code/cep-plugin/styles.css index 28ca4b5..ccc81b0 100755 --- a/code/cep-plugin/styles.css +++ b/code/cep-plugin/styles.css @@ -491,9 +491,6 @@ textarea { padding: 8px 10px; font: 10px var(--font-mono); color: var(--text-sec .speaker-play-button.is-playing { color: var(--accent); } .speaker-name-input { width: 100%; } .speaker-active-field { margin: 0; padding: 6px 8px; white-space: nowrap; } -.speaker-video-preview { margin: 0 0 10px; padding-bottom: 10px; border-bottom: 1px solid var(--border); } -.speaker-video-preview strong { display: block; color: var(--accent); font-size: 10px; } -.speaker-video-preview .field-help { margin: 6px 0 0; } .refinar-actions { display: flex; gap: 8px; flex-wrap: wrap; } .refinar-actions .button { flex: 1 1 180px; } #refinarSpeakerConfig .button { margin-top: 10px; }