🎥

【Rails】YouTube Data APIを使用し動画情報を取得

2023/08/16に公開

YouTube Data APIを使用して、動画情報(サムネイル、動画タイトル、視聴回数、公開日)を取得する。

はじめに

流れは次の通り。

  1. YouTube Data APIの登録
  2. gem:google-api-client の設定
  3. APIキーの取得と設定
  4. APIを利用してビューの表示

YouTube Data APIの登録・gem:google-api-client の設定

  1. YouTube Data APIの登録
    最初にYouTube Data APIにアクセスするために、Google Cloud PlatformでAPIキーを取得する必要がある。APIを有効にして、アプリケーションがYouTubeのデータにアクセスできるようになる。

  2. gem:google-api-client の設定
    gem:google-api-clientはGoogle APIを使用するためのライブラリ。これをアプリケーションに統合して設定することで、YouTube Data APIとのやり取りが可能になる。

それぞれ以下の記事がわかりやすかったので参照ください。

【Ruby on Rails】最もわかりやすいYouTube API 使い方

Gemfileを設定する際はバージョンに注意。

APIキーの取得と設定

  1. APIキーの取得と設定
    Google Cloud Platformから取得したAPIキーをアプリケーションに設定する。

今回はヘルパーを使用して実装する。それぞれの目的は以下の通り。

モジュール メソッド 目的
ApplicationHelper extract_youtube_video_id(link) YouTubeの動画リンクからビデオIDを抽出。ビデオIDをリンクから取得する。
ThumbnailHelper youtube_thumbnail(video_id, options = {}) YouTubeのビデオIDを基に、サムネイル画像や関連データを取得して表示する。

ApplicationHelperの設定

app/helpers/application_helper.rb
module ApplicationHelper
  # YouTubeの動画リンクからビデオIDを抽出するメソッド
  def extract_youtube_video_id(link)
    # もしリンクが提供されていない場合、ビデオIDは存在しないので nil を返す
    return nil if link.nil?
    
    # URLを解析してビデオIDを取得する
    uri = URI(link)  # リンクのURLをURIオブジェクトに変換
    query = URI.decode_www_form(uri.query)  # URLのクエリパラメータをデコードして取得
    query_hash = Hash[query]  # クエリパラメータをハッシュに変換
    query_hash["v"]  # ハッシュからキー"v"に対応する値、ビデオIDを返す
  end
end

上述を設定することで、YouTube動画リンクからビデオIDを取り出すことができる。

ThumbnailHelperの設定

以下のファイルを新規作成し、記述する。

app/helpers/thumbnail_helper.rb
module ThumbnailHelper
  def youtube_thumbnail(video_id, options = {})
    require 'google/apis/youtube_v3'
    
    options = { show_info: true }.merge(options)

    # キャッシュの設定を変更する
    Rails.cache.fetch("youtube_thumbnail_#{video_id}", expires_in: 1.day) do
      service = Google::Apis::YoutubeV3::YouTubeService.new
      service.key = ENV['YOUTUBE_API_KEY']

      # ビデオの詳細情報(snippet, statistics)を取得
      video_response = service.list_videos('snippet,statistics', id: video_id)
      video_item = video_response.items.first

      if video_item
        thumbnail_url = video_item.snippet.thumbnails.maxres.url
        title = video_item.snippet.title
        view_count = video_item.statistics&.view_count || 'N/A'  # nil の場合に 'N/A' をセット
        upload_date = video_item.snippet.published_at.to_date.strftime('%Y/%m/%d')

        content = content_tag(:div, class: 'text-center') do
          image_tag(thumbnail_url, alt: title, **options) +
          if options[:show_info]
            content_tag(:div, class: 'video-info') do
              content_tag(:p, raw("#{title}<br>#{number_with_delimiter(view_count)} views #{upload_date}"))
            end
          end
        end

        content
      else
        # ビデオが見つからない場合の処理をここに記述
        content_tag(:div, "Video not found", class: 'text-center')
      end
    end
  end
end

解説
上記のコードでやっていることは以下の通り。

  1. google-api-clientというGemを使って、YouTubeのAPIを使えるように準備。
  2. 表示する情報のオプションを設定。デフォルト表示にプラスして、必要に応じて表示内容を変更できるようにする。
  3. キャッシュを使って、ビデオ情報を一定期間保存する。これにより、同じビデオに対するリクエストが頻繁に行われても、APIへのリクエストが節約される。使用制約があるので重要。
  4. YouTubeのAPIを使用して、ビデオの詳細情報を取得する。
  5. その情報を使って、サムネイル画像やビデオの情報をHTMLコンテンツとして生成する。情報の表示が不要な場合は、オプションを指定することで非表示にできる。
  6. 動画が見つからないエラーは頻発するため、その時の処理の記載は必須。

APIキーは環境変数に入れ、情報漏洩しないよう注意すること

ビューでの呼び出し

  1. APIを利用してビューの表示:
    youtube_thumbnailメソッドを使用して、YouTubeビデオIDに基づいて動画のサムネイルとその他の情報を取得し、ビューに表示する。表示する情報は、サムネイル画像、タイトル、再生回数、アップロード日を今回は指定した。

ヘルパーを呼び出す記載をしていく。

post/showページ

html
:
<!-- YouTubeカラムの始まり -->
<div class="col-md-8 justify-content-center">
  <!-- ここからはYouTube動画のリンクを取得する部分 -->
  <% video_id = extract_youtube_video_id(@post.link) %>
  
  <!-- リンクをクリックすると新しいウィンドウまたはタブで開かれるリンクを作成 -->
  <%= link_to @post.link, target: "_blank" do %>
    <!-- YouTube動画のサムネイルと情報を表示する部分 -->
    <%= youtube_thumbnail(video_id, size: '1280x720', style: 'width: 80%; height: auto;') %>
  <% end %>
  
  <!-- 見出しを表示 -->
  <h1><%= @title %></h1>
</div>
<!-- YouTubeカラムの終わり -->
:

解説

  • サムネイルサイズは 1280x720で取得することで高画質のサムネイル表示ができる。styleで表示サイズを調整。
  • `target: "_blank"を設定することで、リンクが新しいウィンドウ、もしくはタブで開き表示することができる。

以下のように表示される。

indexページ

<% posts.each_slice(3) do |post_group| %>
  <div class="list-group-item">
    <% post_group.each do |post| %>
      <% video_id = extract_youtube_video_id(post.link) %>
      <!-- video_idが存在しない場合はスキップ -->
      <% next unless video_id.present? %>

      <!-- 各投稿のリンクを作成 -->
      <%= link_to post_path(post) do %>
        <!-- YouTube動画のサムネイルを表示 -->
        <%= youtube_thumbnail(video_id, size: '1280x720', style: 'width: 250px; height: auto;', show_info: false) %>
      <% end %>
    <% end %>
  </div>
<% end %>

解説
showページではサムネイルと動画情報をを取得したことに対し、indexではサムネイルだけを取得している。
表示オプションとしてshow_info: falseを指定しているため、動画情報は表示されないようになる。

Discussion