Solucionado (ver solução)
Solucionado
(ver solução)
13
respostas

API do youtube como utilizar?

Eu preciso criar uma página que lista vídeos do Youtube, mas nunca utilizei a API, preciso fazer alguma configuração no site do google para utilizar?

Eu olhei o site, mas fiquei na dúvida sobre como utilizar a API, devo utilizar o OAuth e como utilizar.

13 respostas

Gisele, no prório site do Youtube eles disponibilizam toda a documentação de recursos da API.

Veja só: https://www.youtube.com/yt/dev/pt-BR/api-resources.html

Oi Gisele

o CodeAcademy tem um curso sobre isso

https://www.codecademy.com/pt-BR/tracks/youtube

eu ja apanhei muito com essa api. Se você precisar de dados dos usuários você vai precisar configurar algumas permissões sim.

Oi Thiago, achei a documentação, mas meu tempo tá um pouco apertado e eu não estava entendendo algumas coisas, porque nunca utilizei essa api. E a minha dificuldade é mais em saber como criar o código para visualizar.

Oi Jefferson, obrigada.

Na documentação encontrei amostras:

Developers Google

Não sei se eu estou certa, mas se eu utilizar esse código eu já consigo listar os vídeos na página?

Encontrei essa outra resposta: Stackoverflow - AngularJS

Mas ficaram muitas dúvidas sobre várias coisas do angular que foram utilizadas:

function init() {
    window.initGapi(); // Calls the init function defined on the window
}
$sce
$window.initGapi
'$q'
 var deferred = $q.defer();

 request.execute(function(response) {
                deferred.resolve(response.result);

São várias partes do angular que são utilizadas e eu não sei porque e são utilizadas no código.

É nessa parte que eu vou puxar a lista de vídeos?

$scope.getChannel = function () {
            googleService.googleApiClientReady().then(function (data) {
                $scope.channel = data;
            },

Entendi errado essa parte da documentação, esse tipo eu nunca entendo, algumas documentações eu consigo me virar pra entender.

Essas amostras não são o que eu preciso e na maioria dos outros exemplos é PHP, Java e Python.

Se eu não estive com um prazo apertado ia tentar só a documentação, mas não achei o que eu quero e eu só quero listar vídeos, depois se precisar de mais coisas eu pesquiso mais.

Encontrei outro tutorial, só que eu não consigo visualizar os videos, não sei se é porque não está no servidor:

var channelIds = 'GoogleDevelopers';
var vidWidth = 500;
var vidHeight = 400;
var vidResults = 10;

$(document).ready(function() {
  $.get(
    "https://www.googleapis.com/youtube/v3/channels", {
      part: 'contentDetails',
      channelId: channelIds,
      key: 'dddddd' },
      function(data) {
        $.each(data.items, function(i, item){
            console.log(data.items);
            pid = item.contentDetails.relatedPlaylists.uploads;
            getVids(pid);
        })
      }
  );
  function getVids(pid) {
    $.get(
      "https://www.googleapis.com/youtube/v3/playlistItems", {
        part: 'snippet',
        maxResults: vidResults,
        playlistId: pid,
        key: 'dddddddd'},
        function(data) {
          var output;
          $.each(data.items, function(i, item) {
            console.log(item);
            videTitle = item.snippet.title;
            videoId = item.snippet.resourceId.videoId;

            output = '<li><iframe height="'+vidHeight+'" width="'+vidWidth+'" src=\"//www.youtube.com/embed/'+videoId+'\"></iframe></li>';

            //Append to results listStyleType
            $('#results').append(output);
          })
        }
      )
    }
  })

Eu achei a documentação complicada, porque eu vi o tutorial da codeacademy que mostra como chamar a API e não encontrei nada parecido na documentação, testei um dos exemplos da documentação no codepen e recebo essa mensagem de erro:

"Error: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project."

Exemplo online:

http://codepen.io/Gisesonia/pen/JWmdBq?editors=1111

Significa que independente de eu querer somente listar os vídeos, eu preciso dessa autenticação? Se eu colocar isso é necessário passar alguma chave para quem for utilizar a página ou é só colocar no código (não sei onde) e funciona?

Testei a solução da codeacademy também, mas recebo esse erro:

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('file://') does not match the recipient window's origin ('null'). (anonymous) @ cb=gapi.loaded_0:73

Código do codeacademy (mudei para minha chave para ver se era esse o problema):

<html>
    <head>
        <script src="script.js" type="text/javascript"></script>
        <script src="https://apis.google.com/js/client.js?onload=onClientLoad" type="text/javascript"></script>
    </head>
    <body>
        <pre id="response"></pre>
    </body>
</html>
// Your use of the YouTube API must comply with the Terms of Service:
// https://developers.google.com/youtube/terms

// Helper function to display JavaScript value on HTML page.
function showResponse(response) {
    var responseString = JSON.stringify(response, '', 2);
    document.getElementById('response').innerHTML += responseString;
}

// Called automatically when JavaScript client library is loaded.
function onClientLoad() {
    gapi.client.load('youtube', 'v3', onYouTubeApiLoad);
}

// Called automatically when YouTube API interface is loaded (see line 9).
function onYouTubeApiLoad() {
    // This API key is intended for use only in this lesson.
    // See https://goo.gl/PdPA1 to get a key for your own applications.
    gapi.client.setApiKey('AIzaSyD_tmni9vPZfR-M7JVq41cEkN4h1A4qK1s');

    search();
}

function search() {
    // Use the JavaScript client library to create a search.list() API call.
    var request = gapi.client.youtube.search.list({
        part: 'snippet',

    });

Testei no codePen e funcionou, mesmo assim achei dificil de encontrar as informações na documentação, tive que pesquisa em vários lugares. Tem pedaços de código, deveria ter um completo, de como carrega a API e de como selecionar os itens.

Por exemplo eu vi que tem formas diferentes de listar resultados, mas eu tenho que saber o que eu quero listar, se for canal tem as opções, se for playlist tem outros itens para configurar e listar.

A parte da autenticação eu não consegui entender como e quando utilizar. Como eu pego link de um video e abro em outra página ou modal.

No codeAcademy ele mostra como usar uma busca, mas não consegui fazer funcionar fora da plataforma, li os comentários e consegui entender, mas não consegui retornar nenhum resultado.

"Por exemplo eu vi que tem formas diferentes de listar resultados, mas eu tenho que saber o que eu quero listar, se for canal tem as opções, se for playlist tem outros itens para configurar e listar."

Se não for um canal ou uma playlist, o que exatamente você quer listar?

Eu quero listar videos de um canal, não entendi muito bem o que seria a playlist.

Só que eu queria colocar um botão de carregar mais, que eu vi na documentação, mas não sei como colocaria nesse código que está listando os canais. Não sei se tem esse pageToken da forma que eu estou listando.

Listaria 6 vídeos na lateral e teria um botão para listar mais:

https://developers.google.com/youtube/v3/code_samples/javascript
// Define some variables used to remember state.
var playlistId, nextPageToken, prevPageToken;

// After the API loads, call a function to get the uploads playlist ID.
function handleAPILoaded() {
  requestUserUploadsPlaylistId();
}

// Call the Data API to retrieve the playlist ID that uniquely identifies the
// list of videos uploaded to the currently authenticated user's channel.
function requestUserUploadsPlaylistId() {
  // See https://developers.google.com/youtube/v3/docs/channels/list
  var request = gapi.client.youtube.channels.list({
    mine: true,
    part: 'contentDetails'
  });
  request.execute(function(response) {
    playlistId = response.result.items[0].contentDetails.relatedPlaylists.uploads;
    requestVideoPlaylist(playlistId);
  });
}

// Retrieve the list of videos in the specified playlist.
function requestVideoPlaylist(playlistId, pageToken) {
  $('#video-container').html('');
  var requestOptions = {
    playlistId: playlistId,
    part: 'snippet',
    maxResults: 10
  };
  if (pageToken) {
    requestOptions.pageToken = pageToken;
  }
  var request = gapi.client.youtube.playlistItems.list(requestOptions);
  request.execute(function(response) {
    // Only show pagination buttons if there is a pagination token for the
    // next or previous page of results.
    nextPageToken = response.result.nextPageToken;
    var nextVis = nextPageToken ? 'visible' : 'hidden';
    $('#next-button').css('visibility', nextVis);
    prevPageToken = response.result.prevPageToken
    var prevVis = prevPageToken ? 'visible' : 'hidden';
    $('#prev-button').css('visibility', prevVis);

    var playlistItems = response.result.items;
    if (playlistItems) {
      $.each(playlistItems, function(index, item) {
        displayResult(item.snippet);
      });
    } else {
      $('#video-container').html('Sorry you have no uploaded videos');
    }
  });
}

// Create a listing for a video.
function displayResult(videoSnippet) {
  var title = videoSnippet.title;
  var videoId = videoSnippet.resourceId.videoId;
  $('#video-container').append('<p>' + title + ' - ' + videoId + '</p>');
}

// Retrieve the next page of videos in the playlist.
function nextPage() {
  requestVideoPlaylist(playlistId, nextPageToken);
}

// Retrieve the previous page of videos in the playlist.
function previousPage() {
  requestVideoPlaylist(playlistId, prevPageToken);
}

O problema é que eu não entendi de onde vem esse pageToken, segundo a documentação deveria aparecer antes do pageInfo.

Porque da forma que eu estou listando não aparece essa opção e eu não sei porque:

Object {
  etag: "'uQc-MPTsstrHkQcRXL3IWLmeNsM/GKJPv4cWJfPPQC4dml2Be0nsLNs'",
  items: [Object {
  contentDetails: Object {
    relatedPlaylists: Object {}
  },
  etag: "'uQc-MPTsstrHkQcRXL3IWLmeNsM/OWPMdSRlXQKVMpuGJHLcZMfaauk'",
  id: "UC_x5XG1OV2P6uZZ5FSM9Ttw",
  kind: "youtube#channel"
}],
  kind: "youtube#channelListResponse",
  pageInfo: Object {
    resultsPerPage: 5,
    totalResults: 1
  }
}

Para usar a API do Youtube, você precisa criar uma chave de API. Aqui tem um vídeo que mostra como criar.

<div class='embed-container'><iframe frameborder="0" allowfullscreen src="https://www.youtube.com/embed/HEGe_V9K-6o"></iframe></div>

Usando a chave da API em cada requisição, você consegue pesquisar.

Por exemplo, para ver os dados desde usuário:

https://www.youtube.com/user/davepeo77

Você deve fazer a seguinte requisição: (Pode testar direto no navegador, substituindo SUA_CHAVE_API pela sua chave de API criada no Console do Desenvolvedor do Google)

https://www.googleapis.com/youtube/v3/channels?part=statistics&forUsername=davepeo77&key=SUA_CHAVE_API

No retorno, você vai precisar do ID deste usuário. No caso do exemplo acima, o ID é UCpMKOMYkxD0SnVhC5qsbfMw

Você pode pesquisar até 50 vídeos por requisição. Para puxar os dados de um vídeo, primeiro você vai ter que pegar os IDs. Um exemplo usando o mesmo usuário:

https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCpMKOMYkxD0SnVhC5qsbfMw&maxResults=50&order=date&type=video&key=SUA_CHAVE_API

Para puxar as demais páginas de resultados, tem que ser uma por uma. O token da página seguinte aparece no começo dos resultados, no exemplo é CDIQAA. Para retornar esta página, basta fazer:

https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCpMKOMYkxD0SnVhC5qsbfMw&maxResults=50&order=date&type=video&pageToken=CDIQAA&key=SUA_CHAVE_API

Nos resultados, eu vou ter um "videoId" para cada resultado. Eu escolhi um vídeo desta segunda página com "id" 9F4EE_r46Wo. Para puxar os dados deste vídeo a consulta seria esta:


https://www.googleapis.com/youtube/v3/videos?part=statistics,player&id=9F4EE_r46Wo&key=SUA_CHAVE_API

Além das estatísticas, eu tenho o "embedHTML" com o link do vídeo, que pode ser aberto direto no navegador.

Obrigada, pena que eu demorei pra ver sua resposta, eu fui achando uns tutoriais e montando o quebra cabeça.

O que me confundiu é que tem duas formas de pegar os dados uma é a que está na documentação que é preciso ler as documentações das APIS clientes e a outra é a forma que eu estava acostumada usando o $.get do Jquery. Outra coisa também era entender como acessar os dados, os itens são diferentes para canal, playlist e video.

Documentação:

 var request = gapi.client.youtube.channels.list({// isso que eu estava tendo entender de onde vinha
    mine: true,
    part: 'contentDetails'
  });
  request.execute(function(response) {// tbm não sabia de onde tinha saído, mas pelo que entendi é uma função da api
    playlistId = response.result.items[0].contentDetails.relatedPlaylists.uploads;
    requestVideoPlaylist(playlistId);
  });

Jquery:

$.get("https://www.googleapis.com/youtube/v3/search", {//aqui o equivalente só que aqui é uma busca diferente de buscar direto no canal, tem opções de parâmetro
       part: 'snippet, id',
       q: q,
       playlistId: playlistId,
       maxResults: 50,
       type: 'playlist',
       key: 'KEY API'
    },
  function (data) {
      console.log(data);
      var nextPageToken = data.nextPageToken;
      var prevPageToken = data.prevPageToken;

Eu consegui consultar a API com Jquery, tá bem simples, mas tem algum problema quando clica em next, parece que tá repetindo os resultados.

Coloquei no codepen que assim dá pra visualizar:

Link do codepen

Eu também estou tentando adaptar para AngularJS, qual seria o substituto do append do Jquery para o AngularJS?

É dificil fazer um carregando no AngularJS? No Jquery eu utilizava o beforeSend.

solução!

O next não funcionou porque na hora de puxar os dados, você atribuiu o valor do token a uma variável local, ao invés da variável global definida no começo do código.

Mesmo que o valor tivesse sido atribuído, não ia funcionar porque nos parâmetros da requisição não está sendo enviado um parâmetro chamado pageToken.

Fiz os seguintes ajustes e funcionou:

<body>
  <form id="search-form">
    <input type="text" id="query">
    <button type="submit">Busca</button>
  </form>
    <div id="results"></div>
  <div id="video-container"></div>
  <button id="prev-button" class="paging-button" onclick="previousPage();">Previous Page</button>
      <button id="next-button" class="paging-button" onclick="nextPage();">Next Page</button> 
</body>
<script  src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script type="text/javascript">
 var searchField = $("#query"); 
  var q = $("#query").val();
  var playlistId, nextPageToken, prevPageToken;
   $("#search-form").submit(function (e) {
       e.preventDefault();
     //console.log("teste");
       $("#results").html("");
     requestVideoPlaylist(playlistId, prevPageToken)

   });

function nextPage() {

    requestVideoPlaylist(playlistId, nextPageToken);
   }

  // Retrieve the previous page of videos in the playlist.
  function previousPage() {
      requestVideoPlaylist(playlistId, prevPageToken);
   }


function requestVideoPlaylist(playlistId, pageToken) {
    var options = {
       part: 'snippet, id',
       q: q,
       playlistId: playlistId,
       maxResults: 50,
       type: 'playlist',
       key: SUA_CHAVE_API
    };

    if (pageToken !== null){
        options.pageToken = pageToken;
    }
    console.log(options)
    $.get("https://www.googleapis.com/youtube/v3/search",options,
  function (data) {
     // console.log(data);
      nextPageToken = data.nextPageToken;
      prevPageToken = data.prevPageToken;
      //console.log(data.items);  

     nextPageToken = data.nextPageToken;
     var nextVis = nextPageToken ? 'visible' : 'hidden';
     $('#next-button').css('visibility', nextVis);
     prevPageToken = data.prevPageToken
     var prevVis = prevPageToken ? 'visible' : 'hidden';
     $('#prev-button').css('visibility', prevVis);

    var playlistItems = data.items;
    if (playlistItems) {
      $.each(playlistItems, function(index, item) {
        displayResult(item);
      });
      } else {
      $('#video-container').html('Sorry you have no uploaded videos');
      } 

    });
    // Create a listing for a video.
    function displayResult(videoSnippet) {
    // console.log(videoSnippet);
     var title = videoSnippet.snippet.title;
     var videoId = videoSnippet.id.playlistId;
     var url = "";
     if (typeof videoSnippet.snippet.thumbnails !== 'undefined') {
        url = videoSnippet.snippet.thumbnails.medium.url;
     }

     $('#video-container').append('<p>' + title + ' - ' + videoId + '</p>'+'<img src=\"'+url+'\">');
   }
 }

</script>

Para fazer algo semelhante ao append você pode tentar o seguinte.

http://blog.sodhanalibrary.com/2014/08/append-or-prepend-html-to-div-using.html#.WOAHhkhtnox

Quanto ao berofeSend, ele não existe, mas você pode criar esta funcionalidade usando interceptadores. Tem um tutorial aqui:

http://benznext.com/angular-js-equivalent-jquerys-ajax-beforesend-using-interceptors/

Muito obrigada. Foi só por causa disso:

 if (pageToken !== null){
        options.pageToken = pageToken;
    }

Você falou que não é atribuido a variável global, é porque vinha de :

      nextPageToken = data.nextPageToken;
      prevPageToken = data.prevPageToken;

?