Youtube Data API v3を使用して動画を再生リストに追加する手順についての覚え書き
はじめに
Youtube Data API v3でYoutbeにアクセスするための作業はこちらで完了しているものとする
動画を追加する
下記APIを使用する
サンプルコード
上記ページのサンプルコード
# -*- coding: utf-8 -*-
# Sample Python code for youtube.playlistItems.insert
# See instructions for running these code samples locally:
# https://developers.google.com/explorer-help/code-samples#python
import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
scopes = [
# "https://www.googleapis.com/auth/youtube.force-ssl"
"https://www.googleapis.com/auth/youtube.readonly"
]
def main():
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
api_service_name = "youtube"
api_version = "v3"
client_secrets_file = "secret.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_local_server(open_browser=False)
youtube = googleapiclient.discovery.build(
api_service_name, api_version, credentials=credentials)
request = youtube.playlistItems().insert(
part="snippet",
body={
"snippet": {
"playlistId": "PLAYLISTID",
"position": 0,
"resourceId": {
"kind": "youtube#video",
"videoId": "F12D4zPcUEA"
}
}
}
)
response = request.execute()
print(response)
if __name__ == "__main__":
main()
ハマリどころ
以下はまったところ
スコープ
Youtube Data APIは実行できる場所(スコープ)が決まっていてそれを指定しないとInsufficient Permission
って怒られる
Traceback (most recent call last):
File "/mnt/c/Users/foobar/Projects/myproj/Youtube/test.py", line 52, in <module>
main()
File "/mnt/c/Users/foobar/Projects/myproj/Youtube/test.py", line 47, in main
response = request.execute()
File "/home/foobar/.local/lib/python3.10/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "/home/foobar/.local/lib/python3.10/site-packages/googleapiclient/http.py", line 938, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet&alt=json returned "Request had insufficient authentication scopes.". Details: "[{'message': 'Insufficient Permission', 'domain': 'global', 'reason': 'insufficientPermissions'}]">
スコープはコードのここで指定する
scopes = [
"https://www.googleapis.com/auth/youtube.force-ssl", #追加更新系APIで必要
"https://www.googleapis.com/auth/youtube.readonly" # 取得系APIで必要
]
サンプルコードをそのまま実行していればハマらなかったところ。
自分は情報取得系APIのサンプルコードの流用で始めたのでスコープが取得系のままなのを気が付かずハマリ散らかした
認証
スコープに複数のURLがあると認証のとき以下のような確認がある
このときアクセスできる情報を選択してください
のところにチェックを入れないとアクセスに失敗する
続行ボタンをクリックするとスクリプトでエラーが発生する
Traceback (most recent call last):
File "/mnt/c/Users/foobar/Projects/myproj/Youtube/test.py", line 52, in <module>
main()
File "/mnt/c/Users/foobar/Projects/myproj/Youtube/test.py", line 30, in main
credentials = flow.run_local_server(open_browser=False)
File "/home/foobar/.local/lib/python3.10/site-packages/google_auth_oauthlib/flow.py", line 455, in run_local_server
self.fetch_token(
File "/home/foobar/.local/lib/python3.10/site-packages/google_auth_oauthlib/flow.py", line 285, in fetch_token
return self.oauth2session.fetch_token(self.client_config["token_uri"], **kwargs)
File "/home/foobar/.local/lib/python3.10/site-packages/requests_oauthlib/oauth2_session.py", line 271, in fetch_token
self._client.parse_request_uri_response(
File "/usr/lib/python3/dist-packages/oauthlib/oauth2/rfc6749/clients/web_application.py", line 220, in parse_request_uri_response
response = parse_authorization_code_response(uri, state=state)
File "/usr/lib/python3/dist-packages/oauthlib/oauth2/rfc6749/parameters.py", line 281, in parse_authorization_code_response
raise_from_error(params.get('error'), params)
File "/usr/lib/python3/dist-packages/oauthlib/oauth2/rfc6749/errors.py", line 399, in raise_from_error
raise cls(**kwargs)
oauthlib.oauth2.rfc6749.errors.AccessDeniedError: (access_denied)
再生リストの動画表示順序の設定
再生リストは「デフォルトの動画表示順序」という設定がある。これが「Youtube内で手動で並べ替え」以外になっているとサンプルコードはエラーを出す
Traceback (most recent call last):
File "/mnt/c/Users/satoshi/Projects/myproj/Youtube/test.py", line 52, in <module>
main()
File "/mnt/c/Users/satoshi/Projects/myproj/Youtube/test.py", line 47, in main
response = request.execute()
File "/home/satoshi/.local/lib/python3.10/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "/home/satoshi/.local/lib/python3.10/site-packages/googleapiclient/http.py", line 938, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet&alt=json returned "Playlist should use manual sorting to support position.". Details: "[{'message': 'Playlist should use manual sorting to support position.', 'domain': 'youtube.playlistItem', 'reason': 'manualSortRequired'}]">
解決するにはplaylistitemリソースのposition
プロパティを削除するか、
body={
"snippet": {
"playlistId": "PLAYLISTID",
"position": 0, # エラーの原因
"resourceId": {
"kind": "youtube#video",
"videoId": "F12D4zPcUEA"
}
}
}
再生リストの「デフォルトの動画表示順序」設定を「Youtube内で手動で並べ替え」のものにする(Youtube側で設定)
おわり
再生リストに動画を追加するだけなのに以外にもつまづきポイントが多くて泣きそう