Participaram da ação integrantes do projeto Cabelos de Prata, da Prefeitura de Boa Vista
O post Distribuição de mudas de planta e entrega de panfletos informativos marcam Dia Nacional do Idoso em Boa Vista apareceu primeiro em Roraima em Tempo.
Participaram da ação integrantes do projeto Cabelos de Prata, da Prefeitura de Boa Vista
O post Distribuição de mudas de planta e entrega de panfletos informativos marcam Dia Nacional do Idoso em Boa Vista apareceu primeiro em Roraima em Tempo.
/* ============================================
PLAYER 93FM — barra inferior amarela
============================================ */
.player-93fm {
display: inline-flex;
align-items: center;
gap: 14px;
padding: 8px 18px 8px 8px;
background: rgba(0, 0, 0, 0.08);
border-radius: 999px;
backdrop-filter: blur(4px);
transition: background 0.25s ease;
}
.player-93fm:hover {
background: rgba(0, 0, 0, 0.15);
}
/* Botão circular com gradiente do logo 93FM */
.player-93fm__btn {
width: 48px;
height: 48px;
border-radius: 50%;
border: none;
cursor: pointer;
background: radial-gradient(
circle at 30% 30%,
#ffb627 0%,
#f77f00 50%,
#d62828 100%
);
color: #fff;
display: inline-flex;
align-items: center;
justify-content: center;
box-shadow:
0 4px 12px rgba(214, 40, 40, 0.35),
inset 0 -3px 0 rgba(0, 0, 0, 0.12);
transition:
transform 0.15s ease,
box-shadow 0.2s ease;
flex-shrink: 0;
}
.player-93fm__btn:hover:not(:disabled) {
transform: scale(1.06);
box-shadow:
0 6px 16px rgba(214, 40, 40, 0.5),
inset 0 -3px 0 rgba(0, 0, 0, 0.12);
}
.player-93fm__btn:active {
transform: scale(0.96);
}
.player-93fm__btn:disabled {
cursor: wait;
opacity: 0.85;
}
/* Ícones — só um visível por vez */
.player-93fm__icon {
position: relative;
width: 22px;
height: 22px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.player-93fm__icon svg {
position: absolute;
opacity: 0;
transition: opacity 0.2s ease;
}
.player-93fm[data-state="paused"] .icon-play {
opacity: 1;
}
.player-93fm[data-state="playing"] .icon-pause {
opacity: 1;
}
.player-93fm[data-state="loading"] .icon-loading {
opacity: 1;
animation: spin-93 0.9s linear infinite;
}
@keyframes spin-93 {
to {
transform: rotate(360deg);
}
}
/* Info ao lado do botão */
.player-93fm__info {
display: flex;
flex-direction: column;
line-height: 1.15;
color: #1a1a1a;
}
.player-93fm__label {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 11px;
font-weight: 800;
letter-spacing: 1.2px;
text-transform: uppercase;
color: #d62828;
}
.player-93fm__title {
font-size: 13px;
font-weight: 600;
color: #2a2a2a;
}
/* Bolinha pulsante "ao vivo" */
.player-93fm__live-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #d62828;
box-shadow: 0 0 0 0 rgba(214, 40, 40, 0.7);
animation: pulse-live 1.6s ease-out infinite;
}
@keyframes pulse-live {
0% {
box-shadow: 0 0 0 0 rgba(214, 40, 40, 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(214, 40, 40, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(214, 40, 40, 0);
}
}
/* Animação suave da bolinha enquanto tocando (mais intensa) */
.player-93fm[data-state="playing"] .player-93fm__live-dot {
animation-duration: 1s;
}
/* ============================================
Botão AO VIVO do topo — sincronizado
============================================ */
.btn-aovivo-menu[data-state="playing"] {
/* opcional: deixa o botão do topo destacado quando tocando */
box-shadow: 0 0 0 3px rgba(214, 40, 40, 0.25);
}
/* Responsivo: esconde o texto em telas pequenas */
@media (max-width: 540px) {
.player-93fm__info {
display: none;
}
.player-93fm {
padding: 4px;
}
}
jQuery(document).ready(function ($) {
const STREAM_URL = 'https://5a2b083e9f360.streamlock.net/93fmrr/93fmrr.stream/playlist.m3u8';
const audio = document.getElementById('radio93fm');
const $player = $('#player93fm');
const TRIGGER_SELECTOR = '.btn-aovivo-menu';
let isPlaying = false;
let isLoading = false;
let hls = null; // instância da hls.js
function getTriggers() {
return $(TRIGGER_SELECTOR);
}
function setState(state) {
const $triggers = getTriggers();
$player.attr('data-state', state);
$triggers.attr('data-state', state);
$triggers.each(function () {
const $text = $(this).find('.trigger-text');
if (!$text.length) return;
switch (state) {
case 'loading': $text.text('CARREGANDO...'); break;
case 'playing': $text.text('PAUSAR'); break;
case 'error': $text.text('ERRO'); break;
default: $text.text('AO VIVO');
}
});
$triggers.prop('disabled', state === 'loading');
}
function attachStream() {
// Estratégia: detecta o melhor método disponível
if (Hls.isSupported()) {
// Chrome, Firefox, Edge: usa hls.js
hls = new Hls({
liveDurationInfinity: true, // marca como stream contínuo
enableWorker: true,
lowLatencyMode: false // rádio não precisa de baixa latência agressiva
});
hls.loadSource(STREAM_URL);
hls.attachMedia(audio);
hls.on(Hls.Events.ERROR, function (event, data) {
console.error('Erro HLS:', data);
if (data.fatal) {
isPlaying = false;
isLoading = false;
setState('error');
setTimeout(() => setState('paused'), 3000);
}
});
} else if (audio.canPlayType('application/vnd.apple.mpegurl')) {
// Safari: suporte nativo
audio.src = STREAM_URL;
} else {
console.error('Navegador não suporta HLS.');
setState('error');
}
}
function detachStream() {
if (hls) {
hls.destroy();
hls = null;
}
audio.removeAttribute('src');
audio.load();
}
function play() {
if (isLoading || isPlaying) return;
isLoading = true;
setState('loading');
attachStream();
const p = audio.play();
if (p !== undefined) {
p.then(() => {
isPlaying = true;
isLoading = false;
setState('playing');
}).catch((err) => {
console.error('Erro ao reproduzir 93FM:', err);
isPlaying = false;
isLoading = false;
setState('error');
setTimeout(() => setState('paused'), 3000);
});
}
}
function pause() {
audio.pause();
detachStream(); // limpa pra próxima conexão pegar o "ao vivo" atualizado
isPlaying = false;
setState('paused');
}
function toggle() {
if (isPlaying) pause();
else play();
}
setState('paused');
$(document).on('click', TRIGGER_SELECTOR, function (e) {
e.preventDefault();
toggle();
});
audio.addEventListener('playing', () => {
isPlaying = true;
isLoading = false;
setState('playing');
});
audio.addEventListener('pause', () => {
if (!isLoading) {
isPlaying = false;
setState('paused');
}
});
audio.addEventListener('error', () => {
isPlaying = false;
isLoading = false;
setState('error');
setTimeout(() => setState('paused'), 3000);
});
});

De Boa
com Pedro Ribeiro