【问题标题】:Insert video results in: HttpError 400 when requesting插入视频结果:请求时出现 HttpError 400
【发布时间】:2022-07-28 17:57:53
【问题描述】:

我想从 python 上传 youtube 频道中的视频,但是当我执行我的代码时,我收到了这个错误

googleapiclient.errors.HttpError:<HttpError 400 请求 https://youtube.googleapis.com/upload/youtube/v3/videos?notifySubscribers=false&prettyPrint=true&alt=json&uploadType=multipart 时返回 \"\'sn-p\'\"。详细信息:\"[{\'message\':\"\'sn-p\'\", \'domain\': \'youtube.part\', \'reason\': \'unexpectedPart\', \'location\': \'part\', \'locationType\': \'parameter\'} ]\">

代码

import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors

from googleapiclient.http import MediaFileUpload

scopes = [\"https://www.googleapis.com/auth/youtube.upload\"]

def index():
    os.environ[\"OAUTHLIB_INSECURE_TRANSPORT\"] = \"1\"

    api_service_name = \"youtube\"
    api_version = \"v3\"
    client_secrets_file = \"CLIENT_SECRET_FILE.json\"

    # Get credentials and create an API client
    flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
        client_secrets_file, scopes)
    credentials = flow.run_console()
    youtube = googleapiclient.discovery.build(
       api_service_name, api_version, credentials=credentials)

    request = youtube.videos().insert(
       part=\"snippet\",
       notifySubscribers=False,
       prettyPrint=True,
       body={
           \"id\" : \"UC5St2PrRiL37g4MP-CPmVAA\",
           \"snippet\": {
               \"categoryId\": \"19\",
               \"title\": \"Upload Testing\",
               \"description\": \"Hello World Description\",
               \"tags\": [
                 \"Travel\",
                 \"video test\",
                 \"Travel Tips\"
               ]
           },
          \"status\": {
               \"privacyStatus\": \"private\",
               \"selfDeclaredMadeForKids\": False
          }
       },
        media_body=MediaFileUpload(\"wheat-field.mp4\")
   )
   response = request.execute()

print(response)

    标签: python google-api youtube-api youtube-data-api google-api-python-client


    【解决方案1】:

    我想如果您咨询Upload a Video 示例。您会发现您的正文格式不正确。

    #!/usr/bin/python
    
    import httplib
    import httplib2
    import os
    import random
    import sys
    import time
    
    from apiclient.discovery import build
    from apiclient.errors import HttpError
    from apiclient.http import MediaFileUpload
    from oauth2client.client import flow_from_clientsecrets
    from oauth2client.file import Storage
    from oauth2client.tools import argparser, run_flow
    
    
    # Explicitly tell the underlying HTTP transport library not to retry, since
    # we are handling retry logic ourselves.
    httplib2.RETRIES = 1
    
    # Maximum number of times to retry before giving up.
    MAX_RETRIES = 10
    
    # Always retry when these exceptions are raised.
    RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError, httplib.NotConnected,
      httplib.IncompleteRead, httplib.ImproperConnectionState,
      httplib.CannotSendRequest, httplib.CannotSendHeader,
      httplib.ResponseNotReady, httplib.BadStatusLine)
    
    # Always retry when an apiclient.errors.HttpError with one of these status
    # codes is raised.
    RETRIABLE_STATUS_CODES = [500, 502, 503, 504]
    
    # 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 API Console at
    # https://console.developers.google.com/.
    # 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 an application to upload files to the
    # authenticated user's YouTube channel, but doesn't allow other types of access.
    YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload"
    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 API 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))
    
    VALID_PRIVACY_STATUSES = ("public", "private", "unlisted")
    
    
    def get_authenticated_service(args):
      flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE,
        scope=YOUTUBE_UPLOAD_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)
    
      return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
        http=credentials.authorize(httplib2.Http()))
    
    def initialize_upload(youtube, options):
      tags = None
      if options.keywords:
        tags = options.keywords.split(",")
    
      body=dict(
        snippet=dict(
          title=options.title,
          description=options.description,
          tags=tags,
          categoryId=options.category
        ),
        status=dict(
          privacyStatus=options.privacyStatus
        )
      )
    
      # Call the API's videos.insert method to create and upload the video.
      insert_request = youtube.videos().insert(
        part=",".join(body.keys()),
        body=body,
        # The chunksize parameter specifies the size of each chunk of data, in
        # bytes, that will be uploaded at a time. Set a higher value for
        # reliable connections as fewer chunks lead to faster uploads. Set a lower
        # value for better recovery on less reliable connections.
        #
        # Setting "chunksize" equal to -1 in the code below means that the entire
        # file will be uploaded in a single HTTP request. (If the upload fails,
        # it will still be retried where it left off.) This is usually a best
        # practice, but if you're using Python older than 2.6 or if you're
        # running on App Engine, you should set the chunksize to something like
        # 1024 * 1024 (1 megabyte).
        media_body=MediaFileUpload(options.file, chunksize=-1, resumable=True)
      )
    
      resumable_upload(insert_request)
    
    # This method implements an exponential backoff strategy to resume a
    # failed upload.
    def resumable_upload(insert_request):
      response = None
      error = None
      retry = 0
      while response is None:
        try:
          print "Uploading file..."
          status, response = insert_request.next_chunk()
          if response is not None:
            if 'id' in response:
              print "Video id '%s' was successfully uploaded." % response['id']
            else:
              exit("The upload failed with an unexpected response: %s" % response)
        except HttpError, e:
          if e.resp.status in RETRIABLE_STATUS_CODES:
            error = "A retriable HTTP error %d occurred:\n%s" % (e.resp.status,
                                                                 e.content)
          else:
            raise
        except RETRIABLE_EXCEPTIONS, e:
          error = "A retriable error occurred: %s" % e
    
        if error is not None:
          print error
          retry += 1
          if retry > MAX_RETRIES:
            exit("No longer attempting to retry.")
    
          max_sleep = 2 ** retry
          sleep_seconds = random.random() * max_sleep
          print "Sleeping %f seconds and then retrying..." % sleep_seconds
          time.sleep(sleep_seconds)
    
    if __name__ == '__main__':
      argparser.add_argument("--file", required=True, help="Video file to upload")
      argparser.add_argument("--title", help="Video title", default="Test Title")
      argparser.add_argument("--description", help="Video description",
        default="Test Description")
      argparser.add_argument("--category", default="22",
        help="Numeric video category. " +
          "See https://developers.google.com/youtube/v3/docs/videoCategories/list")
      argparser.add_argument("--keywords", help="Video keywords, comma separated",
        default="")
      argparser.add_argument("--privacyStatus", choices=VALID_PRIVACY_STATUSES,
        default=VALID_PRIVACY_STATUSES[0], help="Video privacy status.")
      args = argparser.parse_args()
    
      if not os.path.exists(args.file):
        exit("Please specify a valid file using the --file= parameter.")
    
      youtube = get_authenticated_service(args)
      try:
        initialize_upload(youtube, args)
      except HttpError, e:
        print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
    

    专业提示:请记住,您的视频将作为私人视频上传,直到您通过 audit

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      • 1970-01-01
      • 2014-09-05
      • 2015-12-25
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多