feat: adicionada configuração de nomes e status dos falantes no JS
- adicionada configuração de nomes e status dos falantes no JSON da guia Editar vídeo Resumo: - 3 arquivos alterados - 0 novos - 3 modificados - 0 removidos 3 files changed, 108 insertions(+), 1 deletion(-) Arquivos: - code/cep-plugin/index.html - code/cep-plugin/main.js - code/cep-plugin/styles.css
This commit is contained in:
@@ -1331,6 +1331,7 @@ var silenceState = {
|
||||
transcribeModel: null,
|
||||
cachedTranscriptPath: null,
|
||||
jsonOutputPath: null,
|
||||
speakers: [],
|
||||
};
|
||||
|
||||
// ---- Central transcript cache ----
|
||||
@@ -1485,6 +1486,9 @@ function silenceDetectClip() {
|
||||
silenceState.outputDir = path.join(SILENCE_OUTPUT_ROOT, silenceState.fileBaseName);
|
||||
silenceState.transcriptPath = null;
|
||||
silenceState.jsonOutputPath = null;
|
||||
silenceState.speakers = [];
|
||||
var speakerConfig = document.getElementById("silenceSpeakerConfig");
|
||||
if (speakerConfig) speakerConfig.hidden = true;
|
||||
|
||||
document.getElementById("clipSequenceName").textContent = result.sequenceName;
|
||||
document.getElementById("clipFileName").textContent = path.basename(result.mediaPath);
|
||||
@@ -1554,6 +1558,7 @@ function silenceUseCachedTranscript() {
|
||||
silenceState.transcriptPath = entry.transcriptPath;
|
||||
silenceState.transcribeModel = entry.model;
|
||||
silenceState.cachedTranscriptPath = entry.transcriptPath;
|
||||
silenceLoadSpeakerConfiguration();
|
||||
document.getElementById("silenceCacheInfo").textContent =
|
||||
"Usando a transcrição salva em " + new Date(entry.savedAt).toLocaleString() + ".";
|
||||
unlockAfterTranscript();
|
||||
@@ -1676,6 +1681,9 @@ function silenceTranscribe() {
|
||||
}
|
||||
silenceState.transcriptPath = out;
|
||||
silenceState.transcribeModel = model;
|
||||
silenceState.speakers = [];
|
||||
var speakerConfig = document.getElementById("silenceSpeakerConfig");
|
||||
if (speakerConfig) speakerConfig.hidden = true;
|
||||
var resumo = parsed.segments + " trechos · " + Math.round(parsed.duration) + "s de áudio";
|
||||
silenceLog("Transcrição concluída: " + resumo, "ok");
|
||||
document.getElementById("silenceCacheInfo").textContent = "Transcrição pronta — " + resumo + ".";
|
||||
@@ -1734,6 +1742,7 @@ function silenceDiarizeSpeakers() {
|
||||
}
|
||||
var parsed = null;
|
||||
try { parsed = JSON.parse(fs.readFileSync(silenceState.transcriptPath, "utf-8")).diarization; } catch (e) {}
|
||||
if (parsed && Array.isArray(parsed.speakers)) renderSpeakerConfiguration(parsed.speakers);
|
||||
var msg = parsed ? parsed.num_speakers + " locutor(es): " + parsed.speakers.join(", ") : "Locutores detectados.";
|
||||
silenceLog(msg, "ok");
|
||||
info.textContent = msg;
|
||||
@@ -1745,6 +1754,88 @@ function silenceDiarizeSpeakers() {
|
||||
);
|
||||
}
|
||||
|
||||
function speakerNameDefault(speakerId) {
|
||||
return speakerId;
|
||||
}
|
||||
|
||||
function renderSpeakerConfiguration(speakerIds) {
|
||||
var config = document.getElementById("silenceSpeakerConfig");
|
||||
var list = document.getElementById("silenceSpeakerList");
|
||||
var count = document.getElementById("silenceSpeakerCount");
|
||||
if (!config || !list || !count) return;
|
||||
var previous = {};
|
||||
silenceState.speakers.forEach(function (speaker) { previous[speaker.id] = speaker; });
|
||||
silenceState.speakers = speakerIds.map(function (id) {
|
||||
var old = previous[id];
|
||||
return {
|
||||
id: id,
|
||||
name: old && old.name ? old.name : speakerNameDefault(id),
|
||||
active: !old || old.active !== false,
|
||||
};
|
||||
});
|
||||
count.textContent = silenceState.speakers.length + (silenceState.speakers.length === 1 ? " identificado" : " identificados");
|
||||
list.innerHTML = "";
|
||||
silenceState.speakers.forEach(function (speaker, index) {
|
||||
var row = document.createElement("div");
|
||||
row.className = "speaker-row";
|
||||
var label = document.createElement("label");
|
||||
label.className = "field-label";
|
||||
label.textContent = speaker.id;
|
||||
var input = document.createElement("input");
|
||||
input.type = "text";
|
||||
input.className = "select-field speaker-name-input";
|
||||
input.value = speaker.name;
|
||||
input.maxLength = 120;
|
||||
input.setAttribute("aria-label", "Nome de " + speaker.id);
|
||||
input.addEventListener("input", function () { silenceState.speakers[index].name = input.value.trim() || speaker.id; });
|
||||
var activeLabel = document.createElement("label");
|
||||
activeLabel.className = "checkbox-field speaker-active-field";
|
||||
var active = document.createElement("input");
|
||||
active.type = "checkbox";
|
||||
active.checked = speaker.active;
|
||||
active.addEventListener("change", function () { silenceState.speakers[index].active = active.checked; });
|
||||
var activeText = document.createElement("span");
|
||||
activeText.textContent = "Incluir no vídeo";
|
||||
activeLabel.appendChild(active);
|
||||
activeLabel.appendChild(activeText);
|
||||
row.appendChild(label);
|
||||
row.appendChild(input);
|
||||
row.appendChild(activeLabel);
|
||||
list.appendChild(row);
|
||||
});
|
||||
config.hidden = silenceState.speakers.length === 0;
|
||||
}
|
||||
|
||||
function silenceLoadSpeakerConfiguration() {
|
||||
if (!silenceState.transcriptPath) return;
|
||||
try {
|
||||
var transcript = JSON.parse(fs.readFileSync(silenceState.transcriptPath, "utf-8"));
|
||||
var diarization = transcript.diarization;
|
||||
if (diarization && Array.isArray(diarization.speakers)) renderSpeakerConfiguration(diarization.speakers);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function speakerConfigurationForJson() {
|
||||
var speakers = silenceState.speakers.map(function (speaker) {
|
||||
var active = speaker.active !== false;
|
||||
return {
|
||||
id: speaker.id,
|
||||
name: speaker.name || speaker.id,
|
||||
status: active ? "active" : "inactive",
|
||||
include_in_video: active,
|
||||
editorial_instruction: active
|
||||
? "Manter as falas deste falante, salvo decisão específica da IA."
|
||||
: "Excluir todas as falas deste falante do vídeo final.",
|
||||
};
|
||||
});
|
||||
return {
|
||||
total_detected: speakers.length,
|
||||
speakers: speakers,
|
||||
inactive_speakers: speakers.filter(function (speaker) { return !speaker.include_in_video; }).map(function (speaker) { return speaker.id; }),
|
||||
instruction: "Falantes inativos devem ter todas as suas falas removidas do vídeo final; não confundir nome com identidade confirmada.",
|
||||
};
|
||||
}
|
||||
|
||||
// Depois de mutar silenceState.transcriptPath em lugar (diarização, métricas de
|
||||
// voz), propaga a mudança pra cópia central de cache, se forem arquivos diferentes.
|
||||
function syncTranscriptToCache() {
|
||||
@@ -1818,6 +1909,7 @@ function silenceGenerateJson() {
|
||||
transcript.settings = Object.assign({}, transcript.settings, {
|
||||
silence_removal: { enabled: silenceEnabled, min_silence_seconds: minSilence },
|
||||
});
|
||||
transcript.speaker_configuration = speakerConfigurationForJson();
|
||||
|
||||
ensureDir(silenceState.outputDir);
|
||||
var out = path.join(silenceState.outputDir, "dados-para-ia.json");
|
||||
|
||||
Reference in New Issue
Block a user