
📺 Hur du hämtar videor från en YouTube-spellista via API: fungerande kod på 15 minuter
Du slänger in en YouTube-länk i editorn, det fungerar. Men när du behöver en hel spellista på sajten som automatiskt plockar upp nya videor blir det en plåga att kopiera länkar manuellt varje gång.
Ett skript i PHP med YouTube Data API v3 löser problemet helt: det hämtar alla videor från vilken publik spellista som helst, returnerar JSON, och du visar dem precis som du vill, som ett rutnät av kort, en lista, ett galleri. Installationen tar 15 minuter, du behöver bara en API-nyckel och grundläggande PHP.
Här är fungerande kod för WordPress med felhantering, paginering och cachning. Metoden är universell: den fungerar i alla PHP-projekt, inte bara i WP.
💡 Snabb överblick:
- Skapa en API-nyckel i Google Cloud Console och koppla den till YouTube Data API v3
- Skicka en förfrågan till playlistItems och få JSON med alla spellistans videor
- Tolka svaret, samla in miniatyrbilder och länkar, visa dem i ett rutnät på sidan
- Lägg till paginering för spellistor med fler än 50 videor och cachning via set_transient()
Steg 1: Skapa en YouTube Data API v3-nyckel
En API-nyckel identifierar din applikation för YouTube och håller koll på kvoter. Skapas gratis, daglig gräns är 10 000 enheter. En nyckel räcker mer än väl för de flesta sajter.
Gå till Google Cloud Console med ditt Google-konto. Skapa ett nytt projekt, knappen för projektval finns i det övre fältet, sedan Nytt projekt. Ge det ett meningsfullt namn, till exempel my-youtube-feed.
När projektet är skapat, gå till API:er och tjänster → Bibliotek. Skriv YouTube Data API v3 i sökfältet och klicka på Aktivera. Utan det här steget kopplas inte nyckeln till rätt API, och förfrågningar kommer att returnera 403.
Nu till själva nyckeln. Öppna Autentiseringsuppgifter i sidomenyn, klicka på Skapa autentiseringsuppgifter → API-nyckel. Systemet genererar en nyckel och visar den i ett modalfönster. Kopiera den direkt: efter att fönstret stängts syns nyckeln i listan, men dess värde är delvis dolt.
Se till att klicka på Begränsa nyckel. I avsnittet API-begränsningar väljer du YouTube Data API v3, då fungerar inte nyckeln för andra API:er även om den skulle hamna i ett publikt repository. För lokal utveckling kan HTTP-referrer lämnas tom.
Nyckeln ser ut som AIzaSyD-.... Spara den i wp-config.php via define('YOUTUBE_API_KEY', '...') och lägg till wp-config.php i .gitignore. Hårdkoda inte nyckeln i temakoden.
Steg 2: Hämta videor från en spellista
För förfrågan behöver du två saker: en API-nyckel och ett spellist-ID. ID:t extraheras från webbadressen: öppna spellistan på YouTube, kopiera adressfältet. Parametern list= i webbadressen är spellistans ID: till exempel PLp0YhAQYkolGq1e6r1m5....
Grundläggande PHP-förfrågan till playlistItems-ändpunkten:
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 }
Vad som händer här. part=snippet begär grundläggande data: titel, beskrivning, miniatyrbild, position i spellistan. För en fullständig uppsättning kan du ange snippet,contentDetails,status. maxResults=50 är max per förfrågan, API:et returnerar 5 poster som standard, så det är bättre att ange parametern explicit. Koda playlistId via urlencode() ifall det finns specialtecken.
För produktion, ersätt file_get_contents() med wp_remote_get() (i WordPress) eller cURL med timeout. Ett direkt anrop misslyckas om Google är tillfälligt otillgängligt eller nätverket är långsamt. Här är en version med HTTP-felhantering:
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);
Två kontrollnivåer: först fångar is_wp_error() nätverksfel, sedan verifierar vi HTTP-koden. Om något går fel returnerar vi en tom array, sajten kraschar inte.
Steg 3: Visa videolistan på en sida
API:et returnerar en items-array. Varje element är en video från spellistan. Svarsstruktur:
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 }
En video identifieras av resourceId.videoId. Utifrån den sätts länken https://www.youtube.com/watch?v=<videoId> ihop. Miniatyrbilder finns i thumbnails i tre upplösningar: för ett kortrutnät ta medium, för en kompakt lista, default.
Utmatningskod för WordPress, shortcode eller sidmall:
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 }
Tre saker som sparar felsökningstid:
loading="lazy". Med 50 videor på en sida utan lazy loading kommer PageSpeed att sjunka. Attributet säger till webbläsaren: ladda bilden först när den rullas fram till.esc_html()** ochesc_url().** Obligatorisk sanering för WordPress. Videotitlar innehåller ibland citattecken och HTML-entiteter, utan escape-kodning förstör de layouten.target="_blank"** medrel="noopener".** Öppna YouTube i en ny flik, men ge det inte åtkomst tillwindow.opener, skydd mot tab-napping.
CSS för rutnätet, minimal, för ett standardtema:
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 }
Rutnätet anpassar sig automatiskt till skärmbredden: auto-fill + minmax(280px, 1fr) ger från en till flera kolumner utan media queries.
Steg 4: Paginering, kvoter och vanliga fel
Paginering. En förfrågan returnerar max 50 videor. Om det finns fler i spellistan visas ett nextPageToken-fält i svaret. Skicka med det i nästa förfrågan, så returnerar API:et nästa sida. Loop:
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);
Loopen bryter vid 500 videor, ett rimligt tak för en sajtsida. Utan en gräns riskerar du att förbruka hela kvoten på ett par laddningar.
Kvoter. Varje playlistItems.list-anrop kostar 1 kvotenhet, detta bekräftas av Googles officiella kvottabell. Daglig gräns är 10 000 enheter. Det är 10 000 förfrågningar per dag, mer än nog för de allra flesta sajter. Men om spellistan uppdateras ofta, lägg till cachning:
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);
Sex timmar är en rimlig balans mellan aktualitet och kvotekonomi. För icke-kritiska spellistor, sätt 12-24 timmar. get_transient() och set_transient() är inbyggda WordPress-funktioner, de fungerar med objektcache (Redis/Memcached) om det är konfigurerat, annars skriver de till wp_options.
Vanliga fel och vad du gör åt dem:
- 403 Forbidden. API:et är inte aktiverat för projektet i Google Cloud Console. Gå tillbaka till steg 1: knappen Aktivera för YouTube Data API v3 måste vara klickad. Kontrollera också om det finns en IP-begränsning i nyckelinställningarna.
- 400 Bad Request, "API key not valid". Nyckeln skapades precis och har inte aktiverats än. Vänta 2-5 minuter: API-begränsningar slår inte igenom omedelbart.
- 404 Not Found. Ogiltigt spellist-ID, eller så är spellistan privat. En API-nyckel returnerar bara publika och olistade spellistor. Privata kräver OAuth-auktorisering.
- Tom
items-array med giltigt ID. Troligtvis är spellistan tom. Öppna spellistans webbadress i en webbläsare och kontrollera att det finns videor.
💻 Video: YouTube Data API v3 i praktiken
En kort video om ämnet, visar visuellt hela processen från att skapa en nyckel till att visa en videolista:
⁉️🤔 Vanliga frågor
Fungerar API:et med privata spellistor?
Nej.
playlistItems.listmed en API-nyckel returnerar bara publika och olistade spellistor. För privata behöver du OAuth-auktorisering: användaren måste uttryckligen ge din applikation åtkomst till sitt konto. För en publik aggregatorsajt räcker en API-nyckel.
Kan jag hämta videor från någon annans spellista?
Ja, om spellistan är publik. En API-nyckel är inte knuten till spellistans ägare, den identifierar din applikation, inte YouTube-användaren. Alla publika spellistor är tillgängliga via ID, oavsett vem som skapade dem.
Hur får jag fler än 50 videor på en gång?
Det kan du inte, det är en hård gräns för
maxResultsförplaylistItems, fastställd i Googles dokumentation. Använd paginering vianextPageToken(steg 4). För en spellista med 300 videor behöver du 6 sekventiella förfrågningar, tillsammans förbrukar de 6 kvotenheter av 10 000 dagliga.
Varför visas inte videominiatyrerna?
Kontrollera webbadressen i
thumbnails: fältet heterurl, intelinkoch intesrc. Andra orsaken, annonsblockerare klipper ibland domäneni.ytimg.com. Tredje: vissa gamla videor (före 2010) har inte högupplösta miniatyrer, tadefault, den finns alltid där.
Vad gör jag om nyckeln har komprometterats?
Gå omedelbart till Google Cloud Console → Autentiseringsuppgifter, hitta nyckeln och klicka på Ta bort. Skapa en ny. Den gamla nyckeln avaktiveras inom 5 minuter. Lagra nyckeln via
define('YOUTUBE_API_KEY', '...')iwp-config.phpoch exkludera denna fil från repositoryt via.gitignore.
Är det värt besväret med API:et om man bara kan klistra in en spellistlänk?
Om en statisk spellista via iframe räcker för sajten behöver du inte API:et, YouTube tillhandahåller färdig inbäddningskod. Men så fort du behöver automatiskt plocka upp nya videor, filtrera efter datum, anpassa layout eller visa miniatyrer i en icke-standarddesign, blir API:et det enda fungerande alternativet.
För en WordPress-sajt eliminerar kombinationen wp_remote_get() + set_transient() helt kvot- och hastighetsproblem: en gång med några timmars mellanrum hämtar skriptet JSON, cachrar det, och frontenden arbetar med cachen direkt. Spellistan uppdaterar sig själv, redaktören behöver inte klicka på något.
Om ditt tema stöder anpassad PHP i mallar, ta koden från steg 3, ändra CSS:en så att den matchar din design. Om du använder en sidbyggare, slå in PHP-logiken i en shortcode och infoga den var som helst via [youtube_playlist id="PLp0..."].
Testa med en spellista: 15 minuter för en nyckel och den första förfrågan, så ser du om metoden fungerar för din uppgift. Och om du redan har använt API:et för andra syften, skriv i kommentarerna vilken ändpunkt som visade sig vara mest användbar.



