なかなか面倒でした。
URLの種類
以下の動画を例とします。
普通のURL
https://www.youtube.com/watch?v=ngNhpdaT5V0
普通のURL+時間情報
https://www.youtube.com/watch?v=ngNhpdaT5V0&t=45s
短縮URL
短縮URL+時間情報
https://youtu.be/ngNhpdaT5V0?t=45
埋め込みURL
https://www.youtube.com/embed/ngNhpdaT5V0
埋め込みURL+時間情報
https://www.youtube.com/embed/ngNhpdaT5V0?start=45
プレイリスト内の動画
https://www.youtube.com/watch?v=ngNhpdaT5V0&list=PLxai42gkPeMN1nTZFD4PEc96sMI8mdT03&index=3
URL種類の解説
大きく分けて2種類です。
1つめはvideo idがパラメータとして与えられている場合です。
2つめはvideo idがbasenameとして与えられている場合です。
パラメータの場合
以下の機能を使って取り出せます。こちらは素直に取り出せます。
const {URL} = require("url"); const url = "https://www.youtube.com/watch?v=ngNhpdaT5V0"; const urlObj = new URL(url); const videoId = urlObj.searchParams.get("v"); console.log(videoId);
basenameの場合
こちらは複数ライブラリを複合して使う必要があります。
pathのbasenameを使うとパラメータも連結されたままになってしまいます。
urlのpathnameを使うといい感じに思えますが、埋め込みURLの場合にidだけでなくembed/もついてきてしまいます。
色々試した結果、pathnameに対してbasenameを適用すると抜き出せました。
const {URL} = require("url"); const path = require("path"); const url = "https://www.youtube.com/embed/ngNhpdaT5V0?start=45"; const urlObj = new URL(url); const videoId = path.basename(urlObj.pathname); console.log(videoId);
〆
実際に使う場合は、ホストチェックをしてyoutube urlであることを確認したうえで、basenameがwatchであることかパラメータにvがあることかを使って振り分けるのが良いでしょう。
最初はyoutu.beかyoutube.comで振り分ければいい気がしていましたが、embed/が盲点でした。 また別の話ですが、www.youtube.comでもyoutube.comでも開けてしまったりします。めんどくさい...