Áudio
Conteúdo entregue exclusivamente por som. Ideal para aprendizes em mobilidade, revisão de conteúdo ou situações onde a tela não está disponível.
Experimente
As Fases do Sono
Narração sobre o que acontece no corpo em cada fase de um ciclo de sono, do adormecer ao sono REM. O áudio é a leitura exata do texto abaixo.
Texto do áudio
Quando você fecha os olhos para dormir, o cérebro não desliga: ele passa por um ciclo de fases bem definidas, que se repete várias vezes ao longo da noite. A primeira fase é a transição entre estar acordado e dormir. Nela, a atividade cerebral desacelera, os músculos relaxam e é comum sentir pequenos espasmos, como se você estivesse caindo — um reflexo natural chamado mioclonia hípnica. Essa fase dura poucos minutos e serve como a porta de entrada para o sono mais profundo.
Em seguida vem o sono leve, que ocupa a maior parte da noite. O corpo continua a desacelerar: a temperatura cai, os batimentos cardíacos ficam mais lentos e o cérebro produz ondas cerebrais características chamadas fusos do sono. Ainda é relativamente fácil acordar nessa fase, e é aqui que o cérebro começa a organizar as memórias recentes, decidindo o que vale a pena consolidar.
Depois entra o sono profundo, também chamado de sono de ondas lentas. É a fase mais restauradora fisicamente: o corpo libera hormônio do crescimento, repara tecidos e fortalece o sistema imunológico. Acordar alguém nesse estágio é muito mais difícil, e quem é despertado costuma sentir uma confusão passageira, conhecida como inércia do sono.
Por fim, o cérebro entra no sono REM, sigla para movimento rápido dos olhos. É quando a maioria dos sonhos vívidos acontece: a atividade cerebral se aproxima da vigília, os olhos se movem rapidamente sob as pálpebras fechadas, mas os músculos do corpo ficam temporariamente paralisados, evitando que a pessoa represente fisicamente o que está sonhando. Um ciclo completo, do início ao sono REM, dura cerca de noventa minutos — e se repete de quatro a seis vezes por noite.
Neste episódio
Código-fonte
Dados de exemplo
O título e os parágrafos que serão lidos em voz alta — o áudio é a leitura exata deste texto, nada mais.
| 1 |
<?php
|
| 2 |
$titulo = 'As Camadas da Atmosfera';
|
| 3 |
$paragrafos = [
|
| 4 |
'A camada mais próxima do solo é a troposfera, que vai até cerca de doze quilômetros de altura. É onde o ar é mais denso e onde acontece praticamente todo o clima que sentimos: nuvens, chuva e vento.',
|
| 5 |
'Acima dela fica a estratosfera, que se estende até uns cinquenta quilômetros. É nessa camada que vive a maior parte do ozônio da atmosfera, absorvendo boa parte da radiação ultravioleta do Sol antes que ela chegue ao solo.',
|
| 6 |
'Mais alto ainda está a mesosfera, até cerca de oitenta e cinco quilômetros. É a camada mais fria da atmosfera, e é onde a maioria dos meteoros queima ao entrar — o que vemos como estrelas cadentes acontece bem ali.',
|
| 7 |
'Por fim, a termosfera se estende por centenas de quilômetros. Apesar do nome, o ar ali é extremamente rarefeito; é a camada onde ocorrem as auroras e onde orbita a maior parte dos satélites, incluindo a Estação Espacial Internacional.'
|
| 8 |
];
|
| 9 |
?>
|
Texto de leitura e player
O texto fica visível o tempo todo — clicar num parágrafo pula a leitura pra ele.
| 1 |
<div class="audio-demo" data-tipo="audio-tts">
|
| 2 |
|
| 3 |
<div class="audio-cabecalho">
|
| 4 |
<p><?= htmlspecialchars($titulo) ?></p>
|
| 5 |
</div>
|
| 6 |
|
| 7 |
<div class="audio-texto">
|
| 8 |
<?php foreach ($paragrafos as $paragrafo): ?>
|
| 9 |
<p class="audio-paragrafo"><?= htmlspecialchars($paragrafo) ?></p>
|
| 10 |
<?php endforeach; ?>
|
| 11 |
</div>
|
Barra de progresso e botão
A barra reflete a posição real dentro da fala, não um cronômetro simulado.
| 1 |
<div class="audio-barra-trilha">
|
| 2 |
<div class="audio-barra"></div>
|
| 3 |
</div>
|
| 4 |
|
| 5 |
<div class="audio-controles">
|
| 6 |
<button type="button" class="audio-play">Reproduzir</button>
|
| 7 |
</div>
|
| 8 |
|
| 9 |
</div>
|
Card e cabeçalho
Contêiner geral e a caixa de título centralizada.
| 1 |
.audio-demo {
|
| 2 |
max-width: 560px;
|
| 3 |
border: 1px solid #e2e8f0;
|
| 4 |
border-radius: 16px;
|
| 5 |
background: #fff;
|
| 6 |
font-family: sans-serif;
|
| 7 |
overflow: hidden;
|
| 8 |
}
|
| 9 |
|
| 10 |
.audio-cabecalho {
|
| 11 |
padding: 20px 24px;
|
| 12 |
border-bottom: 1px solid #cbd5e1;
|
| 13 |
background: rgba(241, 245, 249, .6);
|
| 14 |
text-align: center;
|
| 15 |
}
|
| 16 |
|
| 17 |
.audio-cabecalho p {
|
| 18 |
margin: 0;
|
| 19 |
font-weight: 700;
|
| 20 |
font-size: 18px;
|
| 21 |
color: #0f172a;
|
| 22 |
}
|
Texto de leitura
O parágrafo em leitura ganha destaque enquanto a fala passa por ele.
| 1 |
.audio-texto {
|
| 2 |
padding: 20px 24px 4px;
|
| 3 |
color: #475569;
|
| 4 |
line-height: 1.6;
|
| 5 |
}
|
| 6 |
|
| 7 |
.audio-paragrafo {
|
| 8 |
margin: 0 0 12px;
|
| 9 |
padding: 6px 8px;
|
| 10 |
border-radius: 8px;
|
| 11 |
cursor: pointer;
|
| 12 |
transition: background-color .2s, color .2s;
|
| 13 |
}
|
| 14 |
|
| 15 |
.audio-paragrafo.ativo {
|
| 16 |
background: rgba(139, 92, 246, .1);
|
| 17 |
color: #1e293b;
|
| 18 |
}
|
Barra de progresso
A largura reflete a posição real dentro da fala, não um cronômetro simulado.
| 1 |
.audio-barra-trilha {
|
| 2 |
margin: 4px 24px 16px;
|
| 3 |
height: 6px;
|
| 4 |
border-radius: 999px;
|
| 5 |
background: #e2e8f0;
|
| 6 |
overflow: hidden;
|
| 7 |
}
|
| 8 |
|
| 9 |
.audio-barra {
|
| 10 |
height: 100%;
|
| 11 |
width: 0%;
|
| 12 |
border-radius: 999px;
|
| 13 |
background: #8b5cf6;
|
| 14 |
transition: width .2s linear;
|
| 15 |
}
|
Botão de reprodução
O mesmo botão alterna entre "Reproduzir" e "Pausar".
| 1 |
.audio-controles {
|
| 2 |
padding: 0 24px 24px;
|
| 3 |
text-align: center;
|
| 4 |
}
|
| 5 |
|
| 6 |
.audio-play {
|
| 7 |
padding: 12px 28px;
|
| 8 |
border: none;
|
| 9 |
border-radius: 999px;
|
| 10 |
background: #8b5cf6;
|
| 11 |
color: #fff;
|
| 12 |
font: inherit;
|
| 13 |
font-weight: 600;
|
| 14 |
cursor: pointer;
|
| 15 |
}
|
Preparar o texto e o estado
O texto que a fala vai ler é o mesmo texto já exibido na tela, concatenado.
| 1 |
document.addEventListener('DOMContentLoaded', function () {
|
| 2 |
var demo = document.querySelector('[data-tipo="audio-tts"]');
|
| 3 |
var paragrafos = demo.querySelectorAll('.audio-paragrafo');
|
| 4 |
var texto = Array.prototype.map.call(paragrafos, function (p) { return p.textContent; }).join('\n\n');
|
| 5 |
var barra = demo.querySelector('.audio-barra');
|
| 6 |
var playBtn = demo.querySelector('.audio-play');
|
| 7 |
|
| 8 |
var posicao = 0;
|
| 9 |
var tocando = false;
|
| 10 |
// Cada fala nova ganha uma geração; um evento de uma fala já cancelada
|
| 11 |
// (por pausar ou pular de parágrafo) se identifica e não mexe mais no
|
| 12 |
// estado — sem isso, um "boundary" ou "end" atrasado de uma fala velha
|
| 13 |
// pode sobrescrever o progresso da fala nova.
|
| 14 |
var geracao = 0;
|
Falar a partir de uma posição
Cancela a fala anterior (se houver) e começa uma nova utterance a partir de "posicao" — só um cancel() por chamada, nunca dois seguidos.
| 1 |
function falarDePosicao() {
|
| 2 |
window.speechSynthesis.cancel();
|
| 3 |
var minhaGeracao = ++geracao;
|
| 4 |
var offsetBase = posicao;
|
| 5 |
var utter = new SpeechSynthesisUtterance(texto.slice(posicao));
|
| 6 |
utter.lang = 'pt-BR';
|
| 7 |
|
| 8 |
utter.addEventListener('boundary', function (evento) {
|
| 9 |
if (minhaGeracao !== geracao) return;
|
| 10 |
if (evento.charIndex != null) posicao = offsetBase + evento.charIndex;
|
| 11 |
atualizarBarra();
|
| 12 |
destacarParagrafo();
|
| 13 |
});
|
| 14 |
|
| 15 |
utter.addEventListener('end', function () {
|
| 16 |
if (minhaGeracao !== geracao) return;
|
| 17 |
tocando = false;
|
| 18 |
posicao = 0;
|
| 19 |
playBtn.textContent = 'Reproduzir';
|
| 20 |
atualizarBarra();
|
| 21 |
destacarParagrafo();
|
| 22 |
});
|
| 23 |
|
| 24 |
window.speechSynthesis.speak(utter);
|
| 25 |
}
|
Pausar sem travar
speechSynthesis.pause()/resume() nativos travam em vários navegadores — cancelar e guardar a posição pra retomar dali é mais confiável.
| 1 |
function pausar() {
|
| 2 |
geracao++;
|
| 3 |
window.speechSynthesis.cancel();
|
| 4 |
tocando = false;
|
| 5 |
playBtn.textContent = 'Reproduzir';
|
| 6 |
}
|
| 7 |
|
| 8 |
playBtn.addEventListener('click', function () {
|
| 9 |
if (tocando) { pausar(); return; }
|
| 10 |
tocando = true;
|
| 11 |
playBtn.textContent = 'Pausar';
|
| 12 |
falarDePosicao();
|
| 13 |
});
|
Progresso e destaque do parágrafo
A barra usa caracteres lidos / total de caracteres; o parágrafo correspondente à posição atual ganha destaque enquanto toca.
| 1 |
function atualizarBarra() {
|
| 2 |
barra.style.width = (posicao / texto.length * 100) + '%';
|
| 3 |
}
|
| 4 |
|
| 5 |
function destacarParagrafo() {
|
| 6 |
var ativo = null;
|
| 7 |
var acumulado = 0;
|
| 8 |
paragrafos.forEach(function (p) {
|
| 9 |
if (acumulado <= posicao) ativo = p;
|
| 10 |
acumulado += p.textContent.length + 2; // +2 pelo separador "\n\n"
|
| 11 |
});
|
| 12 |
paragrafos.forEach(function (p) {
|
| 13 |
p.classList.toggle('ativo', p === ativo && tocando);
|
| 14 |
});
|
| 15 |
}
|
Pular para um parágrafo
Clicar num parágrafo reinicia a leitura a partir dele, sem esperar o fim da fala atual.
| 1 |
var acumuladoOffset = 0;
|
| 2 |
paragrafos.forEach(function (p) {
|
| 3 |
var offset = acumuladoOffset;
|
| 4 |
acumuladoOffset += p.textContent.length + 2;
|
| 5 |
|
| 6 |
p.addEventListener('click', function () {
|
| 7 |
posicao = offset;
|
| 8 |
if (tocando) falarDePosicao();
|
| 9 |
else { atualizarBarra(); destacarParagrafo(); }
|
| 10 |
});
|
| 11 |
});
|