1

Je suis en train de télécharger des sous-titres pour cette vidéo publique youtube (juste pour le test) https://www.youtube.com/watch?v=Txvud7wPbv4ne peut pas télécharger les sous-titres vidéo en utilisant l'API youtube v3 en python

J'utilise l'échantillon de code (captions.py) en dessous Je suis de ce lien https://developers.google.com/youtube/v3/docs/captions/download

Je l'ai déjà stocké le client-secrets.json (oauth2 d'authentification) et youtube-v3-api-captions.json dans le même répertoire (demandé dans l'exemple de code)

I mettre cette ligne de code en cmd: python captions.py --videoid = 'Txvud7wPbv4' --action = 'télécharger'

Je reçois cette erreur: enter image description here Je ne sais pas pourquoi il ne reconnaît pas l'ID vidéo de cette vidéo publique.

Quelqu'un a-t-il eu un problème similaire?

Merci d'avance.

Exemple de code

:

# Usage example: 
# python captions.py --videoid='<video_id>' --name='<name>' --file='<file>' --language='<language>' --action='action' 

import httplib2 
import os 
import sys 

from apiclient.discovery import build_from_document 
from apiclient.errors import HttpError 
from oauth2client.client import flow_from_clientsecrets 
from oauth2client.file import Storage 
from oauth2client.tools import argparser, run_flow 


# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains 

# the OAuth 2.0 information for this application, including its client_id and 
# client_secret. You can acquire an OAuth 2.0 client ID and client secret from 
# the {{ Google Cloud Console }} at 
# {{ https://cloud.google.com/console }}. 
# Please ensure that you have enabled the YouTube Data API for your project. 
# For more information about using OAuth2 to access the YouTube Data API, see: 
# https://developers.google.com/youtube/v3/guides/authentication 
# For more information about the client_secrets.json file format, see: 
# https://developers.google.com/api-client-library/python/guide/aaa_client_secrets 
CLIENT_SECRETS_FILE = "client_secrets.json" 

# This OAuth 2.0 access scope allows for full read/write access to the 
# authenticated user's account and requires requests to use an SSL connection. 
YOUTUBE_READ_WRITE_SSL_SCOPE = "https://www.googleapis.com/auth/youtube.force-ssl" 
YOUTUBE_API_SERVICE_NAME = "youtube" 
YOUTUBE_API_VERSION = "v3" 

# This variable defines a message to display if the CLIENT_SECRETS_FILE is 
# missing. 
MISSING_CLIENT_SECRETS_MESSAGE = """ 
WARNING: Please configure OAuth 2.0 

To make this sample run you will need to populate the client_secrets.json file 
found at: 
    %s 
with information from the APIs Console 
https://console.developers.google.com 

For more information about the client_secrets.json file format, please visit: 
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets 
""" % os.path.abspath(os.path.join(os.path.dirname(__file__), 
            CLIENT_SECRETS_FILE)) 

# Authorize the request and store authorization credentials. 
def get_authenticated_service(args): 
    flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SSL_SCOPE, 
    message=MISSING_CLIENT_SECRETS_MESSAGE) 

    storage = Storage("%s-oauth2.json" % sys.argv[0]) 
    credentials = storage.get() 

    if credentials is None or credentials.invalid: 
    credentials = run_flow(flow, storage, args) 

    # Trusted testers can download this discovery document from the developers page 
    # and it should be in the same directory with the code. 
    with open("youtube-v3-api-captions.json", "r") as f: 
    doc = f.read() 
    return build_from_document(doc, http=credentials.authorize(httplib2.Http())) 


# Call the API's captions.list method to list the existing caption tracks. 
def list_captions(youtube, video_id): 
    results = youtube.captions().list(
    part="snippet", 
    videoId=video_id 
).execute() 

    for item in results["items"]: 
    id = item["id"] 
    name = item["snippet"]["name"] 
    language = item["snippet"]["language"] 
    print "Caption track '%s(%s)' in '%s' language." % (name, id, language) 

    return results["items"] 


# Call the API's captions.insert method to upload a caption track in draft status. 
def upload_caption(youtube, video_id, language, name, file): 
    insert_result = youtube.captions().insert(
    part="snippet", 
    body=dict(
     snippet=dict(
     videoId=video_id, 
     language=language, 
     name=name, 
     isDraft=True 
    ) 
    ), 
    media_body=file 
).execute() 

    id = insert_result["id"] 
    name = insert_result["snippet"]["name"] 
    language = insert_result["snippet"]["language"] 
    status = insert_result["snippet"]["status"] 
    print "Uploaded caption track '%s(%s) in '%s' language, '%s' status." % (name, 
     id, language, status) 


# Call the API's captions.update method to update an existing caption track's draft status 
# and publish it. If a new binary file is present, update the track with the file as well. 
def update_caption(youtube, caption_id, file): 
    update_result = youtube.captions().update(
    part="snippet", 
    body=dict(
     id=caption_id, 
     snippet=dict(
     isDraft=False 
    ) 
    ), 
    media_body=file 
).execute() 

    name = update_result["snippet"]["name"] 
    isDraft = update_result["snippet"]["isDraft"] 
    print "Updated caption track '%s' draft status to be: '%s'" % (name, isDraft) 
    if file: 
    print "and updated the track with the new uploaded file." 


# Call the API's captions.download method to download an existing caption track. 
def download_caption(youtube, caption_id, tfmt): 
    subtitle = youtube.captions().download(
    id=caption_id, 
    tfmt=tfmt 
).execute() 

    print "First line of caption track: %s" % (subtitle) 

# Call the API's captions.delete method to delete an existing caption track. 
def delete_caption(youtube, caption_id): 
    youtube.captions().delete(
    id=caption_id 
).execute() 

    print "caption track '%s' deleted succesfully" % (caption_id) 


if __name__ == "__main__": 
    # The "videoid" option specifies the YouTube video ID that uniquely 
    # identifies the video for which the caption track will be uploaded. 
    argparser.add_argument("--videoid", 
    help="Required; ID for video for which the caption track will be uploaded.") 
    # The "name" option specifies the name of the caption trackto be used. 
    argparser.add_argument("--name", help="Caption track name", default="YouTube for Developers") 
    # The "file" option specifies the binary file to be uploaded as a caption track. 
    argparser.add_argument("--file", help="Captions track file to upload") 
    # The "language" option specifies the language of the caption track to be uploaded. 
    argparser.add_argument("--language", help="Caption track language", default="en") 
    # The "captionid" option specifies the ID of the caption track to be processed. 
    argparser.add_argument("--captionid", help="Required; ID of the caption track to be processed") 
    # The "action" option specifies the action to be processed. 
    argparser.add_argument("--action", help="Action", default="all") 


    args = argparser.parse_args() 

    if (args.action in ('upload', 'list', 'all')): 
    if not args.videoid: 
      exit("Please specify videoid using the --videoid= parameter.") 

    if (args.action in ('update', 'download', 'delete')): 
    if not args.captionid: 
      exit("Please specify captionid using the --captionid= parameter.") 

    if (args.action in ('upload', 'all')): 
    if not args.file: 
     exit("Please specify a caption track file using the --file= parameter.") 
    if not os.path.exists(args.file): 
     exit("Please specify a valid file using the --file= parameter.") 

    youtube = get_authenticated_service(args) 
    try: 
    if args.action == 'upload': 
     upload_caption(youtube, args.videoid, args.language, args.name, args.file) 
    elif args.action == 'list': 
     list_captions(youtube, args.videoid) 
    elif args.action == 'update': 
     update_caption(youtube, args.captionid, args.file); 
    elif args.action == 'download': 
     download_caption(youtube, args.captionid, 'srt') 
    elif args.action == 'delete': 
     delete_caption(youtube, args.captionid); 
    else: 
     # All the available methods are used in sequence just for the sake of an example. 
     upload_caption(youtube, args.videoid, args.language, args.name, args.file) 
     captions = list_captions(youtube, args.videoid) 

     if captions: 
     first_caption_id = captions[0]['id']; 
     update_caption(youtube, first_caption_id, None); 
     download_caption(youtube, first_caption_id, 'srt') 
     delete_caption(youtube, first_caption_id); 
    except HttpError, e: 
    print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) 
    else: 
    print "Created and managed caption tracks." 
+0

et vous êtes sûr que vous avez authentifié avec l'utilisateur et cannel que la vidéo est activée? – DaImTo

+0

La vidéo est accessible et j'ai déjà créé mon identifiant client Oauth. Je suis désolé je suis nouveau à l'aide de l'api youtube. – snat2100

Répondre

2

Votre application semble trop complexe ... il est structuré pour être en mesure de faire tout qui peut être fait avec/sous-titres, non seulement télécharger. Cela le rend plus difficile à déboguer, j'ai donc écrit un abrégé (Python 2 ou 3) La version qui télécharge juste légendes:

# Usage example: $ python captions-download.py Txvud7wPbv4 

from __future__ import print_function 

from apiclient import discovery 
from httplib2 import Http 
from oauth2client import file, client, tools 

SCOPES = 'https://www.googleapis.com/auth/youtube.force-ssl' 
store = file.Storage('storage.json') 
creds = store.get() 
if not creds or creds.invalid: 
    flow = client.flow_from_clientsecrets('client_secret.json', SCOPES) 
    creds = tools.run_flow(flow, store) 
YOUTUBE = discovery.build('youtube', 'v3', http=creds.authorize(Http())) 

def process(vid): 
    caption_info = YOUTUBE.captions().list(
      part='id', videoId=vid).execute().get('items', []) 
    caption_str = YOUTUBE.captions().download(
      id=caption_info[0]['id'], tfmt='srt').execute() 
    caption_data = caption_str.split('\n\n') 
    for line in caption_data: 
     if line.count('\n') > 1: 
      i, cap_time, caption = line.split('\n', 2) 
      print('%02d) [%s] %s' % (
        int(i), cap_time, ' '.join(caption.split()))) 

if __name__ == '__main__': 
    import sys 
    if len(sys.argv) == 2: 
     VID = sys.argv[1] 
    process(VID) 

Le fonctionnement est le suivant:

  1. Vous passez l'ID vidéo (VID) comme le seul argument (sys.argv[1])
  2. Il utilise cette VID pour rechercher les ID de légende avec YOUTUBE.captions().list()
  3. en supposant que la vidéo a (au moins) une piste de sous-titres, je prends son numéro d'identification (caption_info[0]['id'])
  4. Ensuite, il appelle YOUTUBE.captions().download() avec cet ID de légende demandant la srttrack format
  5. Tous les sous-titres individuels sont délimités par des doubles sauts de ligne, donc divisés sur « em
  6. boucle dans chaque sous-titre; il y a des données s'il y a au moins 2 sauts de ligne dans la ligne, de sorte que split() sur la 1ère paire
  7. Afficher la légende #, chronologie de quand il apparaît, alors la légende elle-même, en changeant tous les sauts de ligne restants aux espaces

Quand je cours, j'obtenir le résultat attendu ... ici sur une vidéo que je possède:

$ python captions-download.py MY_VIDEO_ID 
01) [00:00:06,390 --> 00:00:09,280] iterator cool but that's cool 
02) [00:00:09,280 --> 00:00:12,280] your the moment 
03) [00:00:13,380 --> 00:00:16,380] and sellers very thrilled 
    : 

Couple de choses ...

  1. Je pense que vous devez être le propriétaire de la vidéo pour laquelle vous essayez de télécharger les légendes.
    • J'ai essayé mon script sur votre vidéo, et je reçois une erreur interdite 403 HTTP
    • Voici other errors vous pouvez obtenir de l'API
  2. Dans votre cas, il semble que quelque chose est chambouler l'ID vidéo vous passant.
    • il pense que vous le donnez <code> et </code> (notez le 0x3c hexagonal & valeurs 0x3E) ... texte riche?
    • Quoi qu'il en soit, c'est pourquoi j'ai écrit ma propre version, plus courte ... donc j'ai un environnement plus contrôlé pour expérimenter.

FWIW, puisque vous êtes nouveau à l'aide des API Google, je l'ai fait quelques vidéos d'introduction que j'ai fait pour obtenir les développeurs sur-montés à bord avec l'aide des API Google this playlist. Le code d'autorisation est le plus difficile, alors concentrez-vous sur les vidéos 3 et 4 de cette liste de lecture pour vous aider à vous acclimater.

Je n'ai pas vraiment de vidéos qui couvrent les API YouTube (car je me concentre davantage sur les API G Suite) même si j'ai l'exemple Google Apps Script (vidéo 22 dans la playlist); Si vous débutez avec Google Apps Script, vous devez d'abord passer en revue votre JavaScript, puis regarder la vidéo 5 en premier. J'espère que cela t'aides!