Files
pollets/public/index.html
Carlos Narro e1c15fe015 pollets
2026-03-17 17:57:56 +01:00

481 lines
14 KiB
HTML
Raw Permalink Blame History

<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🐣 Els Nostres Pollets - En Directe!</title>
<script src="https://cdn.jsdelivr.net/npm/flv.js@1.6.2/dist/flv.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Comic Sans MS', 'Chalkboard', cursive, sans-serif;
background: linear-gradient(135deg, #87CEEB 0%, #98FB98 50%, #FFE4B5 100%);
min-height: 100vh;
color: #4a4a4a;
}
.clouds {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
overflow: hidden;
z-index: -1;
}
.cloud {
position: absolute;
background: rgba(255,255,255,0.8);
border-radius: 50%;
animation: floatCloud 20s infinite linear;
}
.cloud::before, .cloud::after {
content: '';
position: absolute;
background: inherit;
border-radius: 50%;
}
@keyframes floatCloud {
from { transform: translateX(-200px); }
to { transform: translateX(calc(100vw + 200px)); }
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
header {
text-align: center;
padding: 30px 0;
}
h1 {
font-size: 2.8rem;
margin-bottom: 15px;
color: #FF6B35;
text-shadow: 3px 3px 0 #FFD93D, 5px 5px 0 rgba(0,0,0,0.1);
}
h2 {
font-size: 2rem;
color: #FF6B35;
text-align: center;
margin: 40px 0 30px;
text-shadow: 2px 2px 0 #FFD93D;
}
.live-badge {
display: inline-flex;
align-items: center;
gap: 8px;
background: #e74c3c;
padding: 8px 16px;
border-radius: 20px;
font-weight: bold;
font-size: 0.9rem;
animation: pulse 2s infinite;
}
.live-badge::before {
content: '';
width: 10px;
height: 10px;
background: #fff;
border-radius: 50%;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
.video-container {
background: #2d2d2d;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
margin: 20px 0;
border: 6px solid #FFD93D;
}
#videoPlayer {
width: 100%;
aspect-ratio: 16/9;
background: #000;
}
.controls {
display: flex;
gap: 10px;
justify-content: center;
padding: 20px;
flex-wrap: wrap;
}
button {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
font-weight: 600;
}
button:hover {
transform: translateY(-2px);
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3);
}
.btn-primary {
background: linear-gradient(90deg, #4CAF50, #8BC34A);
color: #fff;
border: 3px solid #388E3C;
font-size: 1.2rem;
}
.btn-danger {
background: linear-gradient(90deg, #FF5722, #FF9800);
color: #fff;
border: 3px solid #E64A19;
font-size: 1.2rem;
}
.status {
text-align: center;
padding: 20px;
background: rgba(255, 255, 255, 0.7);
border-radius: 15px;
margin-top: 20px;
border: 3px dashed #FFD93D;
font-size: 1.1rem;
}
/* Cicle de vida del pollet */
.cicle-section {
background: rgba(255, 255, 255, 0.85);
border-radius: 25px;
padding: 30px;
margin: 40px 0;
border: 4px solid #8BC34A;
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
}
.cicle-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 25px;
margin-top: 20px;
}
.cicle-step {
background: linear-gradient(135deg, #FFF9C4, #FFECB3);
border-radius: 20px;
padding: 20px;
text-align: center;
border: 3px solid #FFD93D;
transition: transform 0.3s;
position: relative;
}
.cicle-step:hover {
transform: scale(1.05);
}
.cicle-step .numero {
position: absolute;
top: -15px;
left: 50%;
transform: translateX(-50%);
background: #FF6B35;
color: white;
width: 35px;
height: 35px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 1.2rem;
border: 3px solid white;
}
.cicle-step .emoji {
font-size: 4rem;
margin: 15px 0;
display: block;
}
.cicle-step h3 {
color: #5D4037;
margin: 10px 0;
font-size: 1.3rem;
}
.cicle-step p {
color: #6D4C41;
font-size: 1rem;
line-height: 1.5;
}
.arrow {
display: none;
}
@media (min-width: 900px) {
.arrow {
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
color: #FF6B35;
}
}
.status-indicator {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 8px;
}
.status-indicator.offline {
background: #e74c3c;
}
.status-indicator.online {
background: #2ecc71;
animation: pulse 1s infinite;
}
.offline-message {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
min-height: 300px;
color: #888;
}
.offline-message svg {
width: 80px;
height: 80px;
margin-bottom: 20px;
opacity: 0.5;
}
footer {
text-align: center;
padding: 30px;
color: #5D4037;
font-size: 1rem;
background: rgba(255,255,255,0.5);
border-radius: 20px;
margin-top: 30px;
}
.fun-fact {
background: linear-gradient(135deg, #E1F5FE, #B3E5FC);
border-radius: 20px;
padding: 25px;
margin: 30px 0;
border: 3px solid #03A9F4;
text-align: center;
}
.fun-fact h3 {
color: #0277BD;
margin-bottom: 15px;
font-size: 1.4rem;
}
.fun-fact p {
color: #01579B;
font-size: 1.1rem;
line-height: 1.6;
}
</style>
</head>
<body>
<div class="clouds">
<div class="cloud" style="width:80px;height:40px;top:10%;left:-100px;animation-delay:0s;"></div>
<div class="cloud" style="width:120px;height:50px;top:25%;left:-100px;animation-delay:5s;"></div>
<div class="cloud" style="width:60px;height:30px;top:5%;left:-100px;animation-delay:10s;"></div>
</div>
<div class="container">
<header>
<h1><EFBFBD> Els Nostres Pollets! 🐥</h1>
<p style="font-size:1.3rem;color:#5D4037;">Mira com neixen i creixen els pollets en directe!</p>
<span class="live-badge" id="liveBadge" style="display: none;">📺 EN DIRECTE</span>
</header>
<div class="video-container">
<video id="videoPlayer" controls autoplay muted></video>
</div>
<div class="controls">
<button class="btn-primary" onclick="conectar()">▶️ Connectar</button>
<button class="btn-danger" onclick="desconectar()">⏹️ Desconnectar</button>
</div>
<div class="status">
<span class="status-indicator offline" id="statusIndicator"></span>
<span id="statusText">Sense connexió - Prem "Connectar" per veure el directe</span>
</div>
<!-- CICLE DE VIDA DEL POLLET -->
<section class="cicle-section">
<h2>🥚 El Cicle de Vida del Pollet 🐔</h2>
<p style="text-align:center;font-size:1.2rem;color:#5D4037;margin-bottom:20px;">
Descobreix com un ou es converteix en un pollet!
</p>
<div class="cicle-container">
<div class="cicle-step">
<span class="numero">1</span>
<span class="emoji">🥚</span>
<h3>L'Ou</h3>
<p>La gallina pon un ou fecundat. L'ou té tot el que el pollet necessita per créixer!</p>
</div>
<div class="cicle-step">
<span class="numero">2</span>
<span class="emoji">🪺</span>
<h3>La Incubació</h3>
<p>La gallina escalfa l'ou durant <strong>21 dies</strong>. La calor fa que el pollet es formi dins!</p>
</div>
<div class="cicle-step">
<span class="numero">3</span>
<span class="emoji">🐣</span>
<h3>L'Eclosió</h3>
<p>El pollet trenca la closca amb el seu "dent d'ou". Triga unes hores en sortir!</p>
</div>
<div class="cicle-step">
<span class="numero">4</span>
<span class="emoji">🐥</span>
<h3>El Pollet Nounat</h3>
<p>El pollet és petit i groc. Ja pot caminar i piular! Menja solo des del primer dia.</p>
</div>
<div class="cicle-step">
<span class="numero">5</span>
<span class="emoji">🐤</span>
<h3>El Pollet Creix</h3>
<p>Durant setmanes, el pollet creix i li surten plomes de veritat. Menja molt!</p>
</div>
<div class="cicle-step">
<span class="numero">6</span>
<span class="emoji">🐔</span>
<h3>Gallina o Gall</h3>
<p>Als 6 mesos ja és adult! Les gallines ponen ous i els galls fan "quiquiriquic"!</p>
</div>
</div>
</section>
<!-- DADES CURIOSES -->
<div class="fun-fact">
<h3>🌟 Sabies que...?</h3>
<p>Un pollet pot recordar la veu de la seva mare des de dins de l'ou!
<br>Els pollets piulen dins l'ou abans de néixer per comunicar-se amb la gallina! 🐣💬</p>
</div>
<footer>
<p>🏫 Projecte Escolar - 3r de Primària</p>
<p>🌐 pollets.com.es</p>
</footer>
</div>
<script>
let flvPlayer = null;
const videoElement = document.getElementById('videoPlayer');
const statusIndicator = document.getElementById('statusIndicator');
const statusText = document.getElementById('statusText');
const liveBadge = document.getElementById('liveBadge');
// Configuración del stream
// En desarrollo: localhost
// En producción: cambiar a pollets.com.es
const STREAM_URL = 'http://localhost:8000/live/pollets.flv';
function conectar() {
if (flvjs.isSupported()) {
if (flvPlayer) {
desconectar();
}
flvPlayer = flvjs.createPlayer({
type: 'flv',
url: STREAM_URL,
isLive: true,
hasAudio: true,
hasVideo: true,
enableStashBuffer: false,
stashInitialSize: 128
}, {
enableWorker: false,
lazyLoadMaxDuration: 3 * 60,
seekType: 'range'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
flvPlayer.on(flvjs.Events.ERROR, (errorType, errorDetail) => {
console.error('Error:', errorType, errorDetail);
actualizarEstado(false, '⚠️ Error de connexió - El directe està actiu?');
});
flvPlayer.on(flvjs.Events.LOADING_COMPLETE, () => {
actualizarEstado(false, '📺 El directe ha acabat');
});
actualizarEstado(true, '🎬 Connectat al directe!');
} else {
alert('El teu navegador no suporta aquest vídeo. Prova amb Chrome o Firefox!');
}
}
function desconectar() {
if (flvPlayer) {
flvPlayer.pause();
flvPlayer.unload();
flvPlayer.detachMediaElement();
flvPlayer.destroy();
flvPlayer = null;
}
actualizarEstado(false, '🔌 Desconnectat');
}
function actualizarEstado(online, mensaje) {
statusIndicator.className = 'status-indicator ' + (online ? 'online' : 'offline');
statusText.textContent = mensaje;
liveBadge.style.display = online ? 'inline-flex' : 'none';
}
// Intentar conectar automáticamente al cargar
window.onload = () => {
setTimeout(conectar, 1000);
};
</script>
</body>
</html>