目次
はじめに
毎晩寝る前にASMRを聴くのが日課になっています。
ただ、YouTubeで「今日の気分に合う1本」を探すのが意外と大変でした。検索すると再生数の多い定番の動画ばかり出てきますし、好きな配信者の新しいアーカイブは通知に埋もれてしまいます。「今夜は耳かきで、30分くらいで、雑談なしのもの」のように条件を決めて探そうとすると、それだけで眠くなってしまいます。
それなら、ASMRの配信だけを集めて、条件で絞り込める場所を自分で作ればいい。そう思って作ったのが ASMRまとめ [https://asmrmatome.com] です。
この記事では、サイトの仕組みと、作っていて一番大変だった「タグの自動付与」で外部APIの上限を超えてしまった話を書きます。
サイトの構成
使っている技術は、どれも一般的なものです。
- フレームワーク:Laravel(PHP)
- サーバー:VPS(Nginx)。共有サーバーではなくVPSにしたのは、定期実行の処理(cron)が多く、自由に組みたかったからです
- 新着動画の取得:YouTubeのRSSフィード
- 動画やチャンネルの詳しい情報:YouTube Data API v3
新着はRSSで見つけて、詳しい情報だけAPIで取る
YouTubeのAPIには1日に使える量(クォータ)の上限があります。登録している配信者は数百人いるので、全員の新着をAPIで頻繁に確認すると、すぐに上限に届いてしまいます。
そこで、新着を見つけるところはRSSに任せています。YouTubeのチャンネルにはRSSフィードがあり、APIキーなしで最新の動画一覧を読めます。これを数分おきに確認して、新しい動画が見つかったときだけAPIで詳しい情報を取ります。詳しい情報とは、配信中か・アーカイブか・配信予定か、動画の長さ、などです。
役割を分けたことで、APIの使用量を抑えたまま、新着をほぼすぐに反映できるようになりました。
できること
- 配信中の一覧:いまライブ配信しているASMRがひと目でわかります
- アーカイブ検索:タグ(耳かき・囁き・環境音など)や動画の長さで絞り込めます
- ランダム再生:迷ったときに1本選んでくれます
- 配信者ページ:配信者ごとの動画一覧です
- 好みから配信者を探す(β):好きなタグから、近い傾向の配信者を探せます
作ってみて大変だったこと:タグの自動付与
このサイトで一番大事なのはタグです。「耳かき」「囁き」「雨音」といったタグで絞り込めないと、YouTubeで検索するのと変わりません。
ところが、動画は毎日たくさん増えます。手作業でタグを付けるのは現実的ではないので、自動化することにしました。
最初は辞書で付けていた
最初の方法は単純で、タグごとに言い回しの一覧(辞書)を用意しておき、動画のタイトルに含まれていたらそのタグを付ける、というものでした。たとえば「耳かき」「みみかき」「耳掃除」のどれかがあれば「耳かき」タグを付けます。
これでもかなり使えましたが、限界もありました。ASMRの動画タイトルは自由に書かれていて、配信者独自の言い回しや略し方、絵文字まじりの表記が多いです。辞書を地道に増やしても取りこぼしは残ります。
AI(Gemini API)に読ませることにした
そこで、新着動画のタイトルをGoogleのGemini APIに読ませて、タグを提案してもらう仕組みを足しました。
使ったのは無料枠です。無料枠には 1分あたりのリクエスト数の上限(当時は15回/分) があります。新着は1件ずつ、ぽつぽつ来るものだと思っていたので、特に対策はしていませんでした。
深夜、新着がまとめて来て上限を超えた
ある日の深夜1時ごろ、多くの配信者の夜の配信がほぼ同時に終わりました。10分ほどで約200件のアーカイブが一気に入ってきました。
新着1件ごとにGeminiを呼ぶ作りで、しかも間隔を空ける処理は入れていませんでした。そのため、リクエストが一時的に 1分あたりの上限を大きく超えて しまいました。
翌朝、Googleから 利用規約違反の通知 が届いていました。原因を調べて上の流れがわかったので、すぐにGeminiの呼び出しを止めて、対策に取りかかりました。
やった対策
- リクエストの間隔を必ず空ける:Geminiへのリクエストは毎回、前のリクエストから5秒以上空けて送ります。一番効いたのはこれです。エラーが出てから対処するのではなく、そもそも上限を超えないようにします
- 上限エラー(429)が返ってきたら、待ってから再試行する:1秒、2秒と待ち時間を延ばしながら、最大2回まで再試行します
- 再試行の二重化を直した:Laravelの
Http::retry()を使っていたところ、自分で書いた再試行と重なって、想定より多くリクエストが飛ぶことがわかりました。テストで呼び出し回数を数えて気づきました。HTTPクライアントの便利な再試行機能を使うときは、自分で書く再試行と重ならないよう注意が必要です
OpenAI APIへ移行した
対策は入れましたが、この経験から「無料枠の上限ぎりぎりで動かす作り」そのものに不安を感じました。そこで、タグ付けはOpenAI APIに移しました。有料でも、使う金額を自分で管理できるほうが安心だと考えたからです。
移行にあたって、最初から次のように作りました。
- 使っていい金額の上限を自分で設定する:累計・1日・1回ごとの上限を持たせ、超えたら自動で止まるようにしました
- 新着は少しずつ処理する:決まった間隔で、少量ずつ処理します
軽量なモデルでも十分な精度が出たので、費用は個人開発でも気にならない程度に収まっています。
この件で学んだこと
- 無料枠の上限は「1日の量」だけでなく「1分あたりの回数」もある:普段は余裕があっても、ある時間に集中すると簡単に超えます
- 外部APIには、エラーが出てからの対処より、出さないための間隔制御が大事:上限を超えてから止めるのでは遅いです
- APIの使用量を記録しておく:いつ、どの処理が何回呼んだかを残していたので、原因をすぐに突き止められました
- 使う前に利用規約と上限をきちんと読む:当たり前のことですが、動くものができると後回しにしがちでした
作ってよかったこと・今後
いちばんの利用者は、たぶん自分です。毎晩寝る前にサイトを開いて、配信中の一覧を眺めたり、ランダム再生に任せたりしています。YouTubeで探していたころより、聴きたいものにたどり着くまでの時間がずっと短くなりました。
「自分が欲しいものを作る」のは個人開発の王道ですが、毎日自分で使うので、使いにくいところにすぐ気づけるのがいいところです。気になったところを直して、また夜に使う。この繰り返しで、少しずつ良くなっています。
今後追加したい機能
- お気に入り機能の拡張:お気に入りにした配信者や動画を、もっと便利に使えるようにしたいです
- 配信者ページの拡張:配信者ごとの特徴や傾向が、ひと目でわかるページにしたいです
さいごに
ASMRを聴く人のための「探しやすい場所」を目指して、少しずつ育てています。
よかったら使ってみてください。
👉 ASMRまとめ [https://asmrmatome.com]