はじめに
この記事の情報は2017年12月のYouTubeに関連した仕様を基に記述したものです。
YouTubeにたくさん動画をアップロードをしていると、アップロードをした後に修正が必要で、それも動画を取り替えないと修正ができないような(字幕の誤字・脱字など)間違いが紛れ込むケースも出てきます。
アップロードした動画自体は一旦削除して、修正版を再度アップロードすればいいのですが、削除した動画につけていたタグや説明もそのまま削除されてしまいます。タグや説明をYouTube謹製の編集画面でいったん表示させてから、メモ帳などのエディタを使ってコピー&ペーストするのはかなり手間のかかる作業なので、できれば避けたいところです。
そこで、YouTube Data API v3を使って動画のタグの情報を読み出して、別の動画に追加するためのPython3のコードを書いてみました。本記事ではそれについて書いていきます。
なお、次節以降のコードを使用するためには、OAuth2.0による認証のための情報の作成が必要です。
というわけで、サクサクとコードを書きます。
ということで、YouTube Data API v3のページも参考にしながら、以下のようなコードを書いてみました。
#!/usr/bin/python | |
import httplib2 | |
import os | |
import sys | |
from apiclient.discovery import build | |
from oauth2client.client import flow_from_clientsecrets | |
from oauth2client.file import Storage | |
from oauth2client.tools import argparser, run_flow | |
# Youtubeからある動画についているタグを別の動画のタグとしてコピーするための | |
# Pythonのテストプログラム。 | |
# URL: https://pandanote.info/?p=1454 | |
# | |
# 使い方: | |
# copytag.py <コピー元の動画のID> <コピー先の動画のID> | |
# | |
# 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 Developers 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 | |
if len(sys.argv) < 3: | |
print('Usage: python3 {0:s} <コピー元の動画のID> <コピー先の動画のID>'.format(sys.argv[0])) | |
quit() | |
source_id = sys.argv[1] | |
target_id = sys.argv[2] | |
del sys.argv[2] | |
del sys.argv[1] | |
CLIENT_SECRETS_FILE = "client_secret_copytag.json" | |
# 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 Developers 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)) | |
# This OAuth 2.0 access scope allows for read-only access to the authenticated | |
# user's account, but not other types of account access. | |
YOUTUBE_READ_WRITE_SCOPE = "https://www.googleapis.com/auth/youtube" | |
YOUTUBE_API_SERVICE_NAME = "youtube" | |
YOUTUBE_API_VERSION = "v3" | |
flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, | |
message=MISSING_CLIENT_SECRETS_MESSAGE, | |
scope=YOUTUBE_READ_WRITE_SCOPE) | |
storage = Storage("%s-oauth2.json" % sys.argv[0]) | |
credentials = storage.get() | |
if credentials is None or credentials.invalid: | |
flags = argparser.parse_args() | |
credentials = run_flow(flow, storage, flags) | |
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, | |
http=credentials.authorize(httplib2.Http())) | |
# コピー元の動画のタグを抜き出して、コピー先の動画のタグとしてコピーします。 | |
# まず、コピー元の動画からタグを抜き出す処理を定義します。 | |
video_list_response = youtube.videos().list( | |
id=source_id, | |
part="snippet", | |
maxResults=50 | |
).execute() | |
tags = [] | |
if not video_list_response["items"]: | |
print("Video {0:s} was not found.".format(source_id)) | |
quit() | |
for video_list_item in video_list_response["items"]: | |
if 'tags' in video_list_item["snippet"]: | |
tags.extend(video_list_item["snippet"]["tags"]) | |
video_list_response = youtube.videos().list( | |
id=target_id, | |
part="snippet", | |
maxResults=50 | |
).execute() | |
if not video_list_response["items"]: | |
print("Video {0:s} was not found.".format(target_id)) | |
quit() | |
target_snippet = video_list_response["items"][0]["snippet"] | |
if "tags" not in target_snippet: | |
target_snippet["tags"] = [] | |
target_snippet["tags"].extend(tags) | |
insert_tag_request = youtube.videos().update( | |
part='snippet', | |
body=dict( | |
snippet=target_snippet, | |
id=target_id | |
) | |
).execute() |
読み込みだけだった前の記事の時とは異なり、読み書きを行うため、SCOPEを変更しています(61行目)。
69-74行目あたりでCredentialを取得していますが、ここでコマンドラインから指定された引数を使用します。そこで、このスクリプト独自のコマンドライン引数(コピー元の動画のID及びコピー先の動画のID)は別の変数にコピーした後に削除(36,37行目)してから、Credentialの取得処理に修正されたコマンドライン引数のリストを渡しています。
使用例
Python3のスクリプトの使用法
例えば、こんなタグが設定されていた動画(以下、「コピー先動画」と書きます。)があったとします。
これに対して、シェルのコマンドプロンプトから以下のコマンドを実行します。コピー先動画は第2引数に指定します。
すると、上記のコマンドの第1引数に指定された動画のタグがコピー先動画のタグにすべて追加されますので、コピー先動画のタグは以下のようになります。
なお、第3引数以降にはCredentialを取得するためのコマンドラインオプションを指定することができますが、一度Credentialの取得に成功すると、その後は取得したものをそのまま使用しますので、コマンドラインオプションを指定する必要はありません。
認証情報の作成
YouTube Data API v3を最初に呼び出すときに限り、呼び出し元のPCにインストールされているブラウザを起動して、認証情報を作成します(呼び出し元のPCからブラウザが起動できない場合には、コマンドの実行がいったん中断して、別のブラウザから認証情報を作成するためのURLにアクセスするように指示されるので、指示通りにブラウザを起動して指定されたURLにアクセスして認証情報を作成します)。
呼び出し元のPCにインストールされているブラウザを起動することができれば、認証情報の作成は自動的に行われます。そこで、Fedora 27がインストールされているPCで認証情報が作成される様子を撮影した動画を作成しました。
Windows 10でもFedora 27の場合と同様に認証情報を自動的に作成することができますが、このあたりの記事を参考にして、pipに付属しているスクリプトを修正する必要があります。
まとめ
ここまで YouTube Data API v3を使用して、動画のタグをコピーするための方法について書きました。これで、タグのコピーがWebブラウザを使わずにコマンドライン経由でできるようになりますので、作業効率の向上につながると思います。
また、説明についても類似の方法でコピーを行うプログラムが書けそうなので、別の記事として書くかもしれません。
この記事は以上です。