Compare commits
2
Commits
b6c1b79336
...
f02f4f3e60
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f02f4f3e60 | ||
|
|
f3e8650a1a |
+20
-14
@@ -138,6 +138,20 @@
|
|||||||
<span>Detectar quem fala logo após transcrever</span>
|
<span>Detectar quem fala logo após transcrever</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label class="checkbox-field">
|
||||||
|
<input type="checkbox" id="silenceVoiceFeaturesAuto">
|
||||||
|
<span>Calcular métricas de voz logo após transcrever</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="speaker-config" id="silenceSpeakerConfig" hidden>
|
||||||
|
<div class="speaker-config-head">
|
||||||
|
<strong>Falantes detectados</strong>
|
||||||
|
<span id="silenceSpeakerCount"></span>
|
||||||
|
</div>
|
||||||
|
<p class="field-help">Dê um nome a cada falante e desative quem não deve aparecer no vídeo. A decisão será enviada no JSON para a IA.</p>
|
||||||
|
<div id="silenceSpeakerList"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mini-action" id="silenceRemovalRow">
|
<div class="mini-action" id="silenceRemovalRow">
|
||||||
<div>
|
<div>
|
||||||
<label class="checkbox-field" style="border:none;padding:0;background:none">
|
<label class="checkbox-field" style="border:none;padding:0;background:none">
|
||||||
@@ -161,33 +175,25 @@
|
|||||||
<div class="step-head">
|
<div class="step-head">
|
||||||
<span class="step-number" aria-hidden="true">3</span>
|
<span class="step-number" aria-hidden="true">3</span>
|
||||||
<div class="step-title">
|
<div class="step-title">
|
||||||
<h2>Enriquecer a transcrição <span class="badge-optional">opcional</span></h2>
|
<h2>Revisar falantes e áudio <span class="badge-optional">opcional</span></h2>
|
||||||
<p>Dados extras que deixam o corte por IA mais preciso.</p>
|
<p>Confira os resultados processados e ajuste os dados antes de gerar o JSON.</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="step-chip" id="step3Chip">Bloqueado</span>
|
<span class="step-chip" id="step3Chip">Bloqueado</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="step-body">
|
<div class="step-body">
|
||||||
<div class="mini-action">
|
<div class="mini-action">
|
||||||
<div>
|
<div>
|
||||||
<strong>Quem fala</strong>
|
<strong>Detecção de falantes</strong>
|
||||||
<span id="silenceDiarizeInfo">Separa os locutores por trecho. Precisa do token Hugging Face.</span>
|
<span id="silenceDiarizeInfo">Separa os falantes por trecho. Precisa do token Hugging Face.</span>
|
||||||
</div>
|
</div>
|
||||||
<button id="btnDiarize" class="button" onclick="silenceDiarizeSpeakers()" type="button" disabled>Detectar</button>
|
<button id="btnDiarize" class="button" onclick="silenceDiarizeSpeakers()" type="button" disabled>Refazer</button>
|
||||||
</div>
|
|
||||||
<div class="speaker-config" id="silenceSpeakerConfig" hidden>
|
|
||||||
<div class="speaker-config-head">
|
|
||||||
<strong>Falantes identificados</strong>
|
|
||||||
<span id="silenceSpeakerCount"></span>
|
|
||||||
</div>
|
|
||||||
<p class="field-help">Dê um nome a cada falante e desative quem não deve aparecer no vídeo. A decisão será enviada no JSON para a IA.</p>
|
|
||||||
<div id="silenceSpeakerList"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mini-action">
|
<div class="mini-action">
|
||||||
<div>
|
<div>
|
||||||
<strong>Métricas de voz</strong>
|
<strong>Métricas de voz</strong>
|
||||||
<span id="silenceVoiceFeaturesInfo">Pitch, energia, velocidade de fala e pausas de cada trecho.</span>
|
<span id="silenceVoiceFeaturesInfo">Pitch, energia, velocidade de fala e pausas de cada trecho.</span>
|
||||||
</div>
|
</div>
|
||||||
<button id="btnVoiceFeatures" class="button" onclick="silenceComputeVoiceFeatures()" type="button" disabled>Calcular</button>
|
<button id="btnVoiceFeatures" class="button" onclick="silenceComputeVoiceFeatures()" type="button" disabled>Refazer</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
+21
-6
@@ -1786,15 +1786,25 @@ function silenceTranscribe() {
|
|||||||
}
|
}
|
||||||
taskEnd(true, "Transcrição pronta: " + resumo);
|
taskEnd(true, "Transcrição pronta: " + resumo);
|
||||||
unlockAfterTranscript();
|
unlockAfterTranscript();
|
||||||
if (document.getElementById("silenceDiarize").checked) {
|
silenceRunAutomaticEnrichments();
|
||||||
silenceDiarizeSpeakers();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
hfSpawnOptions()
|
hfSpawnOptions()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function silenceDiarizeSpeakers() {
|
function silenceRunAutomaticEnrichments() {
|
||||||
|
var shouldDiarize = document.getElementById("silenceDiarize").checked && !!loadHfToken();
|
||||||
|
var shouldMeasureVoice = document.getElementById("silenceVoiceFeaturesAuto").checked;
|
||||||
|
if (shouldDiarize) {
|
||||||
|
silenceDiarizeSpeakers(function () {
|
||||||
|
if (shouldMeasureVoice) silenceComputeVoiceFeatures();
|
||||||
|
});
|
||||||
|
} else if (shouldMeasureVoice) {
|
||||||
|
silenceComputeVoiceFeatures();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function silenceDiarizeSpeakers(onFinished) {
|
||||||
if (!silenceState.transcriptPath) return;
|
if (!silenceState.transcriptPath) return;
|
||||||
if (!silenceState.mediaPath) {
|
if (!silenceState.mediaPath) {
|
||||||
silenceLog("Detecte o clipe/sequência primeiro (passo 1) para saber qual vídeo diarizar.", "err");
|
silenceLog("Detecte o clipe/sequência primeiro (passo 1) para saber qual vídeo diarizar.", "err");
|
||||||
@@ -1835,12 +1845,15 @@ function silenceDiarizeSpeakers() {
|
|||||||
var parsed = null;
|
var parsed = null;
|
||||||
try { parsed = JSON.parse(fs.readFileSync(silenceState.transcriptPath, "utf-8")).diarization; } catch (e) {}
|
try { parsed = JSON.parse(fs.readFileSync(silenceState.transcriptPath, "utf-8")).diarization; } catch (e) {}
|
||||||
if (parsed && Array.isArray(parsed.speakers)) renderSpeakerConfiguration(parsed.speakers);
|
if (parsed && Array.isArray(parsed.speakers)) renderSpeakerConfiguration(parsed.speakers);
|
||||||
var msg = parsed ? parsed.num_speakers + " locutor(es): " + parsed.speakers.join(", ") : "Locutores detectados.";
|
var msg = parsed
|
||||||
|
? "Foram detectados " + parsed.num_speakers + (parsed.num_speakers === 1 ? " falante" : " falantes") + ": " + parsed.speakers.join(", ") + "."
|
||||||
|
: "Falantes detectados.";
|
||||||
silenceLog(msg, "ok");
|
silenceLog(msg, "ok");
|
||||||
info.textContent = msg;
|
info.textContent = msg;
|
||||||
setStep(3, "done", "Enriquecido");
|
setStep(3, "done", "Enriquecido");
|
||||||
taskEnd(true, msg);
|
taskEnd(true, msg);
|
||||||
syncTranscriptToCache();
|
syncTranscriptToCache();
|
||||||
|
if (typeof onFinished === "function") onFinished();
|
||||||
},
|
},
|
||||||
hfSpawnOptions()
|
hfSpawnOptions()
|
||||||
);
|
);
|
||||||
@@ -1865,7 +1878,8 @@ function renderSpeakerConfiguration(speakerIds) {
|
|||||||
active: !old || old.active !== false,
|
active: !old || old.active !== false,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
count.textContent = silenceState.speakers.length + (silenceState.speakers.length === 1 ? " identificado" : " identificados");
|
count.textContent = silenceState.speakers.length +
|
||||||
|
(silenceState.speakers.length === 1 ? " falante detectado" : " falantes detectados");
|
||||||
list.innerHTML = "";
|
list.innerHTML = "";
|
||||||
silenceState.speakers.forEach(function (speaker, index) {
|
silenceState.speakers.forEach(function (speaker, index) {
|
||||||
var row = document.createElement("div");
|
var row = document.createElement("div");
|
||||||
@@ -1877,6 +1891,7 @@ function renderSpeakerConfiguration(speakerIds) {
|
|||||||
input.type = "text";
|
input.type = "text";
|
||||||
input.className = "select-field speaker-name-input";
|
input.className = "select-field speaker-name-input";
|
||||||
input.value = speaker.name;
|
input.value = speaker.name;
|
||||||
|
input.placeholder = "Nome do falante";
|
||||||
input.maxLength = 120;
|
input.maxLength = 120;
|
||||||
input.setAttribute("aria-label", "Nome de " + speaker.id);
|
input.setAttribute("aria-label", "Nome de " + speaker.id);
|
||||||
input.addEventListener("input", function () { silenceState.speakers[index].name = input.value.trim() || speaker.id; });
|
input.addEventListener("input", function () { silenceState.speakers[index].name = input.value.trim() || speaker.id; });
|
||||||
|
|||||||
Reference in New Issue
Block a user