🧐

YouTubeに公開されている動画を推しメンで検索できるサービスを作りました

2022/06/18に公開

概要

先日、乃木坂46の公式YouTubeチャンネルである、「乃木坂配信中」の動画をメンバーを選択して検索できるサービスを公開しました!
見たい動画をクリックするとYouTubeへ遷移します。

この記事は主に、使用したYouTubeAPIについてまとめました。

https://github.com/kngy0306/NogiFil

動機

乃木坂配信中チャンネルは、2022年6月時点で、200本以上の動画が公開されています。
あのメンバーが出ている動画が見たい!と思ったときに、簡単に探せるサービスがあれば良いなと考え制作しました。

構成

フロントエンドはTypeScript, Reactを使用しています。
バックエンドはPHP, Laravelを使用しています。
データベースはMySQLを使用しています。
YouTubeから動画を取得するのはYouTube Data API v3を使用しています。

フロントエンドはVercelにデプロイし、バックエンドはHerokuにデプロイしています。

構成図は以下のようになっています。

サービス構成図

機能

サービスにアクセスすると、最初はすべての動画を表示するようにしています。画面上部にあるプルダウンメニューからメンバーを選択することで、選択したメンバーが出演している動画のみが表示されるようになっています。

top
TOP画面

select_member
メンバー選択時

メンバーが選択されると、Laravelで作成したAPIサーバへアクセスし、データベースに保存している動画データをフロントへ返すようになっています。
データベースにある動画データは、定期的にYouTubeAPIを使用して更新しています。

YouTubeAPI

データベースへ動画データを保存するときは、以下の処理を行っています。

  1. YouTubeから動画を取得
  2. 必要なデータに整形しデータベースへ保存

YouTubeから動画を取得

YouTubeAPIにはさまざまなリソースがあり、一覧を以下から確認できます。

https://developers.google.com/youtube/v3/docs

本サービスはSearchリソースとVideosリソースを使用しています。
Searchリソースでチャンネルに公開されている動画を複数取得し、取得したそれぞれの動画詳細をVideosリソースでさらに取得、という流れになっています。

2つのリソースを使用している理由は、Searchリソースでは動画概要欄を1000文字以下しか取得できないためです。本サービスはメンバーが動画に出演しているかどうかを動画概要欄のタグから判断しています。そのため動画概要欄を全文取得する必要がありましたが、上記理由からVideosリソースも合わせて使用しています。Videosリソースであれば動画概要欄を全文取得することが可能です。

Searchリソースで以下のように実行することで、乃木坂配信中で公開されている動画の中から、最新の動画を1件取得できます。

Searchリソースで最新の動画を1件取得
$ curl -s "https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCfvohDfHt1v5N8l3BzPRsWQ&order=date&maxResults=1&key=自身のAPIKey" | jq .
{
  "kind": "youtube#searchListResponse",
  "etag": "KrTPKro8yrbB07a0BGJifVMsh0E",
  "nextPageToken": "CAEQAA",
  "regionCode": "JP",
  "pageInfo": {
    "totalResults": 323,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "tr8NzsWwvpKsIy0Gkr5wyX9TX0Y",
      "id": {
        "kind": "youtube#video",
        "videoId": "6MMV8QYEsJM"
      },
      "snippet": {
        "publishedAt": "2022-06-14T09:02:19Z",
        "channelId": "UCfvohDfHt1v5N8l3BzPRsWQ",
        "title": "プロスピ直後の2人をお届け!「プロスピやってみた!」動画ぜひご覧ください♪ #shorts",
        "description": "「プロスピやってみた!」 https://youtu.be/je592lVTZU0 #shorts #プロ野球 #プロ野球スピリッツ #プロスピ #ゲーム実況 #黒見 ...",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/6MMV8QYEsJM/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/6MMV8QYEsJM/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/6MMV8QYEsJM/hqdefault.jpg",
            "width": 480,
            "height": 360
          }
        },
        "channelTitle": "乃木坂配信中",
        "liveBroadcastContent": "none",
        "publishTime": "2022-06-14T09:02:19Z"
      }
    }
  ]
}

上記のSearchリソースの結果から取得できるvideoIdを使用して、Videosリソースを実行することで動画の詳細を取得できます。

Videosリソースで動画の詳細を取得
$ curl -s "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=6MMV8QYEsJM&key=自身のAPIKey" | jq .
{
  "kind": "youtube#videoListResponse",
  "etag": "bbsw16MK3fbOjy8ZgZ705MNg2cw",
  "items": [
    {
      "kind": "youtube#video",
      "etag": "Efvr2Z_vkeec8Aq7VJKvHWoe2QA",
      "id": "6MMV8QYEsJM",
      "snippet": {
        "publishedAt": "2022-06-14T09:02:19Z",
        "channelId": "UCfvohDfHt1v5N8l3BzPRsWQ",
        "title": "プロスピ直後の2人をお届け!「プロスピやってみた!」動画ぜひご覧ください♪ #shorts",
        "description": "■「プロスピやってみた!」\nhttps://youtu.be/je592lVTZU0\n\n#shorts #プロ野球 #プロ野球スピリッツ #プロスピ #ゲーム実況 #黒見明香 #柴田柚菜 #乃木坂46 #乃木坂配信中",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/6MMV8QYEsJM/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/6MMV8QYEsJM/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/6MMV8QYEsJM/hqdefault.jpg",
            "width": 480,
            "height": 360
          },
          "standard": {
            "url": "https://i.ytimg.com/vi/6MMV8QYEsJM/sddefault.jpg",
            "width": 640,
            "height": 480
          },
          "maxres": {
            "url": "https://i.ytimg.com/vi/6MMV8QYEsJM/maxresdefault.jpg",
            "width": 1280,
            "height": 720
          }
        },
        "channelTitle": "乃木坂配信中",
        "categoryId": "24",
        "liveBroadcastContent": "none",
        "defaultLanguage": "ja",
        "localized": {
          "title": "プロスピ直後の2人をお届け!「プロスピやってみた!」動画ぜひご覧ください♪ #shorts",
          "description": "■「プロスピやってみた!」\nhttps://youtu.be/je592lVTZU0\n\n#shorts #プロ野球 #プロ野球スピリッツ #プロスピ #ゲーム実況 #黒見明香 #柴田柚菜 #乃木坂46 #乃木坂配信中"
        },
        "defaultAudioLanguage": "ja"
      }
    }
  ],
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 1
  }
}


Searchリソースでは省略されていた動画概要欄(description)が、

"description": "「プロスピやってみた!」 https://youtu.be/je592lVTZU0 #shorts #プロ野球 #プロ野球スピリッツ #プロスピ #ゲーム実況 #黒見 ..."

Videosリソースでは全文取得できています。

"description": "■「プロスピやってみた!」\nhttps://youtu.be/je592lVTZU0\n\n#shorts #プロ野球 #プロ野球スピリッツ #プロスピ #ゲーム実況 #黒見明香 #柴田柚菜 #乃木坂46 #乃木坂配信中"

必要なデータに整形しデータベースへ保存

Videosリソースで取得した動画概要欄から#で始まる文字列を抜き出し、それがメンバーの名前ならその動画に出演しているメンバーとしてデータベースへ保存してます。

今後

現状、動画を見るときはYouTubeへ遷移するようになっていますが、今後はサイト内で動画を再生できるようにしたいと考えています。

GitHubで編集を提案

Discussion