Scripting way to upload videos to peertube and youtube
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
4.2 KiB

  1. #!/usr/bin/python
  2. # coding: utf-8
  3. # From Youtube samples : https://raw.githubusercontent.com/youtube/api-samples/master/python/upload_video.py
  4. import argparse
  5. import httplib
  6. import httplib2
  7. import os
  8. import random
  9. import time
  10. import copy
  11. import json
  12. import google.oauth2.credentials
  13. import google_auth_oauthlib.flow
  14. from googleapiclient.discovery import build
  15. from googleapiclient.errors import HttpError
  16. from googleapiclient.http import MediaFileUpload
  17. from google_auth_oauthlib.flow import InstalledAppFlow
  18. # Explicitly tell the underlying HTTP transport library not to retry, since
  19. # we are handling retry logic ourselves.
  20. httplib2.RETRIES = 1
  21. # Maximum number of times to retry before giving up.
  22. MAX_RETRIES = 10
  23. # Youtube retriables cases
  24. RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError, httplib.NotConnected,
  25. httplib.IncompleteRead, httplib.ImproperConnectionState,
  26. httplib.CannotSendRequest, httplib.CannotSendHeader,
  27. httplib.ResponseNotReady, httplib.BadStatusLine)
  28. RETRIABLE_STATUS_CODES = [500, 502, 503, 504]
  29. CLIENT_SECRETS_FILE = 'youtube_secret.json'
  30. CREDENTIALS_PATH = ".youtube_credentials.json"
  31. SCOPES = ['https://www.googleapis.com/auth/youtube.upload']
  32. API_SERVICE_NAME = 'youtube'
  33. API_VERSION = 'v3'
  34. # Authorize the request and store authorization credentials.
  35. def get_authenticated_service():
  36. flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
  37. if os.path.exists(CREDENTIALS_PATH):
  38. with open(CREDENTIALS_PATH, 'r') as f:
  39. credential_params = json.load(f)
  40. credentials = google.oauth2.credentials.Credentials(
  41. credential_params["token"],
  42. refresh_token=credential_params["_refresh_token"],
  43. token_uri=credential_params["_token_uri"],
  44. client_id=credential_params["_client_id"],
  45. client_secret=credential_params["_client_secret"]
  46. )
  47. else:
  48. credentials = flow.run_local_server()
  49. with open(CREDENTIALS_PATH, 'w') as f:
  50. p = copy.deepcopy(vars(credentials))
  51. del p["expiry"]
  52. json.dump(p, f)
  53. return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
  54. def initialize_upload(youtube, options):
  55. path = options.get('--file')
  56. print options.get('--name')
  57. tags = None
  58. if options.get('--tags'):
  59. tags = options.get('--tags').split(',')
  60. body=dict(
  61. snippet=dict(
  62. title=options.get('--name') or os.path.splitext(os.path.basename(path))[0],
  63. description=options.get('--description') or "",
  64. tags=tags,
  65. categoryId=str(options.get('--category') or 1),
  66. ),
  67. status=dict(
  68. privacyStatus=str(options.get('--privacy') or "private"),
  69. )
  70. )
  71. # Call the API's videos.insert method to create and upload the video.
  72. insert_request = youtube.videos().insert(
  73. part=','.join(body.keys()),
  74. body=body,
  75. media_body=MediaFileUpload(path, chunksize=-1, resumable=True)
  76. )
  77. resumable_upload(insert_request)
  78. # This method implements an exponential backoff strategy to resume a
  79. # failed upload.
  80. def resumable_upload(request):
  81. response = None
  82. error = None
  83. retry = 0
  84. while response is None:
  85. try:
  86. print 'Uploading file...'
  87. status, response = request.next_chunk()
  88. if response is not None:
  89. if 'id' in response:
  90. print 'Video id "%s" was successfully uploaded.' % response['id']
  91. else:
  92. exit('The upload failed with an unexpected response: %s' % response)
  93. except HttpError, e:
  94. if e.resp.status in RETRIABLE_STATUS_CODES:
  95. error = 'A retriable HTTP error %d occurred:\n%s' % (e.resp.status,
  96. e.content)
  97. else:
  98. raise
  99. except RETRIABLE_EXCEPTIONS, e:
  100. error = 'A retriable error occurred: %s' % e
  101. if error is not None:
  102. print error
  103. retry += 1
  104. if retry > MAX_RETRIES:
  105. exit('No longer attempting to retry.')
  106. max_sleep = 2 ** retry
  107. sleep_seconds = random.random() * max_sleep
  108. print 'Sleeping %f seconds and then retrying...' % sleep_seconds
  109. time.sleep(sleep_seconds)
  110. def run(options):
  111. youtube = get_authenticated_service()
  112. try:
  113. initialize_upload(youtube, options)
  114. except HttpError, e:
  115. print 'An HTTP error %d occurred:\n%s' % (e.resp.status, e.content)