効率の良いYouTube Data APIの使い方

:::note
この記事はぶいぎーく！ Advent Calendar 2024 6日目記事として投稿しています。
:::
:::note warn
この記事に書かれている項目はYouTubeが黙認しているであろう機能であり、公式ドキュメント等への記載はありません。
また、今後削除されることがあります。
:::

## YouTube Data APIとは？
YouTube Data APIはYouTube上に存在する動画、コメント、プレイリストなどの各種データを取得、作成、更新するためのAPIです。
この記事では、特定チャンネルの動画情報取得を目的としています。

クオータは 10000unit/day で上限を引き上げることも出来ます。
上限引き上げは[こちらの記事](https://qiita.com/Erytheia/items/3ae377b8c27a40690333)が参考になると思います。

ここで長々と解説するのも問題なので詳細は[YouTube Data API の概要  |  Google for Developers](https://developers.google.com/youtube/v3/getting-started?hl=ja)をご確認ください。

## 課題
さて、「ぶいぎーく！」では現在20名程のメンバーが所属しており、公式サイトでは現在のライブ配信やスケジュール、投稿した動画などを表示するようにしています。
「現在のライブ配信」を扱う以上リアルタイム性を持たせた処理をしつつ、スケジュールにない所謂「ゲリラ配信」にも対応させる必要がありました。

そのため改善前に浮かび上がった課題は以下のようになりました

- 新規取得が低頻度
  しかし、前述の通りクオータは **10000単位/日** で検索(`search:list`)を使った動画取得は **100単位/要求** と非常にコストが悪く、以前使用していたAPIキャッシュサーバーは0:30と12:30の二回のみ新規動画の取得を行っていました
- 情報更新も低頻度
  また、取得済みの動画についても毎時0分に更新されるのみで有るため、配信開始・終了が毎時0分から少しでもずれると、その後1時間はスケジュール・配信中のように一つ前の状態を表示していました
- Shortsの判別
  YouTube Data APIではYouTube Shortsを判別する機能を持ち合わせていません
  動画一覧とShortsの一覧をYouTubeチャンネルのそれと同様に分離する機能を実装するには必要なことです
- メンバーシップ限定などの判別
  Shorts同様に判別が困難でした
  Shortsは実質スクレイピングと同じような手法をいくつかの記事で紹介されていましたが、こちらはそのような方法を見つけることが出来ませんでした
- クオータ制限
  (Shorts判別以外の)すべての元凶はYouTube Data APIのクオータ制限が低い(または、検索のコストが大きい)事です
  `search:list`以外の方法で新規動画を取得する必要がありました

## 調査
今回も日本語記事での解決を目指しましたが、クオータ引き上げ以外の記事を見つけることが出来ませんでした。
ただ、公式ドキュメント内と実際のAPIレスポンスから気になる部分を発見しました。
`relatedPlaylists`内に`uploads`というキーがあること、そしてこれが規則的に生成されていること。
ここが解決への糸口になると考えました。

```json:usaneko_xlarge.items.json
{
  "kind": "youtube#channel",
  "id": "UCLw6ggMqvCiXBXNEWilDzVw",
  "snippet": {
    "title": "うさねこらーじ v2.1",
    "customUrl": "@usaneko_xlarge",
    "defaultLanguage": "ja",
  },
  "contentDetails": {
    "relatedPlaylists": {
      "likes": "",
      "uploads": "UULw6ggMqvCiXBXNEWilDzVw"
    }
  }
}
```
:::note
一部抜粋、省略
:::

しかし、この時点ではShortsやメンバーシップ限定の判別が出来ません。
そこで海外掲示板などにもアクセスして解決法を探しました。
流石海外掲示板と言わんばかりに色々な方法が出てきます。
その中で異彩を放っていたある一つのレスが目に入りました。

## 自動生成プレイリスト
YouTubeではチャンネル毎に自動生成されるプレイリストがあるようで、`UU〜`のアップロード動画はその基本的なものであるようです。

:::note
〜の部分は`UC〜`のようなチャンネルIDから取得出来ます。
前述のうさねこらーじ氏のチャンネルではチャンネルIDが`UCLw6ggMqvCiXBXNEWilDzVw`なので、〜の部分は`Lw6ggMqvCiXBXNEWilDzVw`となります。
:::

そしてそのレスでは`UU__〜`のように二文字のコードを付けることで内容を絞れるのだと言います。
この結果はわざわざJSONで書く必要は無いので、[こちら(うさねこらーじ氏が投稿したShortsのプレイリスト)](https://www.youtube.com/playlist?list=UUSHLw6ggMqvCiXBXNEWilDzVw)をご確認ください

当然のごとくYouTube Data APIでも正常に取得出来るプレイリストでした。
`playlistitems:list`は`search:list`とは異なり 1単位/要求 という素晴らしいコストでありながら、同じかそれ以上の事が出来るようになりました。

海外掲示板にも書いてありましたが以下のようなプレイリストを取得出来ます。

:::note warn
公認と書いていないものはドキュメントやレスポンスに記載されていない(=非公認)機能です。
ただ、プレイリストの説明などが翻訳されているので裏技以外の何でも無いかもしれません。
:::

| 種類             | 接頭辞 | 備考                                                                               |
| :--------------- | :----- | :--------------------------------------------------------------------------------- |
| 高評価した動画   | `LL`   | 公認。Google OAuth 2.0で認証した場合のみ。チャンネルIDは不要(プレイリストIDが`LL`) |
| アップロード動画 | `UU`   | 公認                                                                               |
| 公開動画         | `UULF` | 「動画」タブと同義                                                                 |
| ライブ配信       | `UULV` | 「ライブ」タブと同義                                                               |
| YouTube Shorts   | `UUSH` | 「ショート」タブと同義                                                             |
| 人気の動画       | `UULP` | 「動画」タブの「人気の動画」とほぼ同義                                             |
| 人気のライブ配信 | `UUPV` | 「ライブ」タブの「人気の動画」とほぼ同義                                           |
| 人気のShorts     | `UUPS` | 「ショート」タブの「人気の動画」とほぼ同義                                         |
| メン限動画       | `UUMO` | 該当チャンネルにメンバーシップが無いとエラー                                       |
| メン限配信       | `UUMV` | 該当チャンネルにメンバーシップが無いとエラー                                       |
| メン限Shorts     | `UUMS` | 該当チャンネルにメンバーシップが無いとエラー                                       |

## 解決へ
恐らく非公認な手法でありつつも、確実に内容を絞れるため、ぶいぎーく！(とVirtLive!)用で使用するシステムとしてこのプレイリスト取得へ変更しました。
また、同時にすべての動作を1時間毎に変更して、様子を見ました。

すると変更日を境にガクッと使用量が減り、かなり余裕が出来ました。
![Screenshot 2024-12-04 at 11-33-46 API とサービス – API とサービス – VirtLive Common Inf… – Google Cloud コンソール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616523/06d7f832-31a9-b49d-af1d-4343754d97d6.png)

## 最後に
この手法は裏技のようなものですから、Googleさんから怒られるかもしれません。
それと、実はYouTube Data APIを使うのは実質的にこれが初めてとなります。
おかしなところが有りましたらご指摘をお願いします。

それでは、ぶいぎーく！スタッフ兼VirtLive! JP 零期生の崎津 祥汰でした。
16日分にも寄稿する予定なのでよろしければご期待下さい。