
📺 Cómo obtener videos de una lista de reproducción de YouTube mediante API: código funcional en 15 minutos
Usted suelta un enlace de un video de YouTube en el editor y funciona. Pero cuando necesita una lista de reproducción completa en su sitio que recoja automáticamente los videos nuevos, copiar enlaces manualmente cada vez se vuelve una tarea tediosa.
Un script en PHP con la API de datos de YouTube v3 resuelve el problema por completo: extrae todos los videos de cualquier lista de reproducción pública, devuelve JSON y usted los muestra como quiera: una cuadrícula de tarjetas, una lista, una galería. La configuración toma 15 minutos, solo necesita una clave de API y PHP básico.
A continuación encontrará código funcional para WordPress con manejo de errores, paginación y caché. El enfoque es universal: funciona en cualquier proyecto PHP, no solo en WP.
💡 Resumen rápido:
- Cree una clave de API en Google Cloud Console y vincúlela a la API de datos de YouTube v3
- Envíe una solicitud a playlistItems y obtenga JSON con todos los videos de la lista de reproducción
- Procese la respuesta, recopile miniaturas y enlaces, muéstrelos en una cuadrícula en la página
- Añada paginación para listas de reproducción con más de 50 videos y almacenamiento en caché mediante set_transient()
Paso 1: Crear una clave de la API de datos de YouTube v3
Una clave de API identifica su aplicación ante YouTube y controla las cuotas. Se crea de forma gratuita, el límite diario es de 10 000 unidades. Una clave es más que suficiente para la mayoría de los sitios.
Vaya a Google Cloud Console con su cuenta de Google. Cree un proyecto nuevo, el botón de selección de proyecto está en la barra superior, luego Proyecto nuevo. Asígnele un nombre significativo, por ejemplo my-youtube-feed.
Después de crear el proyecto, vaya a APIs y servicios → Biblioteca. En la barra de búsqueda escriba YouTube Data API v3 y haga clic en Habilitar. Sin este paso, la clave no se vinculará a la API correcta y las solicitudes devolverán un error 403.
Ahora, la clave en sí. En el menú lateral abra Credenciales, haga clic en Crear credenciales → Clave de API. El sistema generará una clave y la mostrará en una ventana modal. Cópiela de inmediato: después de cerrar la ventana, la clave es visible en la lista, pero su valor está parcialmente oculto.
Asegúrese de hacer clic en Restringir clave. En la sección Restricciones de API seleccione YouTube Data API v3, así la clave no funcionará para otras APIs incluso si termina en un repositorio público. Para desarrollo local el referidor HTTP puede dejarse vacío.
La clave tiene un aspecto similar a AIzaSyD-.... Guárdela en wp-config.php mediante define('YOUTUBE_API_KEY', '...') y añada wp-config.php a .gitignore. No incruste la clave directamente en el código del tema.
Paso 2: Obtener videos de una lista de reproducción
Para la solicitud necesita dos cosas: una clave de API y un ID de lista de reproducción. El ID se extrae de la URL: abra la lista de reproducción en YouTube, copie la barra de direcciones. El parámetro list= en la URL es el ID de la lista de reproducción: por ejemplo, PLp0YhAQYkolGq1e6r1m5....
Solicitud PHP básica al endpoint playlistItems:
1 $api_key = 'AIzaSy...'; // your key from step 1 2 $playlist_id = 'PLp0YhAQYkolG...'; // playlist ID from URL 3 4 $api_url = 'https://www.googleapis.com/youtube/v3/playlistItems' . 5 '?part=snippet' . 6 '&maxResults=50' . 7 '&playlistId=' . urlencode($playlist_id) . 8 '&key=' . $api_key; 9 10 $response = file_get_contents($api_url); 11 $data = json_decode($response, true); 12 13 if (json_last_error() !== JSON_ERROR_NONE) { 14 die('JSON parsing error: ' . json_last_error_msg()); 15 }
Qué está sucediendo aquí. part=snippet solicita los datos básicos: título, descripción, miniatura, posición en la lista de reproducción. Para un conjunto completo puede especificar snippet,contentDetails,status. maxResults=50 es el máximo por solicitud, la API devuelve 5 registros por defecto, así que es mejor especificar el parámetro explícitamente. Codifique playlistId mediante urlencode() en caso de que tenga caracteres especiales.
Para producción, reemplace file_get_contents() con wp_remote_get() (en WordPress) o cURL con tiempo de espera. Una llamada directa fallará si Google no está disponible temporalmente o la red está lenta. Aquí tiene una versión con manejo de errores HTTP:
1 $response = wp_remote_get($api_url, [ 2 'timeout' => 15, 3 'headers' => ['Accept' => 'application/json'], 4 ]); 5 6 if (is_wp_error($response)) { 7 error_log('YouTube API error: ' . $response->get_error_message()); 8 return []; 9 } 10 11 $http_code = wp_remote_retrieve_response_code($response); 12 if ($http_code !== 200) { 13 error_log('YouTube API HTTP ' . $http_code); 14 return []; 15 } 16 17 $body = wp_remote_retrieve_body($response); 18 $data = json_decode($body, true);
Dos niveles de verificación: primero is_wp_error() detecta fallos de red, luego verificamos el código HTTP. Si algo sale mal, devolvemos un array vacío, el sitio no se bloquea.
Paso 3: Mostrar la lista de videos en una página
La API devuelve un array items. Cada elemento es un video de la lista de reproducción. Estructura de la respuesta:
1 { 2 "items": [ 3 { 4 "snippet": { 5 "title": "Video title", 6 "description": "Description...", 7 "thumbnails": { 8 "default": { "url": "https://i.ytimg.com/.../default.jpg" }, 9 "medium": { "url": "https://i.ytimg.com/.../mqdefault.jpg" }, 10 "high": { "url": "https://i.ytimg.com/.../hqdefault.jpg" } 11 }, 12 "resourceId": { 13 "videoId": "dQw4w9WgXcQ" 14 } 15 } 16 } 17 ] 18 }
Un video se identifica por resourceId.videoId. A partir de él se construye el enlace https://www.youtube.com/watch?v=<videoId>. Las miniaturas están en thumbnails en tres resoluciones: para una cuadrícula de tarjetas use medium, para una lista compacta, default.
Código de salida para WordPress, shortcode o plantilla de página:
1 if (! empty($data['items'])) { 2 echo '<div class="yt-playlist-grid">'; 3 4 foreach ($data['items'] as $item) { 5 $title = esc_html($item['snippet']['title']); 6 $video_id = esc_attr($item['snippet']['resourceId']['videoId']); 7 $thumbnail = esc_url($item['snippet']['thumbnails']['medium']['url']); 8 $link = 'https://www.youtube.com/watch?v=' . $video_id; 9 10 printf( 11 '<a href="%s" class="yt-card" target="_blank" rel="noopener">' 12 . '<img src="%s" alt="%s" loading="lazy">' 13 . '<span>%s</span></a>', 14 $link, $thumbnail, $title, $title 15 ); 16 } 17 18 echo '</div>'; 19 }
Tres cosas que ahorran tiempo de depuración:
loading="lazy". Con 50 videos en una página sin carga diferida el PageSpeed se desplomará. El atributo le dice al navegador: cargue la imagen solo cuando se desplace hasta ella.esc_html()** yesc_url().** Saneamiento obligatorio para WordPress. Los títulos de los videos a veces contienen comillas y entidades HTML, sin escape romperán la maquetación.target="_blank"** conrel="noopener".** Abra YouTube en una pestaña nueva, pero no le dé acceso awindow.opener, protección contra el secuestro de pestañas.
CSS para la cuadrícula, mínimo, para un tema estándar:
1 .yt-playlist-grid { 2 display: grid; 3 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); 4 gap: 20px; 5 } 6 .yt-card { 7 text-decoration: none; 8 color: inherit; 9 border-radius: 8px; 10 overflow: hidden; 11 transition: transform 0.2s; 12 } 13 .yt-card:hover { 14 transform: translateY(-2px); 15 } 16 .yt-card img { 17 width: 100%; 18 aspect-ratio: 16 / 9; 19 object-fit: cover; 20 } 21 .yt-card span { 22 display: block; 23 padding: 10px; 24 font-weight: 600; 25 font-size: 14px; 26 }
La cuadrícula se ajusta automáticamente al ancho de la pantalla: auto-fill + minmax(280px, 1fr) dan de una a varias columnas sin media queries.
Paso 4: Paginación, cuotas y errores comunes
Paginación. Una solicitud devuelve un máximo de 50 videos. Si hay más en la lista de reproducción, aparece un campo nextPageToken en la respuesta. Páselo en la siguiente solicitud, la API devolverá la página siguiente. Bucle:
1 $all_items = []; 2 $page_token = null; 3 4 do { 5 $url = $api_url . '&pageToken=' . urlencode($page_token ?? ''); 6 // ... API request ... 7 $all_items = array_merge($all_items, $data['items'] ?? []); 8 $page_token = $data['nextPageToken'] ?? null; 9 } while ($page_token && count($all_items) < 500);
El bucle se interrumpe en 500 videos, un límite razonable para una página de sitio. Sin un límite, corre el riesgo de agotar toda la cuota en un par de cargas.
Cuotas. Cada llamada a playlistItems.list cuesta 1 unidad de cuota, esto está confirmado por la tabla de cuotas oficial de Google. El límite diario es de 10 000 unidades. Eso son 10 000 solicitudes al día, más que suficiente para la gran mayoría de los sitios. Pero si la lista de reproducción se actualiza con frecuencia, añada almacenamiento en caché:
1 $cache_key = 'yt_playlist_' . md5($playlist_id); 2 $cached_data = get_transient($cache_key); 3 4 if ($cached_data !== false) { 5 return $cached_data; 6 } 7 8 // ... API request ... 9 10 set_transient($cache_key, $data, HOUR_IN_SECONDS * 6);
Seis horas es un equilibrio razonable entre frescura y economía de cuota. Para listas de reproducción no críticas, establezca de 12 a 24 horas. get_transient() y set_transient() son funciones nativas de WordPress, funcionan con caché de objetos (Redis/Memcached) si está configurado, de lo contrario escriben en wp_options.
Errores comunes y qué hacer al respecto:
- 403 Forbidden. La API no está habilitada para el proyecto en Google Cloud Console. Vuelva al paso 1: debe hacer clic en el botón Habilitar para la API de datos de YouTube v3. Verifique también si hay una restricción de IP en la configuración de la clave.
- 400 Bad Request, «API key not valid». La clave se acaba de crear y aún no se ha activado. Espere de 2 a 5 minutos: las restricciones de la API no se propagan instantáneamente.
- 404 Not Found. ID de lista de reproducción no válido, o la lista de reproducción es privada. Una clave de API solo devuelve listas de reproducción públicas y no listadas. Las privadas requieren autorización OAuth.
- Array
itemsvacío con un ID válido. Lo más probable es que la lista de reproducción esté vacía. Abra la URL de la lista de reproducción en un navegador y asegúrese de que haya videos.
💻 Video: API de datos de YouTube v3 en acción
Un video corto sobre el tema, muestra visualmente todo el proceso desde la creación de una clave hasta la visualización de una lista de videos:
⁉️🤔 Preguntas frecuentes
¿Funciona la API con listas de reproducción privadas?
No.
playlistItems.listcon una clave de API solo devuelve listas de reproducción públicas y no listadas. Para las privadas necesita autorización OAuth: el usuario debe otorgar explícitamente a su aplicación acceso a su cuenta. Para un sitio agregador público, una clave de API es suficiente.
¿Puedo obtener videos de la lista de reproducción de otra persona?
Sí, si la lista de reproducción es pública. Una clave de API no está vinculada al propietario de la lista de reproducción, identifica su aplicación, no al usuario de YouTube. Cualquier lista de reproducción pública es accesible por ID, independientemente de quién la haya creado.
¿Cómo obtengo más de 50 videos a la vez?
No puede, es un límite fijo de
maxResultsparaplaylistItems, establecido en la documentación de Google. Use la paginación mediantenextPageToken(paso 4). Para una lista de reproducción de 300 videos necesitará 6 solicitudes secuenciales, juntas gastarán 6 unidades de cuota de las 10 000 diarias.
¿Por qué no se muestran las miniaturas de los videos?
Verifique la URL en
thumbnails: el campo se llamaurl, nolinknisrc. Segunda razón, los bloqueadores de anuncios a veces cortan el dominioi.ytimg.com. Tercera: algunos videos antiguos (anteriores a 2010) no tienen miniaturas de alta resolución, usedefault, siempre está presente.
¿Qué hacer si la clave se ve comprometida?
Vaya inmediatamente a Google Cloud Console → Credenciales, busque la clave y haga clic en Eliminar. Cree una nueva. La clave antigua se desactiva en 5 minutos. Almacene la clave mediante
define('YOUTUBE_API_KEY', '...')enwp-config.phpy excluya este archivo del repositorio mediante.gitignore.
¿Vale la pena molestarse con la API si puede simplemente pegar un enlace de lista de reproducción?
Si una lista de reproducción estática mediante iframe es suficiente para el sitio, no necesita la API, YouTube proporciona código de inserción listo para usar. Pero tan pronto como necesite recoger automáticamente nuevos videos, filtrar por fecha, personalizar el diseño o mostrar miniaturas en un diseño no estándar, la API se convierte en la única opción viable.
Para un sitio WordPress, la combinación wp_remote_get() + set_transient() elimina por completo las preocupaciones de cuota y velocidad: una vez cada pocas horas el script obtiene JSON, lo almacena en caché, y el frontend trabaja con la caché instantáneamente. La lista de reproducción se actualiza sola, el editor no necesita hacer clic en nada.
Si su tema admite PHP personalizado en plantillas, tome el código del paso 3, cambie el CSS para que coincida con su diseño. Si está usando un constructor de páginas, envuelva la lógica PHP en un shortcode e insértelo en cualquier lugar mediante [youtube_playlist id="PLp0..."].
Pruébelo con una lista de reproducción: 15 minutos para una clave y la primera solicitud, y verá si el enfoque funciona para su tarea. Y si ya ha usado la API para otros fines, escriba en los comentarios qué endpoint le resultó más útil.



