Skip to content

Tutto per WordPress, lo sviluppo web — e non solo

📺 Come ottenere video da una playlist YouTube tramite API: codice funzionante in 15 minuti

📺 Come ottenere video da una playlist YouTube tramite API: codice funzionante in 15 minuti

Hai inserito il link di un video di YouTube nell'editor e funziona. Ma quando ti serve un'intera playlist sul sito che raccolga automaticamente i nuovi video, copiare i link a mano ogni volta diventa un lavoro noioso.

Uno script in PHP con YouTube Data API v3 risolve il problema alla radice: recupera tutti i video da qualsiasi playlist pubblica, restituisce JSON e tu li mostri come preferisci, in una griglia di card, un elenco, una galleria. La configurazione richiede 15 minuti, ti servono solo una chiave API e PHP di base.

Ecco il codice funzionante per WordPress con gestione degli errori, paginazione e caching. L'approccio è universale: funziona in qualsiasi progetto PHP, non solo in WP.

💡 Panoramica rapida:

  • Crea una chiave API in Google Cloud Console e collegala a YouTube Data API v3
  • Invia una richiesta a playlistItems e ottieni il JSON con tutti i video della playlist
  • Analizza la risposta, raccogli thumbnail e link, mostrali in una griglia nella pagina
  • Aggiungi la paginazione per playlist con più di 50 video e il caching tramite set_transient()

Passo 1: Crea una chiave YouTube Data API v3

Una chiave API identifica la tua applicazione presso YouTube e traccia le quote. Si crea gratuitamente, il limite giornaliero è di 10.000 unità. Una chiave è più che sufficiente per la maggior parte dei siti.

Vai su Google Cloud Console con il tuo account Google. Crea un nuovo progetto, il pulsante di selezione progetto è nella barra in alto, poi Nuovo progetto. Assegnagli un nome significativo, ad esempio my-youtube-feed.

Dopo aver creato il progetto, vai su API e servizi → Libreria. Nella barra di ricerca digita YouTube Data API v3 e clicca su Abilita. Senza questo passaggio la chiave non sarà collegata all'API corretta e le richieste restituiranno 403.

Ora, la chiave vera e propria. Nel menu laterale apri Credenziali, clicca su Crea credenziali → Chiave API. Il sistema genererà una chiave e la mostrerà in una finestra modale. Copiala subito: dopo aver chiuso la finestra la chiave è visibile nell'elenco, ma il suo valore è parzialmente nascosto.

Ricordati di cliccare su Limita chiave. Nella sezione Restrizioni API seleziona YouTube Data API v3, così la chiave non funzionerà per altre API anche se finisse in un repository pubblico. Per lo sviluppo locale il referrer HTTP può essere lasciato vuoto.

La chiave ha un aspetto simile a AIzaSyD-.... Salvala in wp-config.php tramite define('YOUTUBE_API_KEY', '...') e aggiungi wp-config.php a .gitignore. Non inserire la chiave in chiaro nel codice del tema.

Passo 2: Ottieni i video da una playlist

Per la richiesta ti servono due cose: una chiave API e un ID playlist. L'ID si estrae dall'URL: apri la playlist su YouTube, copia l'indirizzo dalla barra. Il parametro list= nell'URL è l'ID playlist: ad esempio, PLp0YhAQYkolGq1e6r1m5....

Richiesta PHP di base all'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
13if (json_last_error() !== JSON_ERROR_NONE) {
14 die('JSON parsing error: ' . json_last_error_msg());
15}

Cosa succede qui. part=snippet richiede i dati di base: titolo, descrizione, thumbnail, posizione nella playlist. Per un set completo puoi specificare snippet,contentDetails,status. maxResults=50 è il massimo per richiesta, l'API restituisce 5 record di default, quindi è meglio specificare il parametro esplicitamente. Codifica playlistId tramite urlencode() in caso di caratteri speciali.

Per la produzione sostituisci file_get_contents() con wp_remote_get() (in WordPress) o cURL con timeout. Una chiamata diretta fallirà se Google è temporaneamente non disponibile o la rete è lenta. Ecco una versione con gestione degli errori HTTP:

1$response = wp_remote_get($api_url, [
2 'timeout' => 15,
3 'headers' => ['Accept' => 'application/json'],
4]);
5
6if (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);
12if ($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);

Due livelli di controllo: prima is_wp_error() intercetta i fallimenti di rete, poi verifichiamo il codice HTTP. Se qualcosa va storto, restituiamo un array vuoto, il sito non va in crash.

Passo 3: Mostra l'elenco video in una pagina

L'API restituisce un array items. Ogni elemento è un video della playlist. Struttura della risposta:

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 è identificato da resourceId.videoId. Da esso si compone il link https://www.youtube.com/watch?v=<videoId>. Le thumbnail sono in thumbnails a tre risoluzioni: per una griglia di card prendi medium, per un elenco compatto default.

Codice di output per WordPress, shortcode o template di pagina:

1if (! 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}

Tre accorgimenti che fanno risparmiare tempo di debug:

  • loading="lazy". Con 50 video in una pagina senza lazy loading PageSpeed crollerà. L'attributo dice al browser: carica l'immagine solo quando ci scorri sopra.
  • esc_html()** e esc_url().** Sanitizzazione obbligatoria per WordPress. I titoli dei video a volte contengono virgolette ed entità HTML, senza escaping romperanno il layout.
  • target="_blank"** con rel="noopener".** Apri YouTube in una nuova scheda, ma senza dargli accesso a window.opener, protezione contro il tab-napping.

CSS per la griglia, minimale, per un tema standard:

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 griglia si adatta automaticamente alla larghezza dello schermo: auto-fill + minmax(280px, 1fr) danno da una a più colonne senza media query.

Passo 4: Paginazione, quote ed errori comuni

Paginazione. Una richiesta restituisce al massimo 50 video. Se nella playlist ce ne sono di più, nella risposta compare il campo nextPageToken. Passalo nella richiesta successiva, l'API restituirà la pagina seguente. Ciclo:

1$all_items = [];
2$page_token = null;
3
4do {
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);

Il ciclo si interrompe a 500 video, un tetto ragionevole per una pagina di un sito. Senza un limite rischi di consumare l'intera quota in un paio di caricamenti.

Quote. Ogni chiamata playlistItems.list costa 1 unità di quota, come confermato dalla tabella ufficiale delle quote di Google. Il limite giornaliero è di 10.000 unità. Sono 10.000 richieste al giorno, più che sufficienti per la stragrande maggioranza dei siti. Ma se la playlist si aggiorna frequentemente, aggiungi il caching:

1$cache_key = 'yt_playlist_' . md5($playlist_id);
2$cached_data = get_transient($cache_key);
3
4if ($cached_data !== false) {
5 return $cached_data;
6}
7
8// ... API request ...
9
10set_transient($cache_key, $data, HOUR_IN_SECONDS * 6);

Sei ore sono un buon equilibrio tra freschezza ed economia di quota. Per playlist non critiche imposta 12-24 ore. get_transient() e set_transient() sono funzioni native di WordPress, funzionano con la object cache (Redis/Memcached) se configurata, altrimenti scrivono su wp_options.

Errori comuni e come gestirli:

  • 403 Forbidden. L'API non è abilitata per il progetto in Google Cloud Console. Torna al passo 1: il pulsante Abilita per YouTube Data API v3 deve essere cliccato. Controlla anche se c'è una restrizione IP nelle impostazioni della chiave.
  • 400 Bad Request, «API key not valid». La chiave è stata appena creata e non si è ancora attivata. Aspetta 2-5 minuti: le restrizioni API non si propagano istantaneamente.
  • 404 Not Found. ID playlist non valido, oppure la playlist è privata. Una chiave API restituisce solo playlist pubbliche e non in elenco. Quelle private richiedono l'autorizzazione OAuth.
  • Array items vuoto con ID valido. Molto probabilmente la playlist è vuota. Apri l'URL della playlist in un browser e assicurati che ci siano video.

💻 Video: YouTube Data API v3 in azione

Un breve video sull'argomento, mostra visivamente l'intero processo dalla creazione della chiave alla visualizzazione dell'elenco video:

⁉️🤔 Domande frequenti

L'API funziona con le playlist private?

No. playlistItems.list con una chiave API restituisce solo playlist pubbliche e non in elenco. Per quelle private serve l'autorizzazione OAuth: l'utente deve concedere esplicitamente alla tua applicazione l'accesso al proprio account. Per un sito aggregatore pubblico basta una chiave API.

Posso ottenere i video dalla playlist di qualcun altro?

Sì, se la playlist è pubblica. Una chiave API non è legata al proprietario della playlist, identifica la tua applicazione, non l'utente YouTube. Qualsiasi playlist pubblica è accessibile tramite ID, indipendentemente da chi l'ha creata.

Come ottengo più di 50 video in una volta sola?

Non puoi, è un limite fisso di maxResults per playlistItems, stabilito nella documentazione di Google. Usa la paginazione tramite nextPageToken (passo 4). Per una playlist di 300 video serviranno 6 richieste sequenziali, che insieme spenderanno 6 unità di quota sulle 10.000 giornaliere.

Perché le thumbnail dei video non vengono visualizzate?

Controlla l'URL in thumbnails: il campo si chiama url, non link e non src. Secondo motivo, gli ad blocker a volte bloccano il dominio i.ytimg.com. Terzo: alcuni video vecchi (prima del 2010) non hanno thumbnail ad alta risoluzione, prendi default, c'è sempre.

Cosa fare se la chiave è compromessa?

Vai subito su Google Cloud Console → Credenziali, trova la chiave e clicca su Elimina. Creane una nuova. La vecchia chiave viene disattivata entro 5 minuti. Conserva la chiave tramite define('YOUTUBE_API_KEY', '...') in wp-config.php ed escludi questo file dal repository tramite .gitignore.

Se per il sito basta una playlist statica via iframe, non ti serve l'API, YouTube fornisce un codice embed già pronto. Ma non appena hai bisogno di raccogliere automaticamente i nuovi video, filtrare per data, personalizzare il layout o mostrare le thumbnail in un design non standard, l'API diventa l'unica opzione praticabile.

Per un sito WordPress la combinazione wp_remote_get() + set_transient() elimina completamente i problemi di quota e velocità: una volta ogni poche ore lo script recupera il JSON, lo mette in cache e il frontend lavora con la cache istantaneamente. La playlist si aggiorna da sola, l'editor non deve cliccare nulla.

Se il tuo tema supporta PHP personalizzato nei template, prendi il codice del passo 3, modifica il CSS per adattarlo al tuo design. Se usi un page builder, racchiudi la logica PHP in uno shortcode e inseriscilo ovunque tramite [youtube_playlist id="PLp0..."].

Prova con una playlist: 15 minuti per una chiave e la prima richiesta, e capirai se l'approccio funziona per il tuo caso. E se hai già usato l'API per altri scopi, scrivi nei commenti quale endpoint si è rivelato più utile.