All checks were successful
Deploy ASP.NET MVC to OCI / build-and-deploy (push) Successful in 21m10s
123 lines
4.8 KiB
Plaintext
123 lines
4.8 KiB
Plaintext
@{
|
|
ViewData["Title"] = "Texto para Áudio (Voz)";
|
|
}
|
|
|
|
<div class="text-center mb-5">
|
|
<h1 class="display-4">@ViewData["Title"]</h1>
|
|
<p class="lead">Converta qualquer texto em fala usando vozes neurais de alta qualidade.</p>
|
|
</div>
|
|
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-8">
|
|
<div class="card shadow-custom p-4">
|
|
<div class="mb-4">
|
|
<label for="textInput" class="form-label h5">Digite ou cole seu texto</label>
|
|
<textarea class="form-control" id="textInput" rows="6" placeholder="Escreva aqui o que você deseja que seja lido..."></textarea>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<label for="voiceSelect" class="form-label">Escolher Voz</label>
|
|
<select id="voiceSelect" class="form-select"></select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="rate" class="form-label">Velocidade</label>
|
|
<input type="range" class="form-range" min="0.5" max="2" step="0.1" id="rate" value="1">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="pitch" class="form-label">Tom</label>
|
|
<input type="range" class="form-range" min="0" max="2" step="0.1" id="pitch" value="1">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-grid gap-2 d-md-flex justify-content-md-center">
|
|
<button type="button" class="btn btn-primary btn-lg px-5" onclick="speak()">
|
|
<i class="bi bi-play-fill me-2"></i>Ouvir
|
|
</button>
|
|
<button type="button" class="btn btn-outline-danger btn-lg" onclick="stop()">
|
|
<i class="bi bi-stop-fill me-2"></i>Parar
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-4 alert alert-info">
|
|
<i class="bi bi-info-circle me-2"></i>
|
|
Esta ferramenta usa as vozes instaladas no seu dispositivo. No Android e Windows, você encontrará opções de vozes neurais muito naturais.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@section Scripts {
|
|
<script>
|
|
const synth = window.speechSynthesis;
|
|
const voiceSelect = document.querySelector('#voiceSelect');
|
|
const textInput = document.querySelector('#textInput');
|
|
const rate = document.querySelector('#rate');
|
|
const pitch = document.querySelector('#pitch');
|
|
|
|
let voices = [];
|
|
|
|
function populateVoiceList() {
|
|
voices = synth.getVoices().sort(function (a, b) {
|
|
const aname = a.name.toUpperCase();
|
|
const bname = b.name.toUpperCase();
|
|
if (aname < bname) return -1;
|
|
else if (aname > bname) return 1;
|
|
else return 0;
|
|
});
|
|
|
|
const selectedIndex = voiceSelect.selectedIndex < 0 ? 0 : voiceSelect.selectedIndex;
|
|
voiceSelect.innerHTML = '';
|
|
|
|
for (let i = 0; i < voices.length; i++) {
|
|
const option = document.createElement('option');
|
|
option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
|
|
|
|
if (voices[i].default) {
|
|
option.textContent += ' -- PADRÃO';
|
|
}
|
|
|
|
option.setAttribute('data-lang', voices[i].lang);
|
|
option.setAttribute('data-name', voices[i].name);
|
|
voiceSelect.appendChild(option);
|
|
}
|
|
voiceSelect.selectedIndex = selectedIndex;
|
|
}
|
|
|
|
populateVoiceList();
|
|
if (speechSynthesis.onvoiceschanged !== undefined) {
|
|
speechSynthesis.onvoiceschanged = populateVoiceList;
|
|
}
|
|
|
|
function speak() {
|
|
if (synth.speaking) {
|
|
console.error('speechSynthesis.speaking');
|
|
return;
|
|
}
|
|
if (textInput.value !== '') {
|
|
const utterThis = new SpeechSynthesisUtterance(textInput.value);
|
|
utterThis.onend = function (event) {
|
|
console.log('SpeechSynthesisUtterance.onend');
|
|
}
|
|
utterThis.onerror = function (event) {
|
|
console.error('SpeechSynthesisUtterance.onerror');
|
|
}
|
|
const selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
|
|
for (let i = 0; i < voices.length; i++) {
|
|
if (voices[i].name === selectedOption) {
|
|
utterThis.voice = voices[i];
|
|
break;
|
|
}
|
|
}
|
|
utterThis.pitch = pitch.value;
|
|
utterThis.rate = rate.value;
|
|
synth.speak(utterThis);
|
|
}
|
|
}
|
|
|
|
function stop() {
|
|
synth.cancel();
|
|
}
|
|
</script>
|
|
}
|