python - YouTube 可恢复上传 HttpError 404

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

我编写了一个脚本来执行将 .mp4 文件可恢复上传到 YouTube 的工作。负责处理这个问题的代码大部分是从 https://learndataanalysis.org/how-to-upload-a-video-to-youtube-using-youtube-data-api-in-python/ 重用的。和 https://developers.google.com/youtube/v3/guides/uploading_a_video ,虽然我对过时的语法和库做了一些小的修改。
这是我的代码:

def create_service(client_secret_file, api_name, api_version, *scopes):
    CLIENT_SECRET_FILE = client_secret_file
    API_SERVICE_NAME = api_name
    API_VERSION = api_version
    SCOPES = [scope for scope in scopes[0]]

    cred = None

    pickle_file = f'token_{API_SERVICE_NAME}_{API_VERSION}.pickle'

    if os.path.exists(pickle_file):
        with open(pickle_file, 'rb') as token:
            cred = pickle.load(token)

    if not cred or not cred.valid:
        if cred and cred.expired and cred.refresh_token:
            cred.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
            cred = flow.run_local_server()

        with open(pickle_file, 'wb') as token:
            pickle.dump(cred, token)

    try:
        service = build(API_SERVICE_NAME, API_VERSION, credentials=cred)
        print(API_SERVICE_NAME, 'service created successfully')
        return service
    except Exception as e:
        print('Unable to connect.')
        print(e)
        return None

def upload_video(game_id, slugs): # (durations)
    API_NAME = 'youtube'
    API_VERSION = 'v3'
    SCOPES = ['https://www.googleapis.com/auth/youtube']

    service = create_service(YOUTUBE_CS_FILENAME, API_NAME, API_VERSION, SCOPES)

    # Get playlist ID, title, and video count
    playlist_id, playlist_title, video_count = get_playlist(game_id, service)

    upload_request_body = {
        'snippet': {
            'categoryId': 20,
            'title': generate_title(playlist_title, video_count),
            'description': 'test', # generate_description(durations, slugs),
            'tags': ['Test', 'multiple', 'tags']
        },
        'status': {
            'privacyStatus': 'private',
            'selfDeclaredMadeForKids': False
        }
    }

    mediaFile = MediaFileUpload('final.mp4', chunksize=-1, resumable=True)

    video_insert_request = service.videos().insert(
        part="snippet,status",
        body=upload_request_body,
        media_body=mediaFile
    )

    # 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, http.client.NotConnected,
        http.client.IncompleteRead, http.client.ImproperConnectionState,
        http.client.CannotSendRequest, http.client.CannotSendHeader,
        http.client.ResponseNotReady, http.client.BadStatusLine)

    # Always retry when an apiclient.errors.HttpError with one of these status
    # codes is raised.
    RETRIABLE_STATUS_CODES = [500, 502, 503, 504]

    # Upload the video... finally.
    response = None
    error = None
    retry = 0
    video_id = ''
    while response is None:
        try:
            print("Uploading file...")
            print(video_insert_request)
            status, response = video_insert_request.next_chunk()
            if response is not None:
                if 'id' in response:
                    video_id = response['id']
                    print("Video id '%s' was successfully uploaded." % response['id'])
            else:
                exit("The upload failed with an unexpected response: %s" % response)
        except HttpError as 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 as 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)

    insert_to_playlist(service, playlist_id, video_id)
一切运行成功,直到开始可恢复上传。对 next_chunk() 的调用导致 404 错误。我已经包含了来自 httplib2.debuglevel = 4 的调试信息:
connect: (youtube.googleapis.com, 443)
send: b'POST /upload/youtube/v3/videos?part=snippet%2Cstatus&alt=json&uploadType=resumable HTTP/1.1\r\nHost: youtube.googleapis.com\r\naccept: application/json\r\naccept-encoding: gzip, deflate\r\nuser-agent: (gzip)\r\nx-goog-api-client: gdcl/1.12.1 gl-python/3.6.4\r\ncontent-type: application/json\r\nx-upload-content-type: video/mp4\r\nx-upload-content-length: 38653386\r\ncontent-length: 204\r\nauthorization: Bearer [REDACTED OAUTH TOKEN]'
send: b'{"snippet": {"categoryId": 20, "title": "Test title", "description": "test", "tags": ["Test", "multiple", "tags"]}, "status": {"privacyStatus": "private", "selfDeclaredMadeForKids": false}}'
reply: 'HTTP/1.1 404 Not Found\r\n'
header: Content-Type header: X-GUploader-UploadID header: Content-Length header: Date header: Server header: Alt-Svc Traceback (most recent call last):
  File "./create_video.py", line 354, in <module>
    main()
  File "./create_video.py", line 348, in main
    args.func(args)
  File "./create_video.py", line 26, in run
    upload_video(game_id, slugs) # (durations)
  File "./create_video.py", line 251, in upload_video
    status, response = video_insert_request.next_chunk()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/googleapiclient/_helpers.py", line 134, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/googleapiclient/http.py", line 991, in next_chunk
    raise ResumableUploadError(resp, content)
googleapiclient.errors.ResumableUploadError: <HttpError 404 "Not Found">

最佳答案

今天早上报告了错误。问题解决了~3小时

关于python - YouTube 可恢复上传 HttpError 404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63948760/

相关文章:

python - 使用python读取网络中所有系统的驱动数据

python - 在字典声明中使用 OrderedDict

javascript - 未捕获的安全错误 : Blocked a frame with origin "https://www.google.com" from accessing a frame with origin "http://my.site.com".

javascript - Google Loader 与标准 &lt;script&gt; 标签

javascript - 从 youtube 视频生成音频波形

php - 如何将 youtube 嵌入链接存储在数据库中

iframe - 通过我的服务器代理YouTube iframe

基于 Python 的密码跟踪器(或字典)

python - 如何将openCV中的imshow()和moveWindow()与python结合起来?

python - 如何组合/加速多个 API 调用以提高性能?