Tutorial: Importar una playlist de YouTube a WordPress con título, miniatura y reproductor (gratis, con la API de YouTube)

juanfra91

juanfra91

Curioso
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Si tienes una playlist con 40 videos y quieres 40 entradas en WordPress, cada una con su título, descripción, miniatura como imagen destacada y el video embebido, hacerlo a mano te come la tarde. Así se hace gratis con la API de YouTube y un script PHP.

Parte 1: hazlo tú con la YouTube Data API

Necesitas:
  • Una clave de la YouTube Data API v3 (gratis en Google Cloud Console → APIs y servicios → Credenciales). Cada página de playlist y cada tanda de 50 videos gasta 1 unidad; la cuota por defecto es de 10.000 por día, así que una playlist de unos cientos de videos no es problema.
  • WP-CLI en el servidor, para correr el script con wp eval-file.
  • El ID de la playlist: lo que va después de list= en la URL.

Los pasos:
  1. playlistItems.list devuelve los IDs de 50 en 50, con nextPageToken mientras haya más.
  2. videos.list con hasta 50 IDs juntos trae título, descripción, etiquetas, miniaturas y duración (playlistItems no trae la duración ni todas las etiquetas).
  3. Si la URL de YouTube queda sola en una línea del contenido, WordPress la convierte en reproductor (oEmbed). No hace falta iframe.
  4. media_sideload_image() sube la miniatura a la biblioteca y set_post_thumbnail() la pone como destacada. Guardando la URL de origen en un campo personalizado, no se repiten entradas.

Guárdalo como import-playlist.php:

PHP:
<?php
// Se corre con: wp eval-file import-playlist.php
$key      = 'TU_CLAVE_DE_API';
$playlist = 'PL_ID_DE_TU_PLAYLIST';

require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/image.php';

function yt( $endpoint, $args ) {
    $url = add_query_arg( array_filter( $args ), "https://www.googleapis.com/youtube/v3/$endpoint" );
    $res = wp_remote_get( $url, [ 'timeout' => 20 ] );
    if ( is_wp_error( $res ) ) WP_CLI::error( $res->get_error_message() );
    return json_decode( wp_remote_retrieve_body( $res ), true );
}

// 1. Todos los IDs de la playlist, 50 por página
$ids = []; $token = '';
do {
    $page  = yt( 'playlistItems', [ 'part' => 'contentDetails', 'maxResults' => 50,
             'playlistId' => $playlist, 'pageToken' => $token, 'key' => $key ] );
    foreach ( $page['items'] ?? [] as $item ) $ids[] = $item['contentDetails']['videoId'];
    $token = $page['nextPageToken'] ?? '';
} while ( $token );

// 2 y 3. Detalles de a 50, un borrador por video
foreach ( array_chunk( $ids, 50 ) as $batch ) {
    $data = yt( 'videos', [ 'part' => 'snippet,contentDetails', 'id' => implode( ',', $batch ), 'key' => $key ] );
    foreach ( $data['items'] ?? [] as $v ) {
        $url = 'https://www.youtube.com/watch?v=' . $v['id'];
        if ( get_posts( [ 'post_type' => 'post', 'post_status' => 'any', 'fields' => 'ids',
             'meta_key' => '_source_url', 'meta_value' => $url ] ) ) continue; // ya importado

        $s       = $v['snippet'];
        $post_id = wp_insert_post( [
            'post_title'   => $s['title'],
            'post_content' => $url . "\n\n" . $s['description'],
            'post_status'  => 'draft',
            'tags_input'   => array_slice( $s['tags'] ?? [], 0, 5 ),
        ] );

        // 4. Miniatura como imagen destacada (maxres no existe en todos los videos)
        $thumb = $s['thumbnails']['maxres']['url'] ?? $s['thumbnails']['high']['url'];
        $img   = media_sideload_image( $thumb, $post_id, $s['title'], 'id' );
        if ( ! is_wp_error( $img ) ) set_post_thumbnail( $post_id, $img );

        // La duración viene en ISO 8601 (PT4M13S); se guarda en segundos
        $d = new DateInterval( $v['contentDetails']['duration'] );
        update_post_meta( $post_id, 'duration', $d->d * 86400 + $d->h * 3600 + $d->i * 60 + $d->s );
        update_post_meta( $post_id, '_source_url', $url );
        WP_CLI::log( "Borrador $post_id: {$s['title']}" );
    }
}

Lo que te va a pasar:
  • Los videos privados o borrados aparecen en la playlist pero no en videos.list: se saltean solos.
  • Muchos videos viejos no tienen maxresdefault.jpg; por eso el respaldo a high.
  • La clave, solo del lado del servidor y restringida a la YouTube Data API en Cloud Console.
  • Puedes correrlo cada día por cron: con el chequeo de _source_url solo agrega los videos nuevos.
 
Última edición por un moderador:
¿Te sirvió? Únete a la conversación

Con tu cuenta gratis puedes responder, escribirle al autor por mensaje privado y comprar con Saldo retenido: el pago se libera cuando recibes lo acordado.

Toma 30 segundos · vuelves a este tema al terminar
Atrás
Arriba