jueves, 9 de julio de 2026

Cómo crear un reproductor de YouTube para Blogger con portada giratoria y playlist


En este tutorial vamos a crear un reproductor de música inspirado en los reproductores clásicos, pero con un toque más cálido y decorativo.

El gadget incluye:

  • Reproducción de canciones desde YouTube.
  • Una portada que gira mientras la música está sonando.
  • Botones de reproducir, pausar, siguiente y anterior.
  • Una playlist desplegable.
  • Barra de progreso interactiva.
  • Un diseño completamente personalizable.

Todo funciona directamente desde el blog sin necesidad de abrir YouTube en otra pestaña.

Dificultad: Avanzada
Tiempo aproximado: 35 minutos
Necesitas: Un blog en Blogger + imágenes para el fondo y las portadas de las canciones


Antes de empezar

Este gadget utiliza HTML, CSS, JavaScript y la API de YouTube.

Cada parte cumple una función distinta:

  • HTML → crea la estructura del reproductor.
  • CSS → diseña la interfaz, las animaciones y la portada giratoria.
  • JavaScript → controla la reproducción, la playlist, la barra de progreso y la comunicación con YouTube.

Aunque el código es largo, está dividido en pequeños bloques independientes, lo que facilita entender cómo funciona cada parte.


Paso 1: Preparar el fondo del reproductor

El fondo se define aquí:

background-image:url("URL-DE-TU-IMAGEN");

Solo debes sustituir esa dirección por tu propia imagen.

Algunas ideas:

  • madera
  • papel antiguo
  • flores
  • naturaleza
  • una textura vintage

También puedes cambiar:

background-size:cover;
background-position:center;

si quieres otro tipo de encuadre.


Paso 2: Cambiar la portada del disco

Cada canción utiliza una imagen diferente. El proceso de la imágen es el mismo que se menciona en entradas anteriores.

Dentro de la playlist encontrarás algo como:

cover:"URL-DE-LA-PORTADA"

Solo debes cambiar esa dirección por la imagen que quieras mostrar.

Lo ideal es utilizar imágenes cuadradas para que el efecto circular se vea correctamente.


Paso 3: Entender la portada giratoria

La animación se consigue mediante:

@keyframes spin

Cuando la música comienza:

cover.classList.add("playing");

La imagen empieza a girar.

Cuando la música se pausa:

cover.classList.remove("playing");

La animación también se detiene.

Puedes modificar la velocidad aquí:

animation:spin 8s linear infinite;

Por ejemplo:

Más rápida:

animation:spin 5s linear infinite;

Más lenta:

animation:spin 15s linear infinite;

Paso 4: Añadir canciones

Toda la música se encuentra en este bloque:

const songs = [

Cada canción tiene cuatro datos:

{
    name:"name",
    artist:"artist",
    videoId:"URLvideo",
    cover:"URLimage"
}

¿Qué significa cada uno?

name

El nombre de la canción.

artist

El nombre del artista.

videoId

El identificador del vídeo de YouTube.

Por ejemplo, si el enlace es:

https://youtu.be/LAbZfjMVU0A?si=3h_LsPX-ZhG2QXJh

el videoId es únicamente:

LAbZfjMVU0A

cover

La imagen que aparecerá como portada.

Para añadir una nueva canción basta con copiar uno de los bloques y cambiar esos cuatro valores. Se pueden añadir cuantos bloques quieras.


Paso 5: Personalizar los botones

Los controles se crean aquí:

<button></button>

<button>▶ / ⏸</button>

<button></button>

Puedes sustituir los símbolos por:

  • texto
  • otros emojis
  • iconos personalizados

También puedes modificar su aspecto desde:

.btn

Cambiando:

  • color
  • bordes
  • tamaño
  • tipografía

Paso 6: La playlist desplegable

La lista de canciones permanece oculta hasta pulsar:

togglePlaylist()

Cuando se abre:

.playlist.open

aparece un pequeño panel con desplazamiento.

Puedes cambiar la altura máxima:

max-height:130px;

Si tienes muchas canciones, puedes aumentarla.


Paso 7: La barra de progreso

La barra inferior refleja el avance de la canción.

Se actualiza automáticamente gracias a:

setInterval(...)

Cada medio segundo calcula cuánto ha avanzado el vídeo.

Además, el usuario puede mover la barra manualmente para saltar a otro momento de la canción.


Paso 8: Cambiar los textos del reproductor

Actualmente aparecen estados como:

READY

PLAYING

PAUSED

Puedes traducirlos.

Por ejemplo:

Listo

Reproduciendo

Pausado

Paso 9: Instalarlo en Blogger

  1. Entra al panel de Blogger.
  2. Ve a Diseño.
  3. Selecciona Añadir un gadget.
  4. Elige HTML/Javascript.
  5. Pega el código completo.
  6. Guarda los cambios.

El reproductor aparecerá donde hayas colocado el gadget.


Personalizaciones bonitas

Cambiar la forma de la portada

Busca:

border-radius:50%;

Puedes convertir el disco en una imagen cuadrada:

border-radius:14px;
Cambiar el color del panel

Busca:

.screen

Puedes modificar:

  • transparencia
  • colores
  • bordes
Cambiar el color de la barra de progreso

Busca:

accent-color:#c86b7a;

Puedes sustituirlo por cualquier color que combine con tu blog.

Cambiar la velocidad del disco

Busca:

animation:spin 8s linear infinite;

Cuanto menor sea el número, más rápido girará.


Ideas para usar este gadget

Este reproductor puede servir para:

  • ☕ compartir la música que acompaña tus entradas
  • 📖 crear una banda sonora para tu blog
  • 🌙 recomendar canciones del mes
  • 🍂 hacer playlists según la estación del año
  • 🎼 acompañar una sección de recomendaciones musicales

También puedes crear listas temáticas, como:

  • música para estudiar
  • canciones tranquilas
  • clásicos favoritos
  • descubrimientos del mes

La historia detrás del gadget

Muchas veces la música forma parte del recuerdo que tenemos de un lugar. Este reproductor nació con la idea de que un blog también pudiera tener su propia banda sonora, no solo como un complemento, sino como otra forma de contar quién eres y qué ambiente quieres transmitir. La portada girando lentamente recuerda a los discos de vinilo y a esos momentos en los que una canción sonaba de principio a fin sin prisas. La playlist invita a descubrir nuevas melodías y a quedarse un rato más, acompañando la lectura con música.

Porque, al igual que las palabras, las canciones también pueden hacer que un rincón digital se sienta más vivo.

Código:

<style>

@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+JP:wght@300;400&display=swap');


.yt-player {

  width: 100%;

  max-width: 280px;

  font-family: "Noto Serif JP", serif;


  /* 🌸 FIX REAL: background-image (más compatible que shorthand) */

  background-image: url("URLimage");

  background-size: cover;

  background-position: center;

  background-repeat: no-repeat;


  border-radius: 18px;

  padding: 14px;

  box-shadow: 0 12px 30px rgba(0,0,0,0.18);


  position: relative;

  overflow: hidden;

}


/* 🌑 overlay seguro (no bloquea clicks) */

.yt-player::before {

  content: "";

  position: absolute;

  inset: 0;

  background: rgba(0, 0, 0, 0.45);

  border-radius: 18px;

  z-index: 1;

  pointer-events: none;

}


/* 🔝 capas correctas */

.yt-player > * {

  position: relative;

  z-index: 2;

}


/* YouTube por encima del overlay */

#ytPlayer {

  position: relative;

  z-index: 3;

}


/* portada */

.cover {

  width: 100%;

  height: 150px;

  border-radius: 14px;

  overflow: hidden;

  margin-bottom: 10px;

}


.cover{

  width:100%;

  height:150px;

  border-radius:50%;

  overflow:hidden;

  margin-bottom:10px;

  display:flex;

  align-items:center;

  justify-content:center;

  background:rgba(255,255,255,.12);

  box-shadow:

    inset 0 0 20px rgba(255,255,255,.12),

    0 8px 18px rgba(0,0,0,.35);

  position:relative;

}


/* centro del "vinilo" */

.cover::after{

  content:"";

  position:absolute;

  width:18px;

  height:18px;

  background:#f5f5f5;

  border:4px solid #555;

  border-radius:50%;

  z-index:2;

}


.cover img{

  width:100%;

  height:100%;

  object-fit:cover;

  border-radius:50%;

  animation:spin 8s linear infinite;

  animation-play-state:paused;

}


.cover img.playing{

  animation-play-state:running;

}


@keyframes spin{

  from{

    transform:rotate(0deg);

  }

  to{

    transform:rotate(360deg);

  }

}

/* pantalla */

.screen {

  background: rgba(255,255,255,0.45);

  border-radius: 12px;

  padding: 10px;

  font-size: 12px;

  color: #5a2a2a;

}


/* controles */

.controls {

  display: flex;

  gap: 4px;

  margin-top: 10px;

}


.btn {

  flex: 1;

  border: none;

  padding: 6px;

  border-radius: 10px;

  cursor: pointer;

  background: rgba(255,255,255,0.6);

  font-size: 11px;

}


/* progress */

#progress {

  width: 100%;

  margin-top: 8px;

  accent-color: #c86b7a;

}


/* playlist toggle */

.playlist-toggle {

  margin-top: 10px;

  width: 100%;

  border: none;

  padding: 6px;

  border-radius: 10px;

  background: rgba(255,255,255,0.6);

  cursor: pointer;

  font-size: 11px;

}


/* playlist */

.playlist {

  margin-top: 10px;

  max-height: 0;

  overflow: hidden;

  font-size: 11px;

  transition: max-height 0.4s ease;

}


/* scroll cuando abierta */

.playlist.open {

  max-height: 130px;

  overflow-y: auto;

  scrollbar-width: thin;

}


.playlist.open::-webkit-scrollbar {

  width: 4px;

}


.playlist.open::-webkit-scrollbar-thumb {

  background: rgba(255,255,255,0.5);

  border-radius: 10px;

}


/* canciones */

.song {

  padding: 6px;

  border-radius: 8px;

  cursor: pointer;

}


.song:hover {

  background: rgba(255,255,255,0.4);

}


.song.active {

  background: rgba(255,255,255,0.7);

}


/* artista */

.artist {

  font-size: 9px;

  opacity: 0.7;

  margin-top: 2px;

}

</style>


<div class="yt-player">


  <div class="cover">

    <img id="cover" src="" />

  </div>


  <div class="screen">

    🎧 <b id="title">IGARI YOUTUBE</b><br />

    <div class="artist" id="artist"></div>

    <span id="status">READY</span>

  </div>


  <div class="controls">

    <button class="btn" onclick="prev()">⏮</button>

    <button class="btn" onclick="toggle()">▶ / ⏸</button>

    <button class="btn" onclick="next()">⏭</button>

  </div>


  <input type="range" id="progress" min="0" max="100" value="0" />


  <button class="playlist-toggle" onclick="togglePlaylist()">🎼 Playlist</button>


  <div class="playlist" id="playlist"></div>


  <div id="ytPlayer"></div>


</div>


<script src="https://www.youtube.com/iframe_api"></script>


<script>


let player;

let current = 0;

let isPlaying = false;


const songs = [

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" },

  { name: "Name", artist: "Artist", videoId: "VideoId", cover: "URLimage" }

];


const playlist = document.getElementById("playlist");

const title = document.getElementById("title");

const artist = document.getElementById("artist");

const status = document.getElementById("status");

const cover = document.getElementById("cover");

const progress = document.getElementById("progress");


songs.forEach((s, i) => {

  const div = document.createElement("div");

  div.className = "song";

  div.innerHTML = s.name + `<div class="artist">${s.artist}</div>`;

  div.onclick = () => load(i);

  playlist.appendChild(div);

});


function onYouTubeIframeAPIReady() {

  player = new YT.Player('ytPlayer', {

    height: '0',

    width: '0',

    videoId: songs[0].videoId,

    events: { onReady: () => load(0) }

  });

}


function load(i) {

  current = i;

cover.classList.remove("playing");


  player.loadVideoById(songs[i].videoId);

  player.pauseVideo();


  title.innerText = songs[i].name;

  artist.innerText = songs[i].artist;

  cover.src = songs[i].cover;


  document.querySelectorAll(".song").forEach((el, idx) => {

    el.classList.toggle("active", idx === i);

  });


  status.innerText = "READY";

  isPlaying = false;

}


function toggle() {


  if (isPlaying) {


    player.pauseVideo();

    status.innerText = "PAUSED";

    cover.classList.remove("playing");


  } else {


    player.playVideo();

    status.innerText = "PLAYING";

    cover.classList.add("playing");


  }


  isPlaying = !isPlaying;


}

function next() {


  current = (current + 1) % songs.length;


  load(current);


  player.playVideo();


  cover.classList.add("playing");


  status.innerText = "PLAYING";


  isPlaying = true;


}

function prev() {


  current = (current - 1 + songs.length) % songs.length;


  load(current);


  player.playVideo();


  cover.classList.add("playing");


  status.innerText = "PLAYING";


  isPlaying = true;


}

function togglePlaylist() {

  playlist.classList.toggle("open");

}


setInterval(() => {

  if (player && player.getCurrentTime && player.getDuration) {

    progress.value = (player.getCurrentTime() / player.getDuration()) * 100 || 0;

  }

}, 500);


progress.addEventListener("input", () => {

  if (player) {

    player.seekTo((progress.value / 100) * player.getDuration(), true);

  }

});


</script>

No hay comentarios.:

Publicar un comentario

Cómo crear un reproductor de YouTube para Blogger con portada giratoria y playlist

En este tutorial vamos a crear un reproductor de música inspirado en los reproductores clásicos, pero con un toque más cálido y decorativo. ...