This article uploads videos using the youtube API. The language is Python3. You can proceed according to the official document below, but I have added some points that I was addicted to.
As a premise, it is assumed that the project has been created with GCP.
Install the library to use google API.
python
$ pip install google-api-python-client
Open the link below and create your credentials from the GCP console. This time we will use OAuth 2.0. GCP Console-Credentials (https://console.developers.google.com/apis/credentials?hl=ja)
(1) Go to Create Credentials> OAuth Client ID (select the project in the upper left)
(2) Select "Other". Name is created by entering any value
(3) Client ID and client secret can be obtained
Also, if the OAuth consent screen has not been created, create it.
Fill in the application name and support email fields and press the create button at the bottom of the screen.
Open the link below and search for the YouTube Data API from the GCP console. As of 2020.1, it is "YouTube Data API v3". When you open it, there is an enable button, so enable it. GCP Console-API Library
Working folder
$ tree
.
├── movies
│ └── sample001.MP4 #Video to be uploaded
├── client_secrets.json
└── upload_video.py
There are two sources, JSON and Python for authentication information.
Create client_secrets.json. For client_id
and client_secret
, set the values of the client ID and client secret created in "1. Creating authorization information".
client_secrets.json
{
"web": {
"client_id": "[[INSERT CLIENT ID HERE]]",
"client_secret": "[[INSERT CLIENT SECRET HERE]]",
"redirect_uris": [],
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token"
}
}
Python
Basically, you can use the source of Official, but if it is written in Python2 system and it is Python3 as it is It doesn't work. So, I'll rewrite it a little so that it works with Python3. There are two rewrite points as follows. ・ Migrate from httplib to http.client -Rewriting the print statement (As an aside, change the indent to 4 bytes)
upload_video.py(Official comments have been deleted due to space limitations)
import http.client #httplib is Python3 is http.Migrate to client
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
httplib2.RETRIES = 1
MAX_RETRIES = 10
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)
RETRIABLE_STATUS_CODES = [500, 502, 503, 504]
CLIENT_SECRETS_FILE = "client_secrets.json"
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))
YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
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
)
)
insert_request = youtube.videos().insert(
part=",".join(body.keys()),
body=body,
media_body=MediaFileUpload(options.file, chunksize=-1, resumable=True)
)
resumable_upload(insert_request)
def resumable_upload(insert_request):
response = None
error = None
retry = 0
while response is None:
try:
print("Uploading file...") #print statement
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 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)
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 as e:
print("An HTTP error %d occurred:\n%s" % (e.resp.status, e.content))
--The YouTube Data API passes the contents set in snippet to the API. ʻThe body in initialize_upload makes a dict of the value to be passed as a snippet. --The value passed to snippet is obtained from the argument as ʻargs
.
--In get_authenticated_service
, the object (?) That uses the API is built and returned from the resource name and operation name (insert etc.) of the YouTube Data API. In this case, pass the built object to ʻinitialize_upload and execute upload with
youtube.videos (). Insert`.
From the command line, execute as follows. Since there are many arguments, it may be easier to use a shell script if you want to execute it several times.
Perform video upload
$ python upload_video.py --file="./movies/sample001.MP4" \
--title="Sample Movie" \
--description="This is a sample movie." \
--category="22" \
--privacyStatus="private"
The meanings of the arguments are as follows.
--file: Path of the video to upload --title: Video title after upload --description: Video description --category: Category. The default is 22 --privacyStatus: Video publishing settings. Post privately if private
The items and meanings that can be specified as snippet are described below.
YouTube Data API Videos [YouTube Data API Videos: insert] (https://developers.google.com/youtube/v3/docs/videos/insert?hl=ja)
When you execute it for the first time, the screen will change to the browser and ask for Google account selection and YouTube management permission, so please allow it according to the screen.
If you see a screen like the one below in Chrome, show the details and go to the unsafe page at the bottom left
Allow video management. (Although it may be displayed on another screen, continue to allow it.)
Depending on the size of the video, the upload will be completed as follows after a while.
Execution result
Uploading file...
Video id '[video id]' was successfully uploaded.
You can also confirm that the video has been posted from the YouTube screen.
Originally, I wanted to use the API to upload a large number of videos in a batch, but when I wrote and executed a program that repeatedly executes the API, the following error occurred.
Uploading file...
An HTTP error 403 occurred:
b'{\n "error": {\n "errors": [\n {\n "domain": "youtube.quota",\n "reason": "quotaExceeded",\n "message": "The request cannot be completed because you have exceeded your \\u003ca href=\\"/youtube/v3/getting-started#quota\\"\\u003equota\\u003c/a\\u003e."\n }\n ],\n "code": 403,\n "message": "The request cannot be completed because you have exceeded your \\u003ca href=\\"/youtube/v3/getting-started#quota\\"\\u003equota\\u003c/a\\u003e."\n }\n}\n'
When I investigated, the API is limited to 10,000 per day, and it is said that about 1,600 units will be used for uploading videos. So, it seems that you can upload videos to YouTube via API about 6 videos / day ...
YouTube Data API-Errors YouTube Data API Overview-Quota Usage
An application is required to raise this, but I gave it up because it was just for personal use. At least I could have done what I wanted to do if it was 30 pieces / day, but if it was 6 pieces, manual work might be faster ...
It may be useful if you want to upload videos in your application.
Recommended Posts