RD5 GOLD WEB EDITOR
📄
📄 2-RB4-3CC.HTML
📄 222.JPG
📄 3CC-BASIC1.HTML
📄 Microsoft Paint.exe
📄 R2C-3.HTML
📄 R2C-4.HTML
📄 RB4-3C.HTML
📄 RB4-3CC.HTML
📄 RB4-RETRO.HTML
📄 RB4-RETRO.html
📄 RD5-3CC.html
📄 RL-4.html
📄 TARS.html
📄 TES10.mp3
📄 TES11.mp3
📄 TRISHA-OK.html
📄 TRISHA-WIN.HTML
📄 Tiny-demo.html
📄 Tinybj7-blindado.html
📄 Tinybj7-publica.html
📄 aplicaciones-rd5.html
📄 app1.html
📄 app2.html
📄 app3.html
📄 appb1.html
📄 appb2.html
📄 appb3.html
📄 appb4.html
📄 appb5.html
📄 appb6.html
📄 c-julio.JPG
📄 caratula.gif
📄 caratula02.gif
📄 caratula2.gif
📄 chokurei2.jpg
📄 columna-julio.html
📄 columna-stella.html
📄 columna-stellab.html
📄 demos.html
📄 df3.html
📄 dni.gif
📄 donaciones.gif
📄 ecualizador.html
📄 ed-podcast.JPG
📄 ed-radio.JPG
📄 editorv.html
📄 editorv1.html
📄 editorv2.html
📄 fondo5d.jpg
📄 fresi-clip.html
📄 gold.php
📄 gold62.php
📄 gold93.php
📄 googlefd161ffccea5f6ab.html
📄 gw.php
📄 index-anterior.html
📄 index.html
📄 index2.html
📄 logo.png
📄 logo.webp
📄 magazine.html
📄 manager3.php
📄 mic2.jpg
📄 mini1.html
📄 minib2a.html
📄 mn.php
📄 muestra.JPG
📄 p.html
📄 pm.html
📄 pm2.html
📄 pod-rd5.html
📄 podcast-stops.gif
📄 podcast2.mp3
📄 pp.html
📄 promo-tinybj7.html
📄 radio.html
📄 radio_gold.html
📄 rd5-fresia-4 canvashtml
📄 rd5-fresia-ok.html
📄 rd5-fresia.html
📄 rd5-plus-anterior.html
📄 rd5-plus.html
📄 rd5-plus2.html
📄 rd5-radioplayer.html
📄 rd5-tv.html
📄 rd5.html
📄 sst.html
📄 st.html
📄 starclip.html
📄 stella-2.JPG
📄 stella.JPG
📄 stt.html
📄 t-rd5.html.html
📄 t-rd6.html
📄 t-rd7.html
📄 t-tiny.html
📄 tes0.jpg
📄 tes1.jpg
📄 tes2.jpg
📄 tes4.jpg
📄 tes4.mp3
📄 tes5.jpg
📄 tes7.jpg
📄 tes8.jpg
📄 tienda.html
📄 tiendaaps.html
📄 tiendapps.html
📄 tiny-bj6.html
📄 tiny-bj7-full.html
📄 tiny-bj7.html
📄 tiny3-bj2.html
📄 tinybj7-blindado.html
📄 tinydemo.html
📄 titulo.jpg
📄 tnw2.html
📄 trisha-basic.html
📄 trisha-cafe.html
📄 trisha-mini.html
📄 tv-pantalla.php
📄 tv.html
📄 xdni.html
CÓDIGO (OSCURO GOLD)
VISTA PREVIA
💾 GUARDAR
Tema: Monokai
Tema: Dracula
Tema: Material
Tema: Blackboard
Tema: Abyss
Monospace
Courier
12px
14px
16px
18px
20px
22px
24px
26px
28px
30px
32px
↷ Rehacer
↶ Deshacer
🔍 BUSCAR
+ REPRO RADIO
SIG.
X
<!doctype html> <html lang="es"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> <title>Trisha player R2C-3</title> <style> :root{ --bg:#060606; --panel:#0f0f10; --accent:orange; --muted:#9a9a9a; --glass:rgba(255,255,255,0.03); } html,body{height:100%;margin:0;background:var(--bg);color:#eee;font-family:Arial,Helvetica,sans-serif} .wrap{display:flex;gap:12px;padding:12px;height:100vh;box-sizing:border-box} .col{background:var(--panel);border-radius:10px;padding:12px;box-shadow:0 8px 30px rgba(0,0,0,0.7);display:flex;flex-direction:column} .left{width:65%} .right{width:35%} h1{margin:0 0 10px 0;color:var(--accent);font-size:18px} /* playlist */ #dropArea{border:2px dashed rgba(255,255,255,0.04);padding:10px;border-radius:8px;background:var(--glass);text-align:center;color:var(--muted);cursor:pointer} #playlist{list-style:none;padding:8px;margin-top:10px;overflow:auto;flex:1;background:#050505;border-radius:6px} #playlist li{padding:8px;border-bottom:1px solid rgba(255,255,255,0.02);cursor:pointer} #playlist li.active{background:linear-gradient(90deg, rgba(255,165,0,0.06), rgba(255,165,0,0.02));border-left:4px solid var(--accent)} /* controls */ .controls{display:flex;gap:8px;align-items:center;margin-top:8px} button{background:transparent;border:2px solid var(--accent);color:#fff;padding:6px 10px;border-radius:8px;cursor:pointer} button:hover{background:var(--accent);color:#000} .vol{margin-left:auto;display:flex;align-items:center;gap:8px} input[type=file]{width:100%} /* EQ vertical */ .eq-wrap{display:flex;justify-content:center;gap:14px;margin-top:12px} .eq-band{display:flex;flex-direction:column;align-items:center;gap:6px} .vslider{writing-mode:bt-lr;-webkit-appearance:slider-vertical;height:140px;width:18px;accent-color:var(--accent)} /* vumeters */ .vumeters{display:flex;gap:14px;align-items:flex-end;justify-content:center;margin-top:16px} .needle-canvas{width:120px;height:80px;background:black;border-radius:8px;border:2px solid rgba(255,255,255,0.04)} .bar-v{width:28px;height:120px;background:#060606;border:2px solid rgba(255,255,255,0.04);display:flex;flex-direction:column-reverse;overflow:hidden;border-radius:6px} .bar-fill{width:100%;height:0%;background:linear-gradient(to top, #ff3b3b, orange, yellow, lime);transition:height 0.06s linear} /* progres y tiempo */ .progress-row{margin-top:14px} input[type=range].progress{width:100%;-webkit-appearance:none;height:10px;background:#111;border-radius:8px} input[type=range].progress::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;border-radius:50%;background:var(--accent)} .time{font-family:monospace;color:var(--accent);text-align:center;margin-top:6px} /* responsive */ @media (max-width:900px){ .wrap{flex-direction:column} .left,.right{width:100%} .vumeters{flex-wrap:wrap} } </style> </head> <body> <div class="wrap"> <!-- IZQUIERDA: upload + playlist --> <section class="col left" aria-label="Subir y playlist"> <h1>🔊 Trisha player R2C-3 — Subir & Playlist</h1> <!-- NUEVO: Título de canción en curso --> <div id="currentTrack" style="margin-bottom:8px;color:lime(--accent);font-weight:bold;font-size:14px"></div> <div id="dropArea">Click o arrastrá archivos aquí (mp3, wav)</div> <input type="file" id="audioFile" accept="audio/*" multiple style="margin-top:8px"> <ul id="playlist" aria-live="polite"></ul> <div class="small" style="margin-top:8px;color:var(--muted)">Doble click en la pista para reproducir</div> </section> <!-- DERECHA: controles, EQ y vumeters --> <aside class="col right" aria-label="Controles y vumetros"> <h1>🎚️ Controles — EQ — VU</h1> <div class="controls"> <button id="play">Play</button> <button id="pause">Pause</button> <button id="stop">Stop</button> <div class="vol"> <label style="font-size:13px">Vol</label> <input id="volume" type="range" min="0" max="1" step="0.01" value="0.7" style="width:140px"> <span id="volPct" style="color:var(--muted);font-size:13px">70%</span> </div> </div> <!-- EQ vertical (5 bandas) --> <div class="eq-wrap" id="eqWrap"> <div class="eq-band"><label style="font-size:12px">60Hz</label><input id="eq60" class="vslider" type="range" min="-12" max="12" step="0.5" value="0"></div> <div class="eq-band"><label style="font-size:12px">250Hz</label><input id="eq250" class="vslider" type="range" min="-12" max="12" step="0.5" value="0"></div> <div class="eq-band"><label style="font-size:12px">1kHz</label><input id="eq1k" class="vslider" type="range" min="-12" max="12" step="0.5" value="0"></div> <div class="eq-band"><label style="font-size:12px">4kHz</label><input id="eq4k" class="vslider" type="range" min="-12" max="12" step="0.5" value="0"></div> <div class="eq-band"><label style="font-size:12px">16kHz</label><input id="eq16k" class="vslider" type="range" min="-12" max="12" step="0.5" value="0"></div> </div> <!-- VUMETERS: 2 agujas + 3 barras (low/mid/high) --> <div class="vumeters" aria-hidden="false"> <canvas id="needleL" class="needle-canvas" width="120" height="80" title="Left"></canvas> <canvas id="needleR" class="needle-canvas" width="120" height="80" title="Right"></canvas> <div class="bar-v"><div id="barLow" class="bar-fill"></div></div> <div class="bar-v"><div id="barMid" class="bar-fill"></div></div> <div class="bar-v"><div id="barHigh" class="bar-fill"></div></div> </div> <!-- Progress y tiempo (debajo de vumeters) --> <div class="progress-row"> <input id="progress" class="progress" type="range" min="0" max="100" value="0"> <div class="time"><span id="timeNow">00:00</span> / <span id="timeTotal">00:00</span></div> </div> </aside> </div> <!-- elemento audio oculto --> <audio id="player" crossorigin="anonymous"></audio> <script> /* -------------------------- Elementos DOM ---------------------------*/ const fileInput = document.getElementById('audioFile'); const dropArea = document.getElementById('dropArea'); const playlistEl = document.getElementById('playlist'); const player = document.getElementById('player'); const playBtn = document.getElementById('play'); const pauseBtn = document.getElementById('pause'); const stopBtn = document.getElementById('stop'); const vol = document.getElementById('volume'); const volPct = document.getElementById('volPct'); const progress = document.getElementById('progress'); const timeNow = document.getElementById('timeNow'); const timeTotal = document.getElementById('timeTotal'); const needleL = document.getElementById('needleL'); const needleR = document.getElementById('needleR'); const barLow = document.getElementById('barLow'); const barMid = document.getElementById('barMid'); const barHigh = document.getElementById('barHigh'); const eqIds = ['eq60','eq250','eq1k','eq4k','eq16k']; /* -------------------------- Playlist / drag & drop ---------------------------*/ let tracks = []; let currentIndex = -1; dropArea.addEventListener('click', ()=> fileInput.click()); ['dragenter','dragover'].forEach(ev => dropArea.addEventListener(ev, e=>{ e.preventDefault(); dropArea.style.borderColor = 'orange'; })); ['dragleave','drop'].forEach(ev => dropArea.addEventListener(ev, e=>{ e.preventDefault(); dropArea.style.borderColor = ''; })); dropArea.addEventListener('drop', e=>{ const dt = e.dataTransfer; if(dt && dt.files) handleFiles(Array.from(dt.files).filter(f=>f.type.startsWith('audio'))); }); fileInput.addEventListener('change', e=> handleFiles(Array.from(e.target.files))); function handleFiles(list){ const audioFiles = list.filter(f=>f.type && f.type.startsWith('audio')); if(audioFiles.length === 0) return; tracks = tracks.concat(audioFiles); renderPlaylist(); if(currentIndex === -1) loadTrack(0); } function renderPlaylist(){ playlistEl.innerHTML = ''; tracks.forEach((f,i)=>{ const li = document.createElement('li'); li.textContent = f.name; li.ondblclick = ()=>{ loadTrack(i); player.play(); }; li.onclick = ()=> { loadTrack(i); }; if(i===currentIndex) li.classList.add('active'); playlistEl.appendChild(li); }); } function loadTrack(index){ if(!tracks[index]) return; currentIndex = index; player.src = URL.createObjectURL(tracks[index]); renderPlaylist(); // ensure audio context created on interaction when play is called updateCurrentTitle(); } /* -------------------------- Basic controls & progress ---------------------------*/ playBtn.addEventListener('click', ()=> { player.play(); resumeAudioCtx(); }); pauseBtn.addEventListener('click', ()=> player.pause()); stopBtn.addEventListener('click', ()=> { player.pause(); player.currentTime = 0; }); vol.addEventListener('input', () => { if(gainNode) gainNode.gain.value = parseFloat(vol.value); volPct.textContent = Math.round(vol.value*100)+'%'; }); /* progress bar and time */ player.addEventListener('timeupdate', ()=>{ if(isFinite(player.duration) && player.duration > 0){ const pct = (player.currentTime / player.duration) * 100; progress.value = pct; timeNow.textContent = formatTime(player.currentTime); timeTotal.textContent = formatTime(player.duration); } else { progress.value = 0; timeNow.textContent = '00:00'; timeTotal.textContent = '00:00'; } }); progress.addEventListener('input', ()=> { if(player.duration) player.currentTime = (progress.value/100)*player.duration; }); function formatTime(sec){ if(!isFinite(sec) || isNaN(sec)) return '00:00'; const m = Math.floor(sec/60), s = Math.floor(sec%60); return `${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`; } function updateCurrentTitle(){ const el = document.getElementById('currentTrack'); el && (el.textContent = tracks[currentIndex] ? tracks[currentIndex].name : ''); } /* -------------------------- Web Audio: real VU meters + EQ ---------------------------*/ let audioCtx = null; let sourceNode = null; let splitter = null; let analyserL = null; let analyserR = null; let masterAnalyser = null; let gainNode = null; let eqFilters = []; function initAudioNodes(){ if(audioCtx) return; audioCtx = new (window.AudioContext || window.webkitAudioContext)(); sourceNode = audioCtx.createMediaElementSource(player); gainNode = audioCtx.createGain(); gainNode.gain.value = parseFloat(vol.value); // EQ filters (peaking) const freqs = [60,250,1000,4000,16000]; eqFilters = freqs.map(f=>{ const b = audioCtx.createBiquadFilter(); b.type = 'peaking'; b.frequency.value = f; b.Q.value = 1; b.gain.value = 0; return b; }); // chain: source -> eq0 -> eq1 -> ... -> gain -> destination sourceNode.connect(eqFilters[0]); for(let i=0;i<eqFilters.length-1;i++) eqFilters[i].connect(eqFilters[i+1]); eqFilters[eqFilters.length-1].connect(gainNode); // master analyser masterAnalyser = audioCtx.createAnalyser(); masterAnalyser.fftSize = 2048; gainNode.connect(masterAnalyser); // destination gainNode.connect(audioCtx.destination); // splitter for L/R splitter = audioCtx.createChannelSplitter(2); gainNode.connect(splitter); analyserL = audioCtx.createAnalyser(); analyserR = audioCtx.createAnalyser(); analyserL.fftSize = 512; analyserR.fftSize = 512; splitter.connect(analyserL,0); splitter.connect(analyserR,1); // wire EQ sliders to filters eqIds.forEach((id,i)=>{ const s = document.getElementById(id); s.addEventListener('input', ()=> eqFilters[i].gain.value = parseFloat(s.value)); }); // start animation drawLoop(); } /* resume audio context on user interaction (browsers require) */ function resumeAudioCtx(){ if(!audioCtx) initAudioNodes(); if(audioCtx && audioCtx.state === 'suspended') audioCtx.resume(); } /* small helper: RMS level from time-domain analyser */ function getRMS(analyser){ const buf = new Uint8Array(analyser.fftSize); analyser.getByteTimeDomainData(buf); let sum = 0; for(let i=0;i<buf.length;i++){ const v = (buf[i] - 128) / 128; sum += v*v; } return Math.sqrt(sum / buf.length); } /* frequency-band energy from master analyser */ function getBandEnergy(freq, bandWidth=1){ if(!masterAnalyser) return 0; const sr = audioCtx.sampleRate; const fftSize = masterAnalyser.fftSize; const nyquist = sr / 2; const data = new Uint8Array(masterAnalyser.frequencyBinCount); masterAnalyser.getByteFrequencyData(data); const bin = Math.round((freq/nyquist) * data.length); const half = Math.max(1, Math.round(bandWidth * data.length / (nyquist))); let sum = 0, cnt = 0; for(let i=Math.max(0,bin-half); i<=Math.min(data.length-1,bin+half); i++){ sum += data[i]; cnt++; } return cnt ? (sum/cnt)/255 : 0; } /* draw needles and bars */ const nCtxL = needleL.getContext('2d'); const nCtxR = needleR.getContext('2d'); let angleL = -Math.PI/2, angleR = -Math.PI/2; function drawNeedleCanvas(ctx, canvas, angle){ const w = canvas.width, h = canvas.height; ctx.clearRect(0,0,w,h); const cx = w/2, cy = h*0.95; // arc background ctx.beginPath(); ctx.arc(cx, cy, Math.min(w,h)/1.4, Math.PI, 0); ctx.lineWidth = 7; ctx.strokeStyle = 'brown'; ctx.stroke(); // needle ctx.save(); ctx.translate(cx, cy); ctx.rotate(angle); ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo((Math.min(w,h)/2.3)*1.55, 0); ctx.strokeStyle = 'lime'; ctx.lineWidth = 6; ctx.lineCap = 'round'; ctx.stroke(); ctx.restore(); // pivot ctx.beginPath(); ctx.arc(cx, cy, 3, 0, Math.PI*2); ctx.fillStyle='#999'; ctx.fill(); } /* main animation loop */ function drawLoop(){ requestAnimationFrame(drawLoop); if(!audioCtx) return; // RMS per channel const rmsL = getRMS(analyserL); const rmsR = getRMS(analyserR); // map RMS to angle (-90deg .. +90deg) const targetL = -Math.PI/2 + (rmsL * Math.PI * 1.2); // multiplier for visible swing const targetR = -Math.PI/2 + (rmsR * Math.PI * 1.2); angleL += (targetL - angleL) * 0.14; angleR += (targetR - angleR) * 0.14; drawNeedleCanvas(nCtxL, needleL, angleL); drawNeedleCanvas(nCtxR, needleR, angleR); // bars: low / mid / high energies const low = getBandEnergy(80, 30); // around 80Hz const mid = getBandEnergy(1000, 400); // around 1kHz const high = getBandEnergy(8000, 400); // around 8-16k barLow.style.height = Math.min(100, Math.round(low*120)) + '%'; barMid.style.height = Math.min(100, Math.round(mid*120)) + '%'; barHigh.style.height = Math.min(100, Math.round(high*120)) + '%'; } /* ensure audio ctx created on play / load */ player.addEventListener('play', ()=> resumeAudioCtx()); player.addEventListener('loadedmetadata', ()=>{ if(isFinite(player.duration)) timeTotal.textContent = formatTime(player.duration); }); /* LOOP AUTOMÁTICO DE PLAYLIST */ player.addEventListener('ended', () => { if (tracks.length === 0) return; currentIndex++; if (currentIndex >= tracks.length) currentIndex = 0; loadTrack(currentIndex); player.play(); }); /* when track ends: auto next */ player.addEventListener('ended', ()=>{ if(currentIndex < tracks.length - 1){ loadTrack(currentIndex+1); player.play(); } else { player.currentTime = 0; } }); /* keyboard space play/pause */ document.addEventListener('keydown', e=> { if(e.code==='Space'){ e.preventDefault(); player.paused?player.play():player.pause(); } }); /* initial */ vol.dispatchEvent(new Event('input')); </script> </body> </html>