Skip to content

Tudo para WordPress, desenvolvimento web — e não só

📺 Como obter vídeos de uma playlist do YouTube via API: código funcional em 15 minutos

📺 Como obter vídeos de uma playlist do YouTube via API: código funcional em 15 minutos

Deixou cair um link de vídeo do YouTube no editor e funciona. Mas quando precisa de uma playlist inteira no seu site que detete automaticamente novos vídeos, copiar links manualmente de cada vez torna-se uma tarefa repetitiva.

Um script em PHP com a YouTube Data API v3 resolve o problema por completo: extrai todos os vídeos de qualquer playlist pública, devolve JSON e pode exibi-los como quiser, seja como uma grelha de cartões, uma lista ou uma galeria. A configuração demora 15 minutos, só precisa de uma chave de API e de PHP básico.

Abaixo encontra código funcional para WordPress com tratamento de erros, paginação e cache. A abordagem é universal: funciona em qualquer projeto PHP, não apenas em WP.

💡 Visão geral rápida:

  • Crie uma chave de API na Google Cloud Console e associe-a à YouTube Data API v3
  • Envie um pedido a playlistItems e obtenha JSON com todos os vídeos da playlist
  • Analise a resposta, recolha miniaturas e links, exiba-os numa grelha na página
  • Adicione paginação para playlists com mais de 50 vídeos e cache via set_transient()

Passo 1: Criar uma chave da YouTube Data API v3

Uma chave de API identifica a sua aplicação junto do YouTube e monitoriza as quotas. É criada gratuitamente, o limite diário é de 10.000 unidades. Uma chave é mais do que suficiente para a maioria dos sites.

Aceda à Google Cloud Console com a sua conta Google. Crie um novo projeto, o botão de seleção de projeto está na barra superior, depois Novo Projeto. Dê-lhe um nome significativo, por exemplo my-youtube-feed.

Depois de criar o projeto, vá a APIs e Serviços → Biblioteca. Na barra de pesquisa escreva YouTube Data API v3 e clique em Ativar. Sem este passo, a chave não ficará associada à API correta e os pedidos devolverão 403.

Agora, a chave em si. No menu lateral, abra Credenciais, clique em Criar Credenciais → Chave de API. O sistema irá gerar uma chave e mostrá-la numa janela modal. Copie-a imediatamente: depois de fechar a janela, a chave fica visível na lista, mas o seu valor está parcialmente oculto.

Certifique-se de que clica em Restringir chave. Na secção Restrições de API, selecione YouTube Data API v3, assim a chave não funcionará para outras APIs, mesmo que acabe num repositório público. Para desenvolvimento local, o referenciador HTTP pode ser deixado em branco.

A chave tem o aspeto AIzaSyD-.... Guarde-a no wp-config.php através de define('YOUTUBE_API_KEY', '...') e adicione o wp-config.php ao .gitignore. Não escreva a chave diretamente no código do tema.

Passo 2: Obter vídeos de uma playlist

Para o pedido, precisa de duas coisas: uma chave de API e um ID de playlist. O ID é extraído do URL: abra a playlist no YouTube, copie a barra de endereço. O parâmetro list= no URL é o ID da playlist: por exemplo, PLp0YhAQYkolGq1e6r1m5....

Pedido PHP básico ao 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}

O que está a acontecer aqui. part=snippet solicita dados básicos: título, descrição, miniatura, posição na playlist. Para um conjunto completo, pode especificar snippet,contentDetails,status. maxResults=50 é o máximo por pedido, a API devolve 5 registos por defeito, por isso é melhor especificar o parâmetro explicitamente. Codifique o playlistId com urlencode() para o caso de conter caracteres especiais.

Para produção, substitua file_get_contents() por wp_remote_get() (no WordPress) ou cURL com timeout. Uma chamada direta falhará se o Google estiver temporariamente indisponível ou a rede estiver lenta. Aqui está uma versão com tratamento de erros 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);

Dois níveis de verificação: primeiro, is_wp_error() deteta falhas de rede, depois verificamos o código HTTP. Se algo correr mal, devolvemos um array vazio, o site não vai abaixo.

Passo 3: Exibir a lista de vídeos numa página

A API devolve um array items. Cada elemento é um vídeo da playlist. Estrutura da resposta:

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}

Um vídeo é identificado por resourceId.videoId. A partir dele, constrói-se o link https://www.youtube.com/watch?v=<videoId>. As miniaturas estão em thumbnails em três resoluções: para uma grelha de cartões, escolha medium; para uma lista compacta, default.

Código de saída para WordPress, shortcode ou template de página:

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}

Três coisas que poupam tempo de depuração:

  • loading="lazy". Com 50 vídeos numa página sem lazy loading, o PageSpeed irá cair. O atributo diz ao navegador: carregue a imagem apenas quando for feito scroll até ela.
  • esc_html()** e esc_url().** Higienização obrigatória para WordPress. Os títulos dos vídeos por vezes contêm aspas e entidades HTML, sem escape, irão quebrar o layout.
  • target="_blank"** com rel="noopener".** Abra o YouTube num novo separador, mas não lhe dê acesso ao window.opener, proteção contra tab-napping.

CSS para a grelha, mínimo, para um tema padrão:

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}

A grelha ajusta-se automaticamente à largura do ecrã: auto-fill + minmax(280px, 1fr) proporcionam de uma a várias colunas sem media queries.

Passo 4: Paginação, quotas e erros comuns

Paginação. Um pedido devolve um máximo de 50 vídeos. Se houver mais na playlist, aparece um campo nextPageToken na resposta. Passe-o no pedido seguinte, a API devolverá a página seguinte. 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);

O ciclo é interrompido aos 500 vídeos, um teto razoável para uma página de site. Sem um limite, arrisca-se a gastar toda a quota em dois ou três carregamentos.

Quotas. Cada chamada a playlistItems.list custa 1 unidade de quota, isto é confirmado pela tabela de quotas oficial da Google. O limite diário é de 10.000 unidades. São 10.000 pedidos por dia, mais do que suficiente para a grande maioria dos sites. Mas se a playlist for atualizada com frequência, adicione cache:

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);

Seis horas é um equilíbrio razoável entre atualidade e economia de quota. Para playlists não críticas, defina 12 a 24 horas. get_transient() e set_transient() são funções nativas do WordPress, funcionam com cache de objetos (Redis/Memcached) se estiver configurada, caso contrário, escrevem em wp_options.

Erros comuns e o que fazer:

  • 403 Forbidden. A API não está ativada para o projeto na Google Cloud Console. Volte ao passo 1: o botão Ativar da YouTube Data API v3 tem de ser clicado. Verifique também se existe uma restrição de IP nas definições da chave.
  • 400 Bad Request, «API key not valid». A chave foi criada recentemente e ainda não foi ativada. Aguarde 2 a 5 minutos: as restrições da API não se propagam instantaneamente.
  • 404 Not Found. ID de playlist inválido ou a playlist é privada. Uma chave de API só devolve playlists públicas e não listadas. As privadas requerem autorização OAuth.
  • Array items vazio com ID válido. Muito provavelmente, a playlist está vazia. Abra o URL da playlist num navegador e certifique-se de que tem vídeos.

💻 Vídeo: YouTube Data API v3 em ação

Um pequeno vídeo sobre o tema, mostra visualmente todo o processo, desde a criação de uma chave até à exibição de uma lista de vídeos:

⁉️🤔 Perguntas frequentes

A API funciona com playlists privadas?

Não. playlistItems.list com uma chave de API só devolve playlists públicas e não listadas. Para as privadas, precisa de autorização OAuth: o utilizador tem de conceder explicitamente à sua aplicação acesso à sua conta. Para um site agregador público, uma chave de API é suficiente.

Posso obter vídeos da playlist de outra pessoa?

Sim, se a playlist for pública. Uma chave de API não está associada ao proprietário da playlist, identifica a sua aplicação, não o utilizador do YouTube. Qualquer playlist pública é acessível pelo ID, independentemente de quem a criou.

Como obtenho mais de 50 vídeos de uma só vez?

Não pode, é um limite rígido do maxResults para playlistItems, fixado na documentação da Google. Use a paginação via nextPageToken (passo 4). Para uma playlist de 300 vídeos, precisará de 6 pedidos sequenciais, que, juntos, gastarão 6 unidades de quota das 10.000 diárias.

Porque é que as miniaturas dos vídeos não aparecem?

Verifique o URL em thumbnails: o campo chama-se url, não link nem src. Segunda razão, os bloqueadores de anúncios por vezes cortam o domínio i.ytimg.com. Terceira: alguns vídeos antigos (antes de 2010) não têm miniaturas de alta resolução, escolha default, está sempre presente.

O que fazer se a chave for comprometida?

Vá imediatamente à Google Cloud Console → Credenciais, encontre a chave e clique em Eliminar. Crie uma nova. A chave antiga é desativada em 5 minutos. Guarde a chave através de define('YOUTUBE_API_KEY', '...') no wp-config.php e exclua este ficheiro do repositório via .gitignore.

Se uma playlist estática via iframe for suficiente para o site, não precisa da API, o YouTube fornece código de incorporação pronto. Mas assim que precisar de detetar automaticamente novos vídeos, filtrar por data, personalizar o layout ou exibir miniaturas num design não padronizado, a API torna-se a única opção viável.

Para um site WordPress, a combinação wp_remote_get() + set_transient() elimina completamente as preocupações com quota e velocidade: a cada poucas horas, o script obtém o JSON, guarda-o em cache e o frontend trabalha com a cache instantaneamente. A playlist atualiza-se sozinha, o editor não precisa de clicar em nada.

Se o seu tema suportar PHP personalizado nos templates, pegue no código do passo 3, altere o CSS para combinar com o seu design. Se estiver a usar um construtor de páginas, encapsule a lógica PHP num shortcode e insira-o em qualquer lugar através de [youtube_playlist id="PLp0..."].

Experimente com uma playlist: 15 minutos para uma chave e o primeiro pedido, e verá se a abordagem funciona para a sua tarefa. E se já usou a API para outros fins, escreva nos comentários qual foi o endpoint que se revelou mais útil.