diff --git a/.jhonny/analises.db b/.jhonny/analises.db
index 3529444..46f5302 100644
Binary files a/.jhonny/analises.db and b/.jhonny/analises.db differ
diff --git a/.jhonny/analises.db-shm b/.jhonny/analises.db-shm
deleted file mode 100644
index fe9ac28..0000000
Binary files a/.jhonny/analises.db-shm and /dev/null differ
diff --git a/.jhonny/analises.db-wal b/.jhonny/analises.db-wal
deleted file mode 100644
index e69de29..0000000
diff --git a/code/cep-plugin/index.html b/code/cep-plugin/index.html
index 22897d6..16500c9 100755
--- a/code/cep-plugin/index.html
+++ b/code/cep-plugin/index.html
@@ -375,7 +375,7 @@
-
+
Preview na timeline do Premiere
Reproduzindo os trechos do falante selecionado.
diff --git a/code/cep-plugin/main.js b/code/cep-plugin/main.js
index c27fde8..50af95c 100755
--- a/code/cep-plugin/main.js
+++ b/code/cep-plugin/main.js
@@ -2327,8 +2327,8 @@ function silenceLoadScannerAnalysis() {
turnos = intervalosDoBanco.map(function (intervalo) {
return {
speaker: intervalo.falante,
- start: intervalo.inicio,
- end: intervalo.fim,
+ start: intervalo.inicio_na_timeline,
+ end: intervalo.fim_na_timeline,
timelineStart: intervalo.inicio_na_timeline,
timelineEnd: intervalo.fim_na_timeline,
mediaPath: intervalo.arquivo,
@@ -2405,8 +2405,9 @@ function atualizarTelaRefinar(falantes, audioDoBanco) {
var speakerAudioPlayer = null;
var speakerAudioQueue = null;
-var speakerVideoPlayer = null;
-var speakerVideoQueue = null;
+var speakerTimelineQueue = null;
+var speakerTimelinePoll = null;
+var speakerTimelineToken = 0;
// ---- Central transcript cache ----
// Evita rodar o Whisper de novo para um vídeo já transcrito antes: indexa
@@ -3017,7 +3018,7 @@ function renderSpeakerConfiguration(speakerIds, speakerTurns, alvo) {
play.title = (alvo.video ? "Ver" : "Ouvir") + " trechos de " + speaker.id;
play.setAttribute("aria-label", (alvo.video ? "Ver" : "Ouvir") + " trechos de " + speaker.id);
play.addEventListener("click", function () {
- if (alvo.video) toggleSpeakerVideo(speaker.id, play);
+ if (alvo.video) toggleSpeakerTimeline(speaker.id, play);
else toggleSpeakerAudio(speaker.id, play);
});
var input = document.createElement("input");
@@ -3071,17 +3072,13 @@ function stopSpeakerAudio() {
}
speakerAudioPlayer = null;
speakerAudioQueue = null;
- if (speakerVideoPlayer) {
- speakerVideoPlayer.pause();
- speakerVideoPlayer.onloadedmetadata = null;
- speakerVideoPlayer.ontimeupdate = null;
- speakerVideoPlayer.onended = null;
- speakerVideoPlayer.onerror = null;
- speakerVideoPlayer.removeAttribute("src");
- speakerVideoPlayer.load();
+ speakerTimelineToken += 1;
+ if (speakerTimelinePoll) {
+ clearInterval(speakerTimelinePoll);
+ speakerTimelinePoll = null;
}
- speakerVideoPlayer = null;
- speakerVideoQueue = null;
+ speakerTimelineQueue = null;
+ 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) {
@@ -3090,8 +3087,8 @@ function stopSpeakerAudio() {
});
}
-function toggleSpeakerVideo(speakerId, button) {
- if (speakerVideoPlayer && speakerVideoQueue && speakerVideoQueue.speakerId === speakerId) {
+function toggleSpeakerTimeline(speakerId, button) {
+ if (speakerTimelineQueue && speakerTimelineQueue.speakerId === speakerId) {
stopSpeakerAudio();
return;
}
@@ -3103,53 +3100,71 @@ function toggleSpeakerVideo(speakerId, button) {
showToast("err", "Não há intervalos de vídeo disponíveis para " + speakerId + ".");
return;
}
- if (!silenceState.mediaPath || !fs.existsSync(silenceState.mediaPath)) {
- showToast("err", "Arquivo de vídeo da análise não encontrado.");
- return;
- }
- var video = document.getElementById("refinarSpeakerVideo");
var preview = document.getElementById("refinarSpeakerPreview");
var info = document.getElementById("refinarSpeakerPreviewInfo");
- if (!video || !preview) {
+ if (!preview) {
showToast("err", "Preview de vídeo indisponível nesta versão do painel.");
return;
}
- speakerVideoQueue = { speakerId: speakerId, ranges: ranges, index: 0, button: button };
- speakerVideoPlayer = video;
+ speakerTimelineQueue = { speakerId: speakerId, ranges: ranges, index: 0, button: button };
preview.hidden = false;
if (info) info.textContent = "Reproduzindo os trechos de " + speakerId + ".";
- video.onloadedmetadata = playCurrentSpeakerVideoRange;
- video.ontimeupdate = advanceSpeakerVideoRange;
- video.onended = advanceSpeakerVideoRange;
- video.onerror = function () {
- stopSpeakerAudio();
- showToast("err", "Não foi possível reproduzir o vídeo deste falante.");
- };
- button.textContent = "■ vídeo";
+ button.textContent = "■ timeline";
button.classList.add("is-playing");
- video.src = speakerMediaFileUrl(silenceState.mediaPath);
- video.load();
+ iniciarPreviewNaTimeline(speakerTimelineToken);
}
-function playCurrentSpeakerVideoRange() {
- if (!speakerVideoPlayer || !speakerVideoQueue) return;
- var range = speakerVideoQueue.ranges[speakerVideoQueue.index];
+function iniciarPreviewNaTimeline(token) {
+ if (!speakerTimelineQueue || token !== speakerTimelineToken) return;
+ var range = speakerTimelineQueue.ranges[speakerTimelineQueue.index];
if (!range) { stopSpeakerAudio(); return; }
- speakerVideoPlayer.currentTime = Math.max(0, Number(range.start) - 0.15);
- var playPromise = speakerVideoPlayer.play();
- if (playPromise && playPromise.catch) playPromise.catch(function () { stopSpeakerAudio(); });
+ var inicio = Math.max(0, Number(range.start) - 0.15);
+ var inicioJson = JSON.stringify(inicio);
+ cs.evalScript(
+ "(function(){try{" +
+ "var seq=app.project.activeSequence;" +
+ "if(!seq)return JSON.stringify({ok:false,error:'Nenhuma sequência ativa.'});" +
+ "if(String(seq.sequenceID)!==" + JSON.stringify(String(silenceState.sequenceId)) + ")return JSON.stringify({ok:false,error:'A sequência da análise não está ativa.'});" +
+ "seq.setPlayerPosition(String(Math.round(" + inicioJson + "*254016000000)));" +
+ "app.enableQE();qe.startPlayback();" +
+ "return JSON.stringify({ok:true});" +
+ "}catch(e){return JSON.stringify({ok:false,error:String(e)});}}())",
+ function (raw) {
+ 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 iniciar o preview na timeline.");
+ return;
+ }
+ monitorarPreviewNaTimeline(token);
+ }
+ );
}
-function advanceSpeakerVideoRange() {
- if (!speakerVideoPlayer || !speakerVideoQueue) return;
- var range = speakerVideoQueue.ranges[speakerVideoQueue.index];
- if (!range || speakerVideoPlayer.currentTime < Number(range.end)) return;
- speakerVideoQueue.index += 1;
- if (speakerVideoQueue.index >= speakerVideoQueue.ranges.length) {
- stopSpeakerAudio();
- return;
- }
- playCurrentSpeakerVideoRange();
+function monitorarPreviewNaTimeline(token) {
+ if (speakerTimelinePoll) clearInterval(speakerTimelinePoll);
+ speakerTimelinePoll = setInterval(function () {
+ if (!speakerTimelineQueue || token !== speakerTimelineToken) return;
+ var range = speakerTimelineQueue.ranges[speakerTimelineQueue.index];
+ 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 (raw) {
+ if (!speakerTimelineQueue || token !== speakerTimelineToken) return;
+ var resultado;
+ try { resultado = JSON.parse(raw); } catch (_) { return; }
+ if (!resultado.ok || Number(resultado.position) >= Number(range.end)) {
+ speakerTimelineQueue.index += 1;
+ if (speakerTimelineQueue.index >= speakerTimelineQueue.ranges.length) {
+ stopSpeakerAudio();
+ } else {
+ iniciarPreviewNaTimeline(token);
+ }
+ }
+ }
+ );
+ }, 120);
}
function toggleSpeakerAudio(speakerId, button) {
diff --git a/code/cep-plugin/styles.css b/code/cep-plugin/styles.css
index 3e7d43c..28ca4b5 100755
--- a/code/cep-plugin/styles.css
+++ b/code/cep-plugin/styles.css
@@ -492,7 +492,7 @@ textarea { padding: 8px 10px; font: 10px var(--font-mono); color: var(--text-sec
.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 video { display: block; width: 100%; max-height: 260px; border-radius: 5px; background: #000; }
+.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; }