How to Youtube transcript with api (captions.download

笑着哭i 提交于 2020-01-23 02:49:36

问题


I have built a javascript code to be able to read any Youtube video transcript (gapi.client.youtube.captions.download). The auth 2.0 works fine, I run my app in a local web server everything is fine, the problem is that when I run the request I have the error 403: cb=gapi.loaded_0:164 GET https://content.googleapis.com/youtube/v3/captions/My_API_Key 403 I have not found any solution here in StackOverflow.. any idea ?

Here is my js file:

const CLIENT_ID = 'My_Client_ID';
const DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest"];
const SCOPES = 'https://www.googleapis.com/auth/youtube.readonly';

const authorizeButton = document.getElementById('enter-button');
const signoutButton = document.getElementById('exit-button');
const content = document.getElementById('content');

// default youtube channel
const defaultChannel = 'googledevelopers';

// Load auth2 library
function handleClientLoad(){
    gapi.load('client:auth2', initClient);
}

// Init API client library and set up sing in listeners
function initClient(){
    gapi.client.init({
        discoveryDocs: DISCOVERY_DOCS,
        clientId: CLIENT_ID,
        scope: SCOPES
    }).then(() => {
        // Listen for sing state changes
        gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
        // Handle initial sign in state
        updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
        authorizeButton.onclick = handleAuthClick;
        signoutButton.onclick = handleSignouClick;
    });
}

// update UI sign in state changes
function updateSigninStatus(isSignedIn){
    if(isSignedIn){
        authorizeButton.style.display = 'none';
        signoutButton.style.display = 'block';
        content.style.display = 'block';
        getChannel(defaultChannel);
    }else{
        authorizeButton.style.display = 'block';
        signoutButton.style.display = 'none';
        content.style.display = 'none';
    }
}

// Handle Login
function handleAuthClick(){
    gapi.auth2.getAuthInstance().signIn();
}

// Handle Logout
function handleSignouClick(){
    gapi.auth2.getAuthInstance().signOut();
}

// Display channel Data
function showChannelData(data){
    const channelData = document.getElementById('channel-data');
    channelData.innerHTML = data;
}

// Get channel from API
function getChannel(channel){
    gapi.client.youtube.captions.download({
        id: 'guMGyC1tUYAdL3hgBlcGnW4Rt_bBUbtp'
    })
    .then(response => {
        console.log(response);
        const channel = response.result.items[0];
    })
    .catch(err => alert('No Channel By THat Name'));
}

And here is my index.ejs file:

<!DOCTYPE html>
<html lang="en">
    <head>      
        <title>Your awesome Youtube search engine</title>
        <meta charset="UTF-8" />                    
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Awesome videos!" />
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    </head>
    <body>
        <header>
            <h1 class="w100 text-center"><a href="index.html">YouTube Viral Search</a></h1>
        </header>

<div class="container">
        <p>Login with Google</p>
        <button class="btn green" id="enter-button">Log In</button>
        <button class="btn green" id="exit-button">Log Out</button>
        <br />
        <div id="content">
            <div class="row">
                <div id="channel-data" class="col s12"></div>
            </div>
        </div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.min.js"></script>
<script src="/javascripts/appYT.js"></script>
    <script async defer src="https://apis.google.com/js/api.js"
      onload="this.onload=function(){};handleClientLoad()"
      onreadystatechange="if (this.readyState === 'complete') this.onload()">
    </script>
    </body>
</html>
enter code here

回答1:


You can use the following code for get the transcript in a given video.

This is the working jsfiddle


N.B here I have the videoId zenMEj0cAC4, but you can change it as you desire.

$.ajax({
  type: "GET",
  url: "https://video.google.com/timedtext?type=track&v=zenMEj0cAC4&id=0&lang=en",
  crossDomain: true,
}).done(function(data) {
  console.log(data);
  getCaption(data);
});


var parser, xmlDoc;
var HTML_captions = "";

// Parse the AJAX response and get the captions.
function getCaption(ajax_response) {
  try {

    parser = new DOMParser();
    xmlDoc = parser.parseFromString(ajax_response, "text/xml");
    //console.log(ajax_response);
    //console.log(xmlDoc.getElementsByTagName("transcript").length);

    if (xmlDoc.getElementsByTagName("transcript").length > 0) {
      // Loop the results of the xmlDoc:
      for (var i = 0; i < xmlDoc.getElementsByTagName("transcript")[0].childNodes.length; i++) {
        console.log(xmlDoc.getElementsByTagName("transcript")[0].childNodes[i].innerHTML);
        HTML_captions += xmlDoc.getElementsByTagName("transcript")[0].childNodes[i].innerHTML + "<br/>";
      }
    } else {
      // Loop the results of the ajax_response;
      for (var i = 0; i < ajax_response.getElementsByTagName("transcript")[0].childNodes.length; i++) {
        console.log(ajax_response.getElementsByTagName("transcript")[0].childNodes[i].innerHTML);
        HTML_captions += ajax_response.getElementsByTagName("transcript")[0].childNodes[i].innerHTML + "<br/>";
      }
    }

    document.getElementById("demo").innerHTML = "<i>Preparing captions...</i>";
    setTimeout(fillData(), 2000);

  } catch (err) {
    console.log(err);
    document.getElementById("demo").innerHTML = ('Error at getCaption function - see console form more details.');
    alert('Error at getCaption function - see console form more details.');
  }
}


// Fill the data "captions" in a HTML "div" control.
function fillData() {
  try {
    document.getElementById("demo").innerHTML = HTML_captions;
  } catch (err) {
    console.log(err);
    document.getElementById("demo").innerHTML = ('Error at fillData function - see console form more details.');
    alert('Error at fillData function - see console form more details.');
  }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<div id="demo"><i>Loading captions...</i></div>

Just in case you need more information about how you can get automatic closed captions, you can refer to these answers in Stack Overflow:

  • Get closed caption “cc” for Youtube video
  • Extract automatic captions from YouTube video


来源:https://stackoverflow.com/questions/56843796/how-to-youtube-transcript-with-api-captions-download

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!