TV GRANNY - MODELO 1987

<html style="margin:0;padding:0;"> <link href="https://fonts.googleapis.com/css2?family=Urbanist:wght@400;500;600;700&family=Special+Elite&display=swap" rel="stylesheet"> <script src="https://cdn.tailwindcss.com"></script> <script> (function(){ var s = document.createElement('style'); s.textContent = ` :root{ --bg:#1a1410; --card:#2a1f17; --text:#e8dcc8; --muted:#8a7a65; --accent:#8b2500; --accent-soft:rgba(139,37,0,.25); --accent2:#c9a227; --accent2-soft:rgba(201,162,39,.2); --border:rgba(232,220,200,.12); --wood-dark:#3a2818; --wood-mid:#4a3422; --wood-light:#5c4230; } *{box-sizing:border-box} body{margin:0;background:var(--bg);font-family:'Urbanist',sans-serif;color:var(--text);overflow-x:hidden} /* Wood texture using gradients */ .wood-frame{ background: repeating-linear-gradient(90deg, transparent 0px, transparent 2px, rgba(0,0,0,.08) 2px, rgba(0,0,0,.08) 3px), repeating-linear-gradient(0deg, transparent 0px, transparent 40px, rgba(255,255,255,.02) 40px, rgba(255,255,255,.02) 41px), linear-gradient(135deg, var(--wood-dark) 0%, var(--wood-mid) 30%, var(--wood-dark) 50%, var(--wood-mid) 70%, var(--wood-dark) 100%); border:4px solid #2a1a0e; box-shadow: inset 0 0 40px rgba(0,0,0,.6), inset 0 2px 4px rgba(255,255,255,.05), 0 10px 40px rgba(0,0,0,.7), 0 2px 8px rgba(0,0,0,.5); } /* CRT Screen effect */ .crt-screen{ position:relative; background:#000; border:6px solid #1a0f08; border-radius:8px; box-shadow: inset 0 0 60px rgba(0,0,0,.9), inset 0 0 20px rgba(0,0,0,.8), 0 0 2px rgba(0,0,0,.8); overflow:hidden; } .crt-screen::before{ content:''; position:absolute; inset:0; background:repeating-linear-gradient(0deg, rgba(0,0,0,.15) 0px, rgba(0,0,0,.15) 1px, transparent 1px, transparent 3px); pointer-events:none; z-index:10; } .crt-screen::after{ content:''; position:absolute; inset:0; background:radial-gradient(ellipse at center, transparent 40%, rgba(0,0,0,.5) 100%); pointer-events:none; z-index:11; } .crt-glow{ box-shadow:0 0 30px rgba(255,200,100,.15), inset 0 0 40px rgba(255,200,100,.05); } /* Static noise */ .static-canvas{position:absolute;inset:0;width:100%;height:100%;z-index:5} /* LED indicator */ .led-off{ background:#3a0a00; box-shadow:inset 0 1px 2px rgba(0,0,0,.8); } .led-on{ background:#ff2a00; box-shadow:0 0 8px #ff2a00, 0 0 16px #ff4500, inset 0 0 4px rgba(255,255,255,.3); animation:ledPulse 2s ease-in-out infinite; } @keyframes ledPulse{0%,100%{opacity:1}50%{opacity:.7}} /* Knobs */ .knob{ width:44px;height:44px;border-radius:50%;cursor:pointer; background:radial-gradient(circle at 35% 30%, #6a5540, #3a2818 70%); border:3px solid #1a0f08; box-shadow:0 3px 8px rgba(0,0,0,.6), inset 0 1px 2px rgba(255,255,255,.1); position:relative; transition:transform .1s; } .knob:hover{transform:scale(1.05)} .knob:active{transform:scale(.95)} .knob::after{ content:'';position:absolute;top:4px;left:50%;transform:translateX(-50%); width:3px;height:12px;background:var(--accent2);border-radius:2px; } /* Speaker grille */ .speaker-grille{ background: repeating-linear-gradient(90deg, #1a0f08 0px, #1a0f08 2px, #2a1a0e 2px, #2a1a0e 4px), repeating-linear-gradient(0deg, transparent 0px, transparent 3px, rgba(0,0,0,.3) 3px, rgba(0,0,0,.3) 4px); border:2px solid #1a0f08; border-radius:4px; } /* Antenna */ .antenna{ position:absolute;top:-30px; width:3px;height:40px;background:linear-gradient(180deg,#888,#444); border-radius:2px; box-shadow:0 0 2px rgba(0,0,0,.5); } /* Control buttons */ .ctrl-btn{ padding:8px 14px;border-radius:6px;font-size:12px;font-weight:600; cursor:pointer;transition:all .15s;border:1px solid var(--border); background:linear-gradient(180deg,var(--wood-light),var(--wood-dark)); color:var(--text); box-shadow:0 2px 6px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.08); font-family:'Urbanist',sans-serif; letter-spacing:.03em; } .ctrl-btn:hover{ background:linear-gradient(180deg,var(--wood-mid),var(--wood-dark)); transform:translateY(-1px); box-shadow:0 3px 10px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.1); } .ctrl-btn:active{transform:translateY(1px);box-shadow:0 1px 3px rgba(0,0,0,.4)} .ctrl-btn.active{ background:linear-gradient(180deg,var(--accent),#5a1800); border-color:var(--accent); color:#fff; } /* Channel buttons */ .ch-btn{ width:36px;height:36px;border-radius:50%;cursor:pointer; background:radial-gradient(circle at 35% 30%, #5a4530, #2a1808 70%); border:2px solid #1a0f08;color:var(--text); font-weight:700;font-size:14px; box-shadow:0 2px 6px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.08); transition:all .15s;display:flex;align-items:center;justify-content:center; } .ch-btn:hover{transform:scale(1.08)} .ch-btn:active{transform:scale(.92)} .ch-btn.active{ background:radial-gradient(circle at 35% 30%, var(--accent2), #8a6a10 70%); color:#1a0f08; box-shadow:0 0 12px rgba(201,162,39,.4), 0 2px 6px rgba(0,0,0,.5); } /* Input field */ .url-input{ flex:1;padding:10px 14px;border-radius:6px; background:#0f0a06;border:2px solid #2a1a0e; color:var(--text);font-family:'Urbanist',sans-serif;font-size:13px; outline:none;transition:border-color .2s; } .url-input:focus{border-color:var(--accent2)} .url-input::placeholder{color:var(--muted)} /* Censor overlay */ .censor-overlay{ position:absolute;inset:0;z-index:20; background:rgba(0,0,0,.85); backdrop-filter:blur(8px); display:flex;align-items:center;justify-content:center; color:var(--muted);font-size:14px;letter-spacing:.2em;text-transform:uppercase; } /* Power off screen */ .power-off{ position:absolute;inset:0;background:#000;z-index:6; display:flex;align-items:center;justify-content:center; } /* Channel label */ .channel-label{ position:absolute;top:10px;right:10px;z-index:15; background:rgba(0,0,0,.7);color:var(--accent2); padding:4px 10px;border-radius:4px;font-size:12px; font-weight:700;letter-spacing:.1em; border:1px solid rgba(201,162,39,.3); font-family:'Special Elite',monospace; } /* Volume indicator */ .vol-bar{ height:4px;background:#1a0f08;border-radius:2px;overflow:hidden; border:1px solid #0a0604; } .vol-fill{ height:100%;background:linear-gradient(90deg,var(--accent2),#e8c84a); transition:width .2s; } /* Scratches on wood */ .scratches{ position:absolute;inset:0;pointer-events:none;opacity:.3; background: linear-gradient(115deg, transparent 48%, rgba(255,255,255,.03) 49%, transparent 50%), linear-gradient(65deg, transparent 60%, rgba(0,0,0,.08) 61%, transparent 62%); } /* Dust particles */ @keyframes flicker{0%,100%{opacity:.97}50%{opacity:1}} .flicker{animation:flicker .15s infinite} /* Fullscreen mode */ .fullscreen-mode{ position:fixed !important;inset:20px !important;z-index:9999; width:calc(100vw - 40px) !important;height:calc(100vh - 40px) !important; } /* Reveal animation */ .reveal{opacity:0;transform:translateY(20px);animation:fadeUp .6s ease forwards} .reveal:nth-child(2){animation-delay:.1s} @keyframes fadeUp{to{opacity:1;transform:translateY(0)}} /* Scrollbar */ ::-webkit-scrollbar{width:8px;height:8px} ::-webkit-scrollbar-track{background:var(--bg)} ::-webkit-scrollbar-thumb{background:var(--wood-mid);border-radius:4px} ::-webkit-scrollbar-thumb:hover{background:var(--wood-light)} `; document.head.appendChild(s); })(); </script> <div style="background:radial-gradient(ellipse at 50% 30%, #2a1f15 0%, #1a1410 60%, #0f0b08 100%);min-height:100%;padding:24px 16px 48px;"> <div class="max-w-5xl mx-auto"> <!-- Title --> <div class="reveal text-center mb-6"> <h1 style="font-family:'Special Elite',monospace;font-size:28px;color:var(--text);margin-bottom:6px;letter-spacing:.05em">TV GRANNY — MODELO 1987</h1> <p style="color:var(--muted);font-size:13px">Sala de estar — Móvel de madeira escura</p> </div> <!-- TV Container --> <div class="reveal" id="tvContainer"> <div class="wood-frame rounded-2xl p-5 md:p-7 relative" style="position:relative"> <div class="scratches rounded-2xl"></div> <!-- Antennas --> <div class="antenna" style="left:25%;transform:rotate(-15deg)"></div> <div class="antenna" style="left:30%;transform:rotate(10deg);height:50px"></div> <!-- Brand label --> <div style="text-align:center;margin-bottom:10px"> <span style="font-family:'Special Elite',monospace;font-size:10px;color:var(--muted);letter-spacing:.3em;text-transform:uppercase">Granny Electronics Co.</span> </div> <!-- Main TV body --> <div style="display:flex;flex-direction:column;gap:16px"> <!-- Screen --> <div class="crt-screen" id="crtScreen" style="aspect-ratio:16/9;width:100%;max-width:100%;cursor:pointer" onclick="toggleFullscreen()"> <!-- Channel label --> <div class="channel-label" id="channelLabel">CH 01 — OFF</div> <!-- Power off overlay --> <div class="power-off" id="powerOff"> <div style="text-align:center;color:#333;font-family:'Special Elite',monospace"> <div style="font-size:11px;letter-spacing:.2em">SEMINAROO</div> </div> </div> <!-- Static canvas --> <canvas class="static-canvas" id="staticCanvas" style="display:none"></canvas> <!-- YouTube iframe --> <iframe id="ytPlayer" style="position:absolute;inset:0;width:100%;height:100%;border:none;z-index:4;display:none" src="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> <!-- Censor overlay --> <div class="censor-overlay" id="censorOverlay" style="display:none"> <span style="font-family:'Special Elite',monospace">— CENSURADO —</span> </div> </div> <!-- Bottom panel: speakers + knobs --> <div style="display:flex;gap:16px;align-items:center;flex-wrap:wrap"> <!-- Left speaker --> <div class="speaker-grille" style="flex:1;min-width:80px;height:50px"></div> <!-- Knobs area --> <div style="display:flex;gap:20px;align-items:center;padding:0 10px"> <div style="text-align:center"> <div class="knob" id="volKnob" onclick="cycleVolume()" title="Volume"></div> <div style="font-size:9px;color:var(--muted);margin-top:4px;letter-spacing:.1em;text-transform:uppercase">VOL</div> </div> <div style="text-align:center"> <div class="knob" id="chKnob" onclick="nextChannel()" title="Canal"></div> <div style="font-size:9px;color:var(--muted);margin-top:4px;letter-spacing:.1em;text-transform:uppercase">CH</div> </div> </div> <!-- Right speaker --> <div class="speaker-grille" style="flex:1;min-width:80px;height:50px"></div> <!-- LED indicator --> <div style="display:flex;align-items:center;gap:8px;padding:0 8px"> <div id="ledIndicator" class="led-off" style="width:12px;height:12px;border-radius:50%;border:2px solid #0a0604"></div> <span style="font-size:9px;color:var(--muted);letter-spacing:.1em;text-transform:uppercase">PWR</span> </div> </div> </div> </div> </div> <!-- Control Panel --> <div class="reveal mt-6 rounded-xl p-5" style="background:var(--card);border:1px solid var(--border);box-shadow:0 4px 20px rgba(0,0,0,.4)"> <div style="font-family:'Special Elite',monospace;font-size:12px;color:var(--accent2);letter-spacing:.2em;text-transform:uppercase;margin-bottom:14px">PAINEL DE CONTROLE</div> <!-- URL input --> <div style="display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px"> <input type="text" class="url-input" id="urlInput" placeholder="Cole o link do YouTube aqui..." onkeypress="if(event.key==='Enter')loadVideo()"> <button class="ctrl-btn" onclick="loadVideo()" style="background:linear-gradient(180deg,var(--accent2),#8a6a10);color:#1a0f08;border-color:#8a6a10"> CARREGAR </button> </div> <!-- Main buttons row 1 --> <div style="display:flex;flex-wrap:wrap;gap:10px;margin-bottom:12px"> <button class="ctrl-btn" id="powerBtn" onclick="togglePower()"> <span id="powerIcon">⏻</span> LIGAR </button> <button class="ctrl-btn" onclick="volumeUp()"> ▲ VOL + </button> <button class="ctrl-btn" onclick="volumeDown()"> ▼ VOL − </button> <button class="ctrl-btn" id="muteBtn" onclick="toggleMute()"> MUDO </button> </div> <!-- Main buttons row 2 --> <div style="display:flex;flex-wrap:wrap;gap:10px;margin-bottom:16px"> <button class="ctrl-btn" onclick="copyLink()"> COPIAR LINK </button> <button class="ctrl-btn" onclick="clearScreen()"> LIMPAR TELA </button> <button class="ctrl-btn" id="censorBtn" onclick="toggleCensor()"> CENSURAR </button> <button class="ctrl-btn" onclick="toggleFullscreen()"> TELA CHEIA </button> </div> <!-- Channel selector --> <div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding-top:14px;border-top:1px solid var(--border)"> <span style="font-size:11px;color:var(--muted);letter-spacing:.15em;text-transform:uppercase">Canais:</span> <div style="display:flex;gap:10px;flex-wrap:wrap"> <button class="ch-btn active" id="ch1" onclick="setChannel(1)" title="Desligado / Estática">1</button> <button class="ch-btn" id="ch2" onclick="setChannel(2)" title="Sprunki Music">2</button> <button class="ch-btn" id="ch3" onclick="setChannel(3)" title="Curtas & Animações">3</button> <button class="ch-btn" id="ch4" onclick="setChannel(4)" title="Seu link YouTube">4</button> </div> <div style="margin-left:auto;display:flex;align-items:center;gap:8px;min-width:120px"> <span style="font-size:10px;color:var(--muted);letter-spacing:.1em;text-transform:uppercase">VOL</span> <div class="vol-bar" style="flex:1;width:80px"><div class="vol-fill" id="volFill" style="width:70%"></div></div> <span id="volPct" style="font-size:10px;color:var(--accent2);font-weight:700;font-family:'Special Elite',monospace;min-width:28px">70%</span> </div> </div> <!-- Status --> <div id="statusMsg" style="margin-top:14px;padding:10px 14px;border-radius:6px;background:rgba(0,0,0,.3);border:1px solid var(--border);font-size:12px;color:var(--muted);font-family:'Special Elite',monospace;min-height:38px;display:flex;align-items:center"> TV desligada. Pressione LIGAR para começar... </div> </div> <!-- Instructions --> <div class="reveal mt-6 rounded-xl p-5" style="background:var(--card);border:1px solid var(--border)"> <div style="font-family:'Special Elite',monospace;font-size:12px;color:var(--accent2);letter-spacing:.2em;text-transform:uppercase;margin-bottom:10px">INSTRUÇÕES</div> <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px;font-size:12px;color:var(--muted);line-height:1.6"> <div><span style="color:var(--text);font-weight:600">1.</span> Clique em LIGAR para ligar a TV</div> <div><span style="color:var(--text);font-weight:600">2.</span> Cole um link do YouTube e clique CARREGAR</div> <div><span style="color:var(--text);font-weight:600">3.</span> Use os botões de CANAL para mudar</div> <div><span style="color:var(--text);font-weight:600">4.</span> Ajuste o volume ou ative o MUDO</div> <div><span style="color:var(--text);font-weight:600">5.</span> Clique na tela para TELA CHEIA</div> <div><span style="color:var(--text);font-weight:600">6.</span> Use CENSURAR para ocultar a imagem</div> </div> <div style="margin-top:12px;padding-top:12px;border-top:1px solid var(--border);font-size:11px;color:var(--muted)"> <span style="color:var(--accent2);font-weight:600">Canais pré-configurados:</span> CH1=Estática | CH2=Sprunki Music | CH3=Curtas | CH4=Seu link </div> </div> </div> </div> <script> (function(){ // State window.tvState = { powered: false, channel: 1, volume: 70, muted: false, censored: false, fullscreen: false, currentUrl: '', currentVideoId: '', staticInterval: null }; // Predefined channels window.channels = { 2: { name: 'Sprunki Music', videoId: 'dQw4w9WgXcQ' }, // placeholder - will use search 3: { name: 'Curtas & Animações', videoId: '9bZkp7q19f0' } // placeholder }; // DOM elements window.els = { crtScreen: document.getElementById('crtScreen'), powerOff: document.getElementById('powerOff'), staticCanvas: document.getElementById('staticCanvas'), ytPlayer: document.getElementById('ytPlayer'), censorOverlay: document.getElementById('censorOverlay'), ledIndicator: document.getElementById('ledIndicator'), powerBtn: document.getElementById('powerBtn'), powerIcon: document.getElementById('powerIcon'), muteBtn: document.getElementById('muteBtn'), censorBtn: document.getElementById('censorBtn'), channelLabel: document.getElementById('channelLabel'), urlInput: document.getElementById('urlInput'), statusMsg: document.getElementById('statusMsg'), volFill: document.getElementById('volFill'), volPct: document.getElementById('volPct'), tvContainer: document.getElementById('tvContainer') }; // Static noise generator window.initStatic = function() { var canvas = els.staticCanvas; var ctx = canvas.getContext('2d'); function resize(){ canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; } resize(); window.addEventListener('resize', resize); function drawStatic(){ if(!tvState.powered || tvState.channel !== 1) return; var w = canvas.width, h = canvas.height; var imgData = ctx.createImageData(w, h); var data = imgData.data; for(var i=0;i<data.length;i+=4){ var v = Math.random()*255; data[i] = v; data[i+1] = v; data[i+2] = v; data[i+3] = 255; } ctx.putImageData(imgData, 0, 0); } if(tvState.staticInterval) clearInterval(tvState.staticInterval); tvState.staticInterval = setInterval(drawStatic, 80); }; // Play click sound via Web Audio window.playClick = function(type){ try{ var AC = window.AudioContext || window.webkitAudioContext; if(!AC) return; var ctx = new AC(); var osc = ctx.createOscillator(); var gain = ctx.createGain(); osc.connect(gain); gain.connect(ctx.destination); if(type==='power'){ osc.frequency.setValueAtTime(80, ctx.currentTime); osc.frequency.exponentialRampToValueAtTime(2000, ctx.currentTime+0.05); osc.frequency.exponentialRampToValueAtTime(100, ctx.currentTime+0.2); gain.gain.setValueAtTime(0.2, ctx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime+0.25); osc.start(); osc.stop(ctx.currentTime+0.25); } else if(type==='static'){ // white noise burst var bufferSize = ctx.sampleRate * 0.15; var buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate); var data = buffer.getChannelData(0); for(var i=0;i<bufferSize;i++) data[i] = Math.random()*2-1; var noise = ctx.createBufferSource(); noise.buffer = buffer; var ng = ctx.createGain(); ng.gain.setValueAtTime(0.15, ctx.currentTime); ng.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime+0.15); noise.connect(ng); ng.connect(ctx.destination); noise.start(); } else { osc.frequency.setValueAtTime(600, ctx.currentTime); osc.frequency.exponentialRampToValueAtTime(200, ctx.currentTime+0.08); gain.gain.setValueAtTime(0.1, ctx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime+0.1); osc.start(); osc.stop(ctx.currentTime+0.1); } } catch(e){} }; // Extract YouTube video ID window.extractVideoId = function(url){ if(!url) return null; var patterns = [ /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/, /youtube\.com\/shorts\/([a-zA-Z0-9_-]{11})/ ]; for(var i=0;i<patterns.length;i++){ var m = url.match(patterns[i]); if(m) return m[1]; } return null; }; // Update status window.setStatus = function(msg){ els.statusMsg.textContent = msg; }; // Update channel label window.updateChannelLabel = function(){ var names = {1:'OFF / ESTÁTICA', 2:'SPRUNKI MUSIC', 3:'CURTAS & ANIMAÇÕES', 4:'SEU LINK YT'}; var ch = tvState.channel; els.channelLabel.textContent = 'CH 0' + ch + ' — ' + names[ch]; // Update channel buttons for(var i=1;i<=4;i++){ var btn = document.getElementById('ch'+i); if(btn) btn.classList.toggle('active', i===ch); } }; // Update volume display window.updateVolumeDisplay = function(){ var v = tvState.muted ? 0 : tvState.volume; els.volFill.style.width = v + '%'; els.volPct.textContent = v + '%'; els.muteBtn.classList.toggle('active', tvState.muted); }; // Toggle power window.togglePower = function(){ tvState.powered = !tvState.powered; playClick('power'); if(tvState.powered){ els.powerOff.style.display = 'none'; els.ledIndicator.className = 'led-on'; els.powerIcon.textContent = '⏻'; els.powerBtn.querySelector('span').textContent = '⏻'; els.powerBtn.childNodes[1].textContent = ' DESLIGAR'; els.crtScreen.classList.add('crt-glow','flicker'); setStatus('TV ligada! Selecione um canal ou cole um link do YouTube.'); setChannel(tvState.channel); initStatic(); } else { els.powerOff.style.display = 'flex'; els.staticCanvas.style.display = 'none'; els.ytPlayer.style.display = 'none'; els.ytPlayer.src = ''; els.ledIndicator.className = 'led-off'; els.powerBtn.querySelector('span').textContent = '⏻'; els.powerBtn.childNodes[1].textContent = ' LIGAR'; els.crtScreen.classList.remove('crt-glow','flicker'); if(tvState.staticInterval){ clearInterval(tvState.staticInterval); tvState.staticInterval=null; } setStatus('TV desligada.'); } }; // Set channel window.setChannel = function(ch){ if(!tvState.powered){ setStatus('Ligue a TV primeiro!'); return; } tvState.channel = ch; updateChannelLabel(); playClick('static'); // Brief static flash els.staticCanvas.style.display = 'block'; els.ytPlayer.style.display = 'none'; setTimeout(function(){ if(ch === 1){ // Static only els.staticCanvas.style.display = 'block'; els.ytPlayer.style.display = 'none'; setStatus('Canal 1 — Apenas estática. Nenhum sinal.'); } else if(ch === 4){ // User's link els.staticCanvas.style.display = 'none'; if(tvState.currentVideoId){ loadVideoById(tvState.currentVideoId); setStatus('Canal 4 — Reproduzindo seu link do YouTube.'); } else { els.ytPlayer.style.display = 'none'; setStatus('Canal 4 — Nenhum link carregado. Cole um URL do YouTube acima.'); } } else { // Predefined channels els.staticCanvas.style.display = 'none'; var chData = channels[ch]; if(chData){ loadVideoById(chData.videoId); setStatus('Canal ' + ch + ' — ' + chData.name); } } }, 400); }; // Next channel window.nextChannel = function(){ if(!tvState.powered) return; var next = (tvState.channel % 4) + 1; setChannel(next); }; // Load video by ID window.loadVideoById = function(videoId){ if(!videoId) return; tvState.currentVideoId = videoId; var muteParam = tvState.muted ? '&mute=1' : ''; els.ytPlayer.src = 'https://www.youtube.com/embed/' + videoId + '?autoplay=1&rel=0' + muteParam; els.ytPlayer.style.display = 'block'; els.staticCanvas.style.display = 'none'; }; // Load video from input window.loadVideo = function(){ if(!tvState.powered){ setStatus('Ligue a TV primeiro!'); return; } var url = els.urlInput.value.trim(); if(!url){ setStatus('Por favor, cole um link do YouTube.'); return; } var videoId = extractVideoId(url); if(!videoId){ setStatus('Link inválido! Use um URL válido do YouTube (youtube.com/watch?v=... ou youtu.be/...).'); return; } tvState.currentUrl = url; tvState.currentVideoId = videoId; playClick('click'); setChannel(4); setStatus('Vídeo carregado com sucesso! Reproduzindo no Canal 4.'); }; // Volume controls window.volumeUp = function(){ if(tvState.volume < 100){ tvState.volume = Math.min(100, tvState.volume + 10); if(tvState.muted) tvState.muted = false; updateVolumeDisplay(); playClick('click'); setStatus('Volume: ' + tvState.volume + '%'); } }; window.volumeDown = function(){ if(tvState.volume > 0){ tvState.volume = Math.max(0, tvState.volume - 10); if(tvState.muted) tvState.muted = false; updateVolumeDisplay(); playClick('click'); setStatus('Volume: ' + tvState.volume + '%'); } }; window.cycleVolume = function(){ volumeUp(); }; window.toggleMute = function(){ tvState.muted = !tvState.muted; updateVolumeDisplay(); playClick('click'); // Reload player with mute param if(tvState.currentVideoId && tvState.powered && tvState.channel !== 1){ loadVideoById(tvState.currentVideoId); } setStatus(tvState.muted ? 'Mudo ativado.' : 'Mudo desativado. Volume: ' + tvState.volume + '%'); }; // Toggle censor window.toggleCensor = function(){ tvState.censored = !tvState.censored; els.censorOverlay.style.display = tvState.censored ? 'flex' : 'none'; els.censorBtn.classList.toggle('active', tvState.censored); playClick('click'); setStatus(tvState.censored ? 'Tela censurada.' : 'Censura removida.'); }; // Copy link window.copyLink = function(){ var text = tvState.currentUrl || (tvState.currentVideoId ? 'https://www.youtube.com/watch?v=' + tvState.currentVideoId : ''); if(!text){ setStatus('Nenhum link para copiar.'); return; } if(navigator.clipboard){ navigator.clipboard.writeText(text).then(function(){ setStatus('Link copiado para a área de transferência!'); }).catch(function(){ fallbackCopy(text); }); } else { fallbackCopy(text); } playClick('click'); }; function fallbackCopy(text){ var ta = document.createElement('textarea'); ta.value = text; document.body.appendChild(ta); ta.select(); try{ document.execCommand('copy'); setStatus('Link copiado!'); } catch(e){ setStatus('Não foi possível copiar automaticamente.'); } document.body.removeChild(ta); } // Clear screen window.clearScreen = function(){ els.urlInput.value = ''; tvState.currentUrl = ''; tvState.currentVideoId = ''; els.ytPlayer.src = ''; els.ytPlayer.style.display = 'none'; if(tvState.powered){ els.staticCanvas.style.display = 'block'; setChannel(1); } playClick('click'); setStatus('Tela limpa. Link e vídeo removidos.'); }; // Toggle fullscreen window.toggleFullscreen = function(){ tvState.fullscreen = !tvState.fullscreen; els.tvContainer.classList.toggle('fullscreen-mode', tvState.fullscreen); playClick('click'); setStatus(tvState.fullscreen ? 'Modo tela cheia ativado. Clique novamente para sair.' : 'Modo normal.'); }; // Init updateChannelLabel(); updateVolumeDisplay(); })(); </script> </html>

Public Last updated: 2026-08-13 04:28:03 PM