Neste artigo, você aprenderá como listar os últimos vídeos de um canal do YouTube utilizando a API de dados da plataforma.
Para processar os dados, utilizaremos a linguagem JavaScript.
Se você ainda não possuir uma chave de API, veja como fazer isso clicando aqui, pois sem ela não é possível acessar os dados.
Para mais postagens sobre a API do YouTube acesse: YouTube API.
Método search
A operação search
permite consultar vídeos, playlists e canais com base em parâmetros de pesquisa fornecidos na requisição. A requisição dos dados é do tipo REST e o retorno vem na forma de um arquivo JSON
.
A URL do método search
é [1]
https://www.googleapis.com/youtube/v3/search?part=[PROPRIEDADES-SOLICITADAS]&channelId=[ID-DO-CANAL]&key=[CHAVE-DE-API]&maxResults=[QTDE-DE-VIDEOS]&type=[TIPO-DE-RECURSO]&order=[MÉTODO-DE-CLASSIFICAÇÃO]
- O parâmetro
part
é obrigatório e deve conter uma lista com as propriedades solicitadas separadas por vírgula. As propriedades podem serid
e/ousnippet
. Utilizaremos ambas; channelId
é o ID do Canal que iremos listar os vídeos, que pode ser obtido acessando as configurações avançadas do canal;- O parâmetro
key
é a chave de API e é obrigatório; maxResults
é a quantidade máxima de resultados que serão retornados. O limite para o valor desse parâmetro é 50 e o valor padrão, caso você não especifique, é 5;type
indica o tipo de item que você deseja:video
,playlist
ouchannel
;order
é o método que será utilizado para classificar os resultados da pesquisa. Utilizaremos o valordate
, que ordena os resultados em ordem cronológica reversa (do mais recente para o mais antigo);
Existem mais parâmetros, porém esses são os essenciais. Todos os parâmetros devem estar codificados para URL e a requisição deve ser do tipo GET.
Você pode, por exemplo, copiar e colar essa URL no seu navegador (com os parâmetros preenchidos, é claro) e ver a resposta no próprio navegador.
Um exemplo de requisição
Para exemplificar, vamos listar os 3 últimos vídeos do canal do blog. O ID do Canal é UCRD_6Vp8VEuU_IoZHBUrkiw (esse dado é público). A URL para essa requisição será
https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&channelId=UCRD_6Vp8VEuU_IoZHBUrkiw&key=[CHAVE-DE-API]&maxResults=3&type=video&order=date
O caractere %2C
é a vírgula separando os valores id
e snippet
(lembre-se: os parâmetros devem estar codificados para URL). Em key
você deve colocar a sua chave de API.
A resposta será o seguinte arquivo JSON
:
{ "kind": "youtube#searchListResponse", "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/z7aDLhWvSKry3hrZFlEAuUNvDGI\"", "nextPageToken": "CAMQAA", "regionCode": "BR", "pageInfo": { "totalResults": 9, "resultsPerPage": 3 }, "items": [ { "kind": "youtube#searchResult", "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/VSNJDKMfmm0i--itDeV64UoVq1o\"", "id": { "kind": "youtube#video", "videoId": "QlljqUoH9_k" }, "snippet": { "publishedAt": "2018-08-19T08:30:12.000Z", "channelId": "UCRD_6Vp8VEuU_IoZHBUrkiw", "title": "Animação do Selection Sort (ordenação por Seleção)", "description": "Confira as ofertas do dia da Amazon Brasil: https://amzn.to/2vzdSb3 Animação ilustrando o funcionamento do Selection Sort (algoritmo de ordenação por ...", "thumbnails": { "default": { "url": "https://i.ytimg.com/vi/QlljqUoH9_k/default.jpg", "width": 120, "height": 90 }, "medium": { "url": "https://i.ytimg.com/vi/QlljqUoH9_k/mqdefault.jpg", "width": 320, "height": 180 }, "high": { "url": "https://i.ytimg.com/vi/QlljqUoH9_k/hqdefault.jpg", "width": 480, "height": 360 } }, "channelTitle": "Blog Cyberini", "liveBroadcastContent": "none" } }, { "kind": "youtube#searchResult", "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/xcP8tFjPRieIU9Ge0iZ7Fc2dKN4\"", "id": { "kind": "youtube#video", "videoId": "j3a9dG6SLZo" }, "snippet": { "publishedAt": "2018-08-10T03:03:27.000Z", "channelId": "UCRD_6Vp8VEuU_IoZHBUrkiw", "title": "Animação do Insertion Sort (ordenação por inserção)", "description": "Confira as ofertas do dia da Amazon Brasil: https://amzn.to/2vzdSb3 Animação ilustrando o funcionamento do Insertion Sort (algoritmo de ordenação por ...", "thumbnails": { "default": { "url": "https://i.ytimg.com/vi/j3a9dG6SLZo/default.jpg", "width": 120, "height": 90 }, "medium": { "url": "https://i.ytimg.com/vi/j3a9dG6SLZo/mqdefault.jpg", "width": 320, "height": 180 }, "high": { "url": "https://i.ytimg.com/vi/j3a9dG6SLZo/hqdefault.jpg", "width": 480, "height": 360 } }, "channelTitle": "Blog Cyberini", "liveBroadcastContent": "none" } }, { "kind": "youtube#searchResult", "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/72F0Or0NAO4XRfRkm54i6iR8re4\"", "id": { "kind": "youtube#video", "videoId": "0kmw0_-gXTc" }, "snippet": { "publishedAt": "2018-04-18T23:53:17.000Z", "channelId": "UCRD_6Vp8VEuU_IoZHBUrkiw", "title": "Gráfico de uma solução da equação de Poisson", "description": "Gráfico de uma solução da equação de Poisson. Essa equação e o programa que resolve ela foram retirados do livro \"Spectral Methods in MATLAB\" por ...", "thumbnails": { "default": { "url": "https://i.ytimg.com/vi/0kmw0_-gXTc/default.jpg", "width": 120, "height": 90 }, "medium": { "url": "https://i.ytimg.com/vi/0kmw0_-gXTc/mqdefault.jpg", "width": 320, "height": 180 }, "high": { "url": "https://i.ytimg.com/vi/0kmw0_-gXTc/hqdefault.jpg", "width": 480, "height": 360 } }, "channelTitle": "Blog Cyberini", "liveBroadcastContent": "none" } } ] }
A API não retorna a URL do vídeo porque todas as URLs de vídeos do YouTube possuem a seguinte forma
https://www.youtube.com/watch?v=[ID-DO-VIDEO]
Portanto, só precisamos do ID do vídeo para criar a URL.
Observe que a maioria dessas informações é inútil para nós, servindo apenas para aumentar o consumo de dados. Felizmente, as APIs do Google permitem realizar requisições parciais.
Requisições parciais: solicitando apenas os dados necessários
Para eliminar os dados que não utilizaremos, podemos utilizar o parâmetro fields
[4], que é padrão em todas as requisições da API de Dados do YouTube (e da API do Blogger também).
O valor do parâmetro fields
deve ser uma lista com os nomes dos campos que desejamos separados por vírgula. Se um campo tiver subcampos, então devemos colocar os subcampos desejados entre parênteses, logo após o nome do campo-pai.
Por exemplo, se quiséssemos apenas o título, a descrição, o id e a thumbnail média dos vídeos, então o parâmetro fields
seria
fields=items(id(videoId),snippet(title,description,thumbnails(medium)))
A URL da requisição do exemplo anterior teria o seguinte aspecto
https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&channelId=UCRD_6Vp8VEuU_IoZHBUrkiw&key=[CHAVE-DE-API]&maxResults=3&type=video&order=date&fields=items(id(videoId)%2Csnippet(title%2Cdescription%2Cthumbnails(medium)))
Observe que o parâmetro fields
está codificado para URL. A resposta da requisição acima seria
{ "items": [ { "id": { "videoId": "QlljqUoH9_k" }, "snippet": { "title": "Animação do Selection Sort (ordenação por Seleção)", "description": "Confira as ofertas do dia da Amazon Brasil: https://amzn.to/2vzdSb3 Animação ilustrando o funcionamento do Selection Sort (algoritmo de ordenação por ...", "thumbnails": { "medium": { "url": "https://i.ytimg.com/vi/QlljqUoH9_k/mqdefault.jpg", "width": 320, "height": 180 } } } }, { "id": { "videoId": "j3a9dG6SLZo" }, "snippet": { "title": "Animação do Insertion Sort (ordenação por inserção)", "description": "Confira as ofertas do dia da Amazon Brasil: https://amzn.to/2vzdSb3 Animação ilustrando o funcionamento do Insertion Sort (algoritmo de ordenação por ...", "thumbnails": { "medium": { "url": "https://i.ytimg.com/vi/j3a9dG6SLZo/mqdefault.jpg", "width": 320, "height": 180 } } } }, { "id": { "videoId": "0kmw0_-gXTc" }, "snippet": { "title": "Gráfico de uma solução da equação de Poisson", "description": "Gráfico de uma solução da equação de Poisson. Essa equação e o programa que resolve ela foram retirados do livro \"Spectral Methods in MATLAB\" por ...", "thumbnails": { "medium": { "url": "https://i.ytimg.com/vi/0kmw0_-gXTc/mqdefault.jpg", "width": 320, "height": 180 } } } } ] }
Comprimindo os dados
Por padrão, o arquivo JSON
das respostas das requisições são indentados, porém, numa situação prática, o código indentado não é bom, pois representa um consumo extra de dados.
Podemos utilizar o parâmetro prettyPrint
[4] com valor false
para retornar o código JSON comprimido numa única linha
https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&channelId=UCRD_6Vp8VEuU_IoZHBUrkiw&key=[CHAVE-DE-API]&maxResults=3&type=video&order=date&fields=items(id(videoId)%2Csnippet(title%2Cdescription%2Cthumbnails(medium)))&prettyPrint=false
Sem a compressão, a requisição anterior retornaria um arquivo JSON
de 1,43 KB contra 1,16 KB da versão comprimida. A diferença é ínfima porque poucos dados foram solicitados. Quanto mais dados, mais visível será a diferença. Além disso, essa pequena diferença será significativa após várias requisições.
Função de callback (só para JavaScript)
Outro parâmetro útil é o callback
[4]. Nele podemos colocar o nome de uma função JavaScript que deve ser chamada para processar a resposta, que é passada para a função como argumento.
Uma das vantagens de utilizar uma função de callback é que podemos passar a URL da requisição para uma tag script
.
Exemplo prático
A página HTML a seguir lista os últimos 8 vídeos de um canal. No atributo src
da tag script
, substitua [CHAVE-DE-API]
pela sua chave de API e [ID-DO-CANAL]
pelo ID do canal que você deseja listar os vídeos.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name='viewport' content='width=device-width, initial-scale=1.0'/> <title>Exemplo: Listando vídeos de canais do YouTube</title> <style> body, html{ margin: 0; padding: 0; } #content{ max-width: 960px; margin: 0 auto; } .video-item{ display: block; float: left; width: 50%; } .video-item a{ text-decoration: none; color: black; } .video-item a:hover{ text-decoration: underline; opacity: 0.7; } .video-item img, .video-item p, .video-item h2{ width: 100%; height: auto; } .video-item .content{ padding: 5px; } h1{ text-align: center; } h2{ font-size: 20px; } </style> </head> <body> <div id="content"> <h1>Lista de vídeos de um canal do YouTube</h1> <div id="container"></div> </div> <script type="text/javascript"> //cria uma lista com os vídeos do canal especificado function funcaoCallback(json){ var videos = json.items; //array com os vídeos var youtubeUrl = 'https://www.youtube.com/watch?v='; //padrão de URL do YouTube var output_html = ""; for(i = 0; i < videos.length; i++){ output_html += "<div class=\"video-item\">"; output_html += "<div class=\"content\">"; output_html += "<a href=\"" + youtubeUrl + videos[i].id.videoId + "\">"; output_html += "<img src=\""+ videos[i].snippet.thumbnails.medium.url+"\" width=\"" + videos[i].snippet.thumbnails.medium.width + "\" height=\"" + videos[i].snippet.thumbnails.medium.height +"\"/>"; output_html += "<h2>"; output_html += videos[i].snippet.title.substr(0, 70); output_html += "</h2>"; output_html += "<p>"; output_html += videos[i].snippet.description.substr(0, 90); output_html += "</p>"; output_html += "</a>"; output_html += "</div>"; output_html += "</div>"; } document.getElementById("container").innerHTML = output_html; } </script> <script async src="https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&channelId=[ID-DO-CANAL]&key=[CHAVE-DE-API]&maxResults=3&type=video&order=date&fields=items(id(videoId)%2Csnippet(title%2Cdescription%2Cthumbnails(medium)))&prettyPrint=false&callback=funcaoCallback"></script> </body> </html>
Veja o resultado (para o canal do blog):
Considerações finais
Apesar de ser um pouco complexa, a API de dados YouTube é bem completa. Com as informações desse guia, você poderia criar um gadget para divulgar os últimos vídeos de um canal num website, blog ou até mesmo num aplicativo de celular.
O único problema é que o método search
consome cerca de 100 cotas por requisição [3]. Considerando que atualmente a API de dados do YouTube fornece até 1.000.000 cotas por dia, isso significa que você teria direito a cerca de 10.000 requisições por dia, caso você utilize apenas o método search
.
Existe uma alternativa que consome menos cotas, utilizando o método PlaylistItems (list)
[2]. Com esse método, podemos reduzir o consumo para cerca de 3 cotas por requisição [3]. Fica para um próximo artigo.
Referências
- [1] Search: list. Acesso em 20 e agosto de 2018.
- [2] PlaylistItems: list. Acesso em 20 e agosto de 2018.
- [3] YouTube Data API (v3) - Quota Calculator. Acesso em 20 e agosto de 2018.
- [4] Standard Query Parameters. Acesso em 20 e agosto de 2018.
Rapaz! Que maravilha! Isso muito me interessa!
ResponderExcluirVou estudar isso aqui.
Obrigado por compartilhar.
Muito obrigado pelo artigo. Deu certo!
ResponderExcluirFico feliz por tê-lo ajudado com este artigo!
ExcluirCara ótimo artigo, pena que o order=date parou de funcionar :/ Sabe alguma solução para ordenar os últimos vídeos listado do canal ?
ResponderExcluirEstranho, eu testei aqui e funcionou
ExcluirEu não consigo fazer algo para que me retorne mais de 50 videos?
ResponderExcluirSe a sua consulta tiver mais de 50 resultados, ela vai ser paginada (50 resultados por página). Na primeira requisição você vai receber 50 resultados, daí os 50 resultados seguintes você obtém fazendo uma nova requisição utilizando o campo "pageToken" e inserindo o ID "nextPage" da requisição anterior.
ExcluirEsse ID da "nextPage" de uma página fica no cabeçalho da requisição da página anterior. Se você usar o parâmetro "fields" para comprimir os dados retornados, vai ter que incluir "nextPage" nesse parâmetro.
Mais informações aqui: Search: list (Ajuda do YouTube API)
o meu fica pagina em branco o que pode ser
ResponderExcluirQual foi o erro apresentado no console do seu navegador?
ExcluirSerá que tem um jeito desses videos serem reproduzidos no proprio site?
ResponderExcluirSim, você pode usar o recurso de incorporação de vídeos do YouTube. Esse código que eu apresentei não carrega o vídeo na página, ele abre a página do YouTube onde está o vídeo.
ExcluirO YouTube tem um guia em português sobre como incorporar um vídeo na página (clique aqui para acessar).
Basicamente, você cria um iframe e no atributo src você coloca http://www.youtube.com/embed/ID_DO_VÍDEO.
Se o seu layout for responsivo, vai ter que pesquisar o código CSS para deixar o player responsivo.
gostei do artigo, mas infelizmente o consumo de cota que é 10.000 acaba muito rapido, só nos testes que eu estava realizando zerei as cotas da minha API Key, então descobri uma outra forma de puxar os videos de qualquer canal e com suporte a player sem a necessidade do uso da API, usando ajax e css apenas.
ResponderExcluiré um script muito simples.
Assim que possivel coloco ele aqui pra compartilhar
De fato, esse limite é problemático (a API do Blogger é mais generosa).
ExcluirTambém dá para puxar os vídeos através do feed RSS (XML) do canal, daí você não precisa de cotas e nada. O feed do canal do blog, por exemplo, é https://www.youtube.com/feeds/videos.xml?channel_id=UCRD_6Vp8VEuU_IoZHBUrkiw.
A URL genérica é https://www.youtube.com/feeds/videos.xml?channel_id=[ID-DO-CANAL]. Porém, esse método retorna apenas os últimos vídeos.
Outra forma é usar a API com algum cache intermediário. Você salva a resposta da requisição num arquivo no servidor e estabelece um prazo de validade, daí sempre que alguém faz a requisição, você retorna o cache.
Agradeço por compartilhar sua experiência!
Tentei fazer isso aí, só que me veio essa mensagem:
ResponderExcluir{
"error": {
"code": 403,
"message": "Requests from referer are blocked.",
"errors": [
{
"message": "Requests from referer are blocked.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
O que se passa aí?
Olá, parece alguma restrição da Chave de API. Entra no console do Google e tenta alterar a configuração da sua chave dando mais permissões.
Excluir