1

Ich versuche, die Untertitelung für diese öffentliche YouTube-Video zum Download (nur zum Testen) https://www.youtube.com/watch?v=Txvud7wPbv4Video kann nicht Bildunterschriften mit youtube API v3 in Python

Ich bin mit dem Codebeispiel (captions.py) unter dem Download ich habe von diesem Link https://developers.google.com/youtube/v3/docs/captions/download

ich bereits die Client-secrets.json (oauth2 Authentifizierung) und youtube-v3-api-captions.json im gleichen Verzeichnis gespeichert habe (in dem Beispielcode gefragt)

I setze diese Codezeile in cmd: python captions.py --videoid = 'Txvud7wPbv4' --action = 'download'

Ich bekomme diesen Fehler: enter image description here Ich weiß nicht, warum es die Video-ID dieses öffentlichen Videos nicht erkennt.

Wer hatte ein ähnliches Problem?

Vielen Dank im Voraus.

Codebeispiel:

# 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

und Sie sind sicher, dass Sie sich mit dem Benutzer und dem Kanal authentifiziert haben, auf dem das Video läuft? – DaImTo

+0

Das Video ist zugänglich und ich habe bereits meine OAuth Client ID erstellt. Es tut mir leid, dass ich neu bei der Verwendung der YouTube-API bin. – snat2100

Antwort

2

Ihre Anwendung scheint übermäßig komplex ... ist es strukturiert Lage sein alles zu tun, die w/Bildunterschriften getan werden kann, nicht nur herunterladen. Das macht es schwieriger zu debuggen, so schrieb ich einen gekürzten (Python 2 oder 3) Version, die nur Bildunterschriften Downloads:

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

Die Funktionsweise ist folgende:

  1. Sie passieren in der Video-ID (VID) als einziges Argument (sys.argv[1])
  2. Es verwendet, dass die VID caption IDs nachschlagen mit YOUTUBE.captions().list()
  3. das Video Angenommen hat (mindestens) einer Titelspur, schnappen I seine ID (caption_info[0]['id'])
  4. Dann ruft es YOUTUBE.captions().download() mit dieser Beschriftung ID der srttrack format
  5. Alle einzelnen Posten abgegrenzt sind durch doppelte Zeilenumbrüche anfordert, so aufgeteilt auf ‚em
  6. Schleife durch jede Beschriftung; es gibt Daten, wenn mindestens zwei Zeilenumbrüche in der Linie sind, so dass nur split() auf dem ersten Paar
  7. Anzeige der Titel #, Timeline, wenn es angezeigt wird, dann ist die Beschriftung selbst, alle verbleibenden Zeilenumbrüche Räume Ändern

Wenn ich es laufen lasse, erhalte ich das erwartete Ergebnis ... hier auf einem Video, das ich besitze:

$ 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 
    : 

Paar Dinge ...

  1. ich glaube, Sie müssen sein der Besitzer des Videos, für das du die Untertitel herunterladen möchtest.
    • ich mein Skript auf Ihrem Video versucht, und ich bekomme einen 403 HTTP Forbidden Fehler
    • Hier sind other errors Sie von der API ist vermasselt
  2. In Ihrem Fall sieht es so etwas bekommen kann die Video-ID Sie vorbei in.
    • es denkt, dass Sie es <code> und </code> (man beachte die hex 0x3c & 0x3E Werte) ... Rich-Text zu geben?
    • Wie auch immer, das ist, warum ich meine eigene, kürzere Version geschrieben habe ... also habe ich eine kontrolliertere Umgebung zum Experimentieren.

FWIW, da Sie mit Google-APIs neu sind, ich habe ein paar Intro-Videos gemacht ich gemacht, um Entwickler on-Bord mit der Verwendung von Google APIs in this playlist. Der Auth-Code ist der härteste, also konzentriere dich auf die Videos 3 und 4 in dieser Playlist, damit du dich daran gewöhnen kannst.

Ich habe wirklich keine Videos, die YouTube-APIs abdecken (da ich mich mehr auf G Suite-APIs konzentriere), obwohl ich das Beispiel Google Apps Script habe (Video 22 in Playlist); Wenn Sie mit Apps Script noch nicht vertraut sind, müssen Sie zuerst Ihr JavaScript überprüfen und dann zuerst Video 5 auschecken. Hoffe das hilft!

Verwandte Themen