LoginSignup
52
44

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-10-21

導入

下記の記事で、APIキーの取得など解説されているので、まずはそちらを参考にしてみてください
最近のGoogle API Ruby Clientを使ってYoutubeで動画を探してファイルとしてダウンロードする

Google APIをを触るための準備

API Keyの取得

  • Google API Consoleに行く
  • プロジェクトを作成する
    GenerateProgect1.png
    GenerateProject2.png

  • APIキーを取得する(プロジェクトを作成できればできています)
    GetNewAPIKey.png

  • Youtube Data APIを有効にする
    EnableYoutubeDataAPI.png

Google API Ruby Clientを使うための準備

google-api-ruby-clientはGoogleのAPIを触るための、Google謹製のRubyライブラリです。
0.8.x以降にて大幅な変更があり、ライブラリの使い方が大きく変更しています
Gemfileに記述する場合は

Gemfile
gem 'google-api-client', '~> 0.11'

Ruby on Railsで導入する場合は、下記の記事を参考にしてみてください
Railsでyoutube APIを使ってみた

gemについてのGithubはこちら

コマンド
$ bundle install

APIkeyをcredentials.ymlにセットする

以前に記事を作成しているので、こちらを参考にして、環境変数を定義しましょう
たった30分でわかるcredentials.yml.enc[rails5.2] - 環境変数を定義する使い方

クラスGoogle::Apis::YoutubeV3::YouTubeService

gem 'google-api-client'をインストールすることで利用できるようになったクラス。

参考リンクを翻訳しながら理解していきます。

GoogleのAPIを利用するには下記のように記述して、サービス名を指定します。

Google::Apis::~サービス名

サービスはたくさんあるので、詳しくみたい方は次のリンクを開いてください。
参考リンク

今回はYoutubV3を指定しています

require 'google/apis/youtube_v3' #YoutubeV3を使用するために、呼び出す

Google::Apis::YoutubeV3

このYoutubeV3にもたくさんのサービスがあり、今回はYouTubeServiceを利用します。

require 'google/apis/youtube_v3' #YoutubeV3を使用するために、呼び出す

Google::Apis::YoutubeV3::YouTubeService

このYouTubeServiceは、
動画のアップロード、プレイリストの作成と管理、コンテンツの検索など、YouTubeのコア機能をサポートします。

YouTubeServiceのクラスを利用するには、下記のように記述します

require 'google/apis/youtube_v3'

Youtube = Google::Apis::YoutubeV3::YouTubeService.new

これでクラスを作成し、インスタンスメソッドが継承される

Google::Apis::YoutubeV3::YouTubeServiceのGithubはこちら

インスタンス属性の概要

key ⇒ String

APIの秘密鍵を入れる

keyにAPIキーを定義
require 'google/apis/youtube_v3' #YoutubeV3を使用するために、呼び出す

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = "API KEY"
でkeyにAPIキーを環境変数で定義
require 'google/apis/youtube_v3' #YoutubeV3を使用するために、呼び出す

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

quota_user ⇒ String

サーバーサイドアプリケーションのクォータ目的で利用可能です. ユーザーに割り当てられた任意の文字列を指定することができますが、40文字を超えてはいけません。
(どうもあまり使っている例はないので、さほど重要ではなさそうです)

user_ip ⇒ String

非推奨です。代わりに quotaUser を使用してください。

補足でより理解する

class YouTubeService < Google::Apis::Core::BaseService

このGoogle::Apis::YoutubeV3::YouTubeServiceGoogle::Apis::Core::BaseServiceを継承している

なので、Google::Apis::Core::BaseServiceのメソッドやインスタンス属性も利用可能

Google::Apis::Core::BaseServiceのGithub

インスタンスメソッド list_〇〇〇

クラスGoogle::Apis::YoutubeV3::YouTubeServiceには、list_〇〇〇メソッドが用意されている。

基本の型
list_〇〇〇(part名, デフォルトのnilから変更したいオプションキー)

基本的にマニュアルページでlistがあるものは利用できます。
Channels:listの場合は、list_channels
searchs:listの場合は、list_searches
videos: listの場合は、list_videos

他にもあるので、一度Githubを確認しておきましょう!
githubはこちら

channels

Channels:listの場合のページには、チャンネル情報を取得できる。
これをRailsで取得するには、メソッドでlist_channels利用する

元のインスタンスメソッド
      def list_channels(part, category_id: nil, for_username: nil, hl: nil, id: nil, managed_by_me: nil, max_results: nil, mine: nil, my_subscribers: nil, on_behalf_of_content_owner: nil, page_token: nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:get, 'youtube/v3/channels', options)
          command.response_representation = Google::Apis::YoutubeV3::ListChannelsResponse::Representation
          command.response_class = Google::Apis::YoutubeV3::ListChannelsResponse
          command.query['categoryId'] = category_id unless category_id.nil?
          command.query['forUsername'] = for_username unless for_username.nil?
          command.query['hl'] = hl unless hl.nil?
          command.query['id'] = id unless id.nil?
          command.query['managedByMe'] = managed_by_me unless managed_by_me.nil?
          command.query['maxResults'] = max_results unless max_results.nil?
          command.query['mine'] = mine unless mine.nil?
          command.query['mySubscribers'] = my_subscribers unless my_subscribers.nil?
          command.query['onBehalfOfContentOwner'] = on_behalf_of_content_owner unless on_behalf_of_content_owner.nil?
          command.query['pageToken'] = page_token unless page_token.nil?
          command.query['part'] = part unless part.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

デフォルトがnilになっているので、

list_channels(part名必須, nilから変更したいオプション)と利用すれば良いでしょう。

使用できるpart

part名 情報
id --
snippet --
brandingSettings --
contentDetails --
invideoPromotion --
statistics --
topicDetails --

part パラメータには、API レスポンスに含める 1 つまたは複数の channel リソース プロパティをカンマ区切りリストの形式で指定します。このパラメータに指定できる part 名は id、snippet、 brandingSettings、 contentDetails、 invideoPromotion、 statistics、 topicDetails です。このパラメータに子プロパティを持つプロパティが指定されている場合、その子プロパティもレスポンスに含まれます。たとえば、channel リソースで、contentDetails プロパティに uploads プロパティなど、他のプロパティが含まれているとします。この場合、part=contentDetails と設定すると、API レスポンスには、これらのネストされたプロパティもすべて含まれることになります。

part例
youtube.list_channels("id", オプションキー)
youtube.list_channels("snippet", オプションキー)
youtube.list_channels("brandingSettings", オプションキー)
youtube.list_channels("contentDetails", オプションキー)
youtube.list_channels("invideoPromotion", オプションキー)
youtube.list_channels("statistics", オプションキー)
youtube.list_channels("topicDetails", オプションキー)

オプション

オプションは公式ガイドで解説

オプションに適切に承認されたリクエストでのみ使用できますと記述されている場合

そのアカウントでログイン認証が成功した場合のみ、確認が可能
つまり、他人のアカウント情報を確認できない。

フィルタ

レスポンス

{
  "kind": "youtube#channelListResponse", #list_channelsを利用していることがわかる
  "etag": etag,
  "nextPageToken": string,
  "prevPageToken": string,
  "pageInfo": {
    "totalResults": integer,
    "resultsPerPage": integer
  },
  "items": [
    チャンネル リソース #ここに取得したい情報一覧が表示
  ]
}
実例
{
  "kind": "youtube#channelListResponse",
  "etag": "kEY0ccyV8cSoyol7-OVNH4UXvKw",
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#channel",
      "etag": "WdLWGmqdwWdL0EWpqGLJ_eTOzjA",

      #portのidから得られる情報
      "id": "UCPyNsNSTUtywkekbDdCA_8Q", #portのidから得られる情報。この例では"youtubeチャンネルのid"を指定しているので、指定したチャンネルidが表示されている

      #portのsnippetから得られる情報
      "snippet": { #portのsnippetから得られる情報
        "title": "はなおでんがん",
        "description": "どうもおはえりすめんてん、はなおです。おはえりすめんてんは\nおはよう+ミカエリスメンテンの造語です。\nuuumっぽく無いですが、uuumです。uuumの闇担当です笑\n文系でも楽しめる理系動画をメインに\nいろいろやってます。編集には定評があります。チャンネル登録よろしくお願いしますψ(`∇´)ψ\n2017年6月1日急上昇1位、登録者増加数日本1位に輝きました!\n\n☆twitterフォローお願いします(^^)→https://twitter.com/hanao87_0",
        "customUrl": "はなおchannnel",
        "publishedAt": "2014-11-27T13:34:05Z",
        "thumbnails": {
          "default": {
            "url": "https://yt3.ggpht.com/a/AATXAJyJBq8uwiGgJMOUoj9iEsOZgzrZszNMwMPRi8C8HxU=s88-c-k-c0xffffffff-no-rj-mo",
            "width": 88,
            "height": 88
          },
          "medium": {
            "url": "https://yt3.ggpht.com/a/AATXAJyJBq8uwiGgJMOUoj9iEsOZgzrZszNMwMPRi8C8HxU=s240-c-k-c0xffffffff-no-rj-mo",
            "width": 240,
            "height": 240
          },
          "high": {
            "url": "https://yt3.ggpht.com/a/AATXAJyJBq8uwiGgJMOUoj9iEsOZgzrZszNMwMPRi8C8HxU=s800-c-k-c0xffffffff-no-rj-mo",
            "width": 800,
            "height": 800
          }
        },
        "localized": {
          "title": "はなおでんがん",
          "description": "どうもおはえりすめんてん、はなおです。おはえりすめんてんは\nおはよう+ミカエリスメンテンの造語です。\nuuumっぽく無いですが、uuumです。uuumの闇担当です笑\n文系でも楽しめる理系動画をメインに\nいろいろやってます。編集には定評があります。チャンネル登録よろしくお願いしますψ(`∇´)ψ\n2017年6月1日急上昇1位、登録者増加数日本1位に輝きました!\n\n☆twitterフォローお願いします(^^)→https://twitter.com/hanao87_0"
        }
      },

      #portのcontentDetailsから得られる情報
      "contentDetails": {
        "relatedPlaylists": {
          "likes": "",
          "favorites": "",
          "uploads": "UUPyNsNSTUtywkekbDdCA_8Q",
          "watchHistory": "HL",
          "watchLater": "WL"
        }
      },

      #portのstatisticsから得られる情報
      "statistics": {
        "viewCount": "757628049",
        "commentCount": "0",
        "subscriberCount": "1650000",
        "hiddenSubscriberCount": false,
        "videoCount": "628"
      },

      #portのtopicDetailsから得られる情報
      "topicDetails": {
        "topicIds": [
          "/m/02jjt",
          "/m/02jjt"
        ],

      #portのtopicCategoriesから得られる情報
        "topicCategories": [
          "https://en.wikipedia.org/wiki/Entertainment"
        ]
      },

      #portのbrandingSettingsから得られる情報
      "brandingSettings": {
        "channel": {
          "title": "はなおでんがん",
          "description": "どうもおはえりすめんてん、はなおです。おはえりすめんてんは\nおはよう+ミカエリスメンテンの造語です。\nuuumっぽく無いですが、uuumです。uuumの闇担当です笑\n文系でも楽しめる理系動画をメインに\nいろいろやってます。編集には定評があります。チャンネル登録よろしくお願いしますψ(`∇´)ψ\n2017年6月1日急上昇1位、登録者増加数日本1位に輝きました!\n\n☆twitterフォローお願いします(^^)→https://twitter.com/hanao87_0",
          "keywords": "はなおチャンネル はなおでんがんチャンネル はなおでんがん",
          "defaultTab": "Featured",
          "moderateComments": true,
          "showRelatedChannels": true,
          "showBrowseView": true,
          "featuredChannelsTitle": "サブちゃんっ!",
          "featuredChannelsUrls": [
            "UCYeEDmOpvEtnKM6KSSqC4UA"
          ],
          "unsubscribedTrailer": "7YfzRxQWuAQ",
          "profileColor": "#000000"
        },
        "image": {
          "bannerImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerTabletLowImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1138-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerTabletImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1707-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerTabletHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w2276-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerTabletExtraHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w2560-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileLowImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileMediumHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileExtraHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerTvImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
          "bannerTvLowImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
          "bannerTvMediumImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
          "bannerTvHighImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj"
        },
        "hints": [
          {
            "property": "channel.featured_tab.template.string",
            "value": "Everything"
          },
          {
            "property": "channel.modules.show_comments.bool",
            "value": "True"
          },
          {
            "property": "channel.banner.mobile.medium.image.url",
            "value": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj"
          }
        ]
      }
    }
  ]
}

実例

チャンネル名を取得(title)
チャンネル登録者数を取得(subscriberCount)
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :id => 'UCPyNsNSTUtywkekbDdCA_8Q' #YouTubeチャンネルのIDを指定
}

response = youtube.list_channels("snippet", options)

@channel_title = response[:items][0][:snippet][:title]

チャンネルアイコンを取得(icon)
チャンネル登録者数を取得(subscriberCount)
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :id => 'UCPyNsNSTUtywkekbDdCA_8Q' #YouTubeチャンネルのIDを指定
}

response = youtube.list_channels("snippet", options)

@channnel_icon = response[:items][0][:snippet][:thumbnails][:high]

チャンネル登録者数を取得
チャンネル登録者数を取得(subscriberCount)
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :id => 'UCPyNsNSTUtywkekbDdCA_8Q' #YouTubeチャンネルのIDを指定
}

response = youtube.list_channels("statistics", options)

@subscriberCount = response[:items][0][:statistics][:subscriberCount]

総閲覧数を取得(viewCount)
総閲覧数を取得(viewCount)
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :id => 'UCPyNsNSTUtywkekbDdCA_8Q' #YouTubeチャンネルのIDを指定
}

response = youtube.list_channels("statistics", options)

@viewCount = response[:items][0][:statistics][:viewCount]

searchs

searchs:listの場合
これをRailsで取得するには、メソッドlist_searchs利用する

元のインスタンスメソッド
def list_searches(part, channel_id: nil, channel_type: nil, event_type: nil, for_content_owner: nil, for_developer: nil, for_mine: nil, location: nil, location_radius: nil, max_results: nil, on_behalf_of_content_owner: nil, order: nil, page_token: nil, published_after: nil, published_before: nil, q: nil, region_code: nil, related_to_video_id: nil, relevance_language: nil, safe_search: nil, topic_id: nil, type: nil, video_caption: nil, video_category_id: nil, video_definition: nil, video_dimension: nil, video_duration: nil, video_embeddable: nil, video_license: nil, video_syndicated: nil, video_type: nil, fields: nil, quota_user: nil, options: nil, &block) 
           command = make_simple_command(:get, 'youtube/v3/search', options) 
           command.response_representation = Google::Apis::YoutubeV3::SearchListsResponse::Representation 
           command.response_class = Google::Apis::YoutubeV3::SearchListsResponse 
           command.query['channelId'] = channel_id unless channel_id.nil? 
           command.query['channelType'] = channel_type unless channel_type.nil? 
           command.query['eventType'] = event_type unless event_type.nil? 
           command.query['forContentOwner'] = for_content_owner unless for_content_owner.nil? 
           command.query['forDeveloper'] = for_developer unless for_developer.nil? 
           command.query['forMine'] = for_mine unless for_mine.nil? 
           command.query['location'] = location unless location.nil? 
           command.query['locationRadius'] = location_radius unless location_radius.nil? 
           command.query['maxResults'] = max_results unless max_results.nil? 
           command.query['onBehalfOfContentOwner'] = on_behalf_of_content_owner unless on_behalf_of_content_owner.nil? 
           command.query['order'] = order unless order.nil? 
           command.query['pageToken'] = page_token unless page_token.nil? 
           command.query['part'] = part unless part.nil? 
           command.query['publishedAfter'] = published_after unless published_after.nil? 
           command.query['publishedBefore'] = published_before unless published_before.nil? 
           command.query['q'] = q unless q.nil? 
           command.query['regionCode'] = region_code unless region_code.nil? 
           command.query['relatedToVideoId'] = related_to_video_id unless related_to_video_id.nil? 
           command.query['relevanceLanguage'] = relevance_language unless relevance_language.nil? 
           command.query['safeSearch'] = safe_search unless safe_search.nil? 
           command.query['topicId'] = topic_id unless topic_id.nil? 
           command.query['type'] = type unless type.nil? 
           command.query['videoCaption'] = video_caption unless video_caption.nil? 
           command.query['videoCategoryId'] = video_category_id unless video_category_id.nil? 
           command.query['videoDefinition'] = video_definition unless video_definition.nil? 
           command.query['videoDimension'] = video_dimension unless video_dimension.nil? 
           command.query['videoDuration'] = video_duration unless video_duration.nil? 
           command.query['videoEmbeddable'] = video_embeddable unless video_embeddable.nil? 
           command.query['videoLicense'] = video_license unless video_license.nil? 
           command.query['videoSyndicated'] = video_syndicated unless video_syndicated.nil? 
           command.query['videoType'] = video_type unless video_type.nil? 
           command.query['fields'] = fields unless fields.nil? 
           command.query['quotaUser'] = quota_user unless quota_user.nil? 
           execute_or_queue_command(command, &block) 
         end 

デフォルトがnilになっているので、

list_searches(part, nilから変更したいオプション)と利用すれば良いでしょう。

使用できるpart

part名 情報
id --
snippet --

part パラメータには、API レスポンスに含める 1 つまたは複数の search リソースのプロパティをカンマ区切りリストの形式で指定します。このパラメータに指定できる part 名は id と snippet です。

このパラメータに子プロパティを持つプロパティが指定されている場合、その子プロパティもレスポンスに含まれます。たとえば、search の結果では、snippet プロパティには、結果のタイトルや説明などを識別する別のプロパティが含まれます。この場合、part=snippet と設定すると、API レスポンスには、ネストされているプロパティもすべて含まれることになります。

part例
youtube.list_searches("id", オプションキー)
youtube.list_searches("snippet", オプションキー)
レスポンス
{
  "kind": "youtube#searchListResponse", #ここでlist_searchesを利用していることがわかる
  "etag": etag,
  "nextPageToken": string,
  "prevPageToken": string,
  "pageInfo": {
    "totalResults": integer,
    "resultsPerPage": integer
  },
  "items": [
    検索リソース
  ]
}
portsがidの場合
{
  "kind": "youtube#searchListResponse",
  "etag": "LvvBU1w1wIcopnyguJvHCsjcfiU",
  "nextPageToken": "CAEQAA",
  "regionCode": "JP",
  "pageInfo": {
    "totalResults": 656,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "qxByuq8_-FH49yZF8MSHKK-b5lA",
      #idしか得られていない
      "id": {
        "kind": "youtube#video",
        "videoId": "E69J8_CyuWo"
      }
    }
  ]
}
portsがsnippetの場合
{
  "kind": "youtube#searchListResponse",
  "etag": "vF-cucsIawV9-XYHVe_HDOX5X64",
  "nextPageToken": "CAEQAA",
  "regionCode": "JP",
  "pageInfo": {
    "totalResults": 656,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "JIYYfrcpdz_hJ5uGqaeeqal5n3s",
      "id": {
        "kind": "youtube#video",
        "videoId": "E69J8_CyuWo"
      },
      #snippetの項目があり、動画のタイトルなどの情報がある
      "snippet": {
        "publishedAt": "2020-07-23T11:02:06Z",
        "channelId": "UCPyNsNSTUtywkekbDdCA_8Q",
        "title": "「車で東京行こ?」ペーパードライバーの後輩がアルファードで拉致して東京まで運転するドッキリで車内ガチギレ大発狂wwwwwwww",
        "description": "練習中、2回くらい死にかけました ((( ))) 編集:マコ チャンネル登録お願いします! ○はなおのtwitter→ https://twitter.com/hanao87_0 ○でんがんのtwitter→ ...",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/E69J8_CyuWo/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/E69J8_CyuWo/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/E69J8_CyuWo/hqdefault.jpg",
            "width": 480,
            "height": 360
          }
        },
        "channelTitle": "はなおでんがん",
        "liveBroadcastContent": "none",
        "publishTime": "2020-07-23T11:02:06Z"
      }
    }
  ]
}

オプション

list_searchesのオプジョン
list_searches(part, channel_id: nil, channel_type: nil, event_type: nil, for_content_owner: nil, for_developer: nil, for_mine: nil, location: nil, location_radius: nil, max_results: nil, on_behalf_of_content_owner: nil, order: nil, page_token: nil, published_after: nil, published_before: nil, q: nil, region_code: nil, related_to_video_id: nil, relevance_language: nil, safe_search: nil, topic_id: nil, type: nil, video_caption: nil, video_category_id: nil, video_definition: nil, video_dimension: nil, video_duration: nil, video_embeddable: nil, video_license: nil, video_syndicated: nil, video_type: nil, fields: nil, quota_user: nil, user_ip: nil, options: nil)

このオプションは大量にあるので、必要な分optionに定義して、省略する

通常
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = "API KEY"
youtube_search_list = youtube.list_searches("id,snippet", type: "video", q: "キーワード", max_results: 50)
list_searchesのオプションを定義して省略
require 'google/apis/youtube_v3'
option = {
    q: keyword,
    type: 'video',
    max_results: 2,
    order: :date,
    page_token: next_page_token,
    published_after: after.iso8601,
    published_before: before.iso8601
  }
response = youtube.list_searches(:snippet, option)


youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = "API KEY"
youtube_search_list = youtube.list_searches(:snippet, option)

それぞれのオプションの解説はこちら

オプションに適切に承認されたリクエストでのみ使用できますと記述されている場合

そのアカウントでログイン認証が成功した場合のみ、確認が可能
つまり、他人のアカウント情報を確認できない。

実例

動画のURLを取得する
動画のURLを作成する
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :channelId => 'UCPyNsNSTUtywkekbDdCA_8Q', #YouTubeチャンネルのIDを指定
  :order => "date"
}

response = youtube.list_searches(:id, options)

video_id = response[:items][0][:id][:videoId]
@video_url = "https://www.youtube.com/watch?v=#{video_id}"

動画タイトルを取得する
動画タイトルを取得する
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :channelId => 'UCPyNsNSTUtywkekbDdCA_8Q', #YouTubeチャンネルのIDを指定
  :order => "date"                          #日付順で動画を取得
}

response = youtube.list_searches(:snippet, options)

@video_title = response[:items][0][:snippet][:title]

動画サムネイル画像を取得する
動画タイトルを取得する
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :channelId => 'UCPyNsNSTUtywkekbDdCA_8Q', #YouTubeチャンネルのIDを指定
  :order => "date"                          #日付順で動画を取得
}

response = youtube.list_searches(:snippet, options)

@video_image = response[:items][0][:snippet][:thumbnails][:high]

YouTubeチャンネルのURLを取得する
YouTubeチャンネルURLを取得する
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

keyword = "はなおでんがん" #実際には検索フォームで取得するが、今回は例として”はなおでんがん”をセット
options = {
  :q => keyword,   #キーワード検索している想定
  :order => "date" #日付順で動画を取得
}

response = youtube.list_searches("id, snippet", options)

channel_id = response[:items][0][:snippet][:channelId]
@channel_url = "https://www.youtube.com/channel/#{channel_id}" #aタグに挿入するURL
@channel_title = response[:items][0][:channelTitle]            #aタグのテキスト用
その他
実例
require 'google/apis/youtube_v3'
require 'active_support/all'

GOOGLE_API_KEY="<API_KEY>" #上記で作成したキー

def find_videos(keyword, after: 1.months.ago, before: Time.now) #検索キーワードと検索範囲を変えれるように引数に値を取っています
  service = Google::Apis::YoutubeV3::YouTubeService.new
  service.key = GOOGLE_API_KEY
  next_page_token = nil
  opt = {
    q: keyword,
    type: 'video',
    max_results: 2,
    order: :date,
    page_token: next_page_token,
    published_after: after.iso8601,
    published_before: before.iso8601
  }
  results = service.list_searches(:snippet, opt)
  results.items.each do |item|
    id = item.id
    snippet = item.snippet
    puts "\"#{snippet.title}\" by #{snippet.channel_title} (id: #{id.video_id}) (#{snippet.published_at})"
  end
end

find_videos('明日香ちゃんねる')

subscriptions

Subscriptions: listの場合
これをRailsで取得するには、メソッドlist_subscriptions利用する

使用できるpart

part名 情報
id --
snippet part=snippet と設定すると、API レスポンスには、ネストされているプロパティもすべて含まれることになります。
contentDetails --
partの例
youtube.list_videos("id", オプションキー)
youtube.list_videos("snippet", オプションキー)
youtube.list_videos("contentDetail", オプションキー)

このパラメータに子プロパティを持つプロパティが指定されている場合、その子プロパティもレスポンスに含まれます。たとえば、subscription リソースの snippet プロパティに、登録チャンネルの表示タイトルなど、他のプロパティが含まれているとします。この場合、part=snippet と設定すると、API レスポンスには、ネストされているプロパティもすべて含まれることになります。

オプション

オプションに適切に承認されたリクエストでのみ使用できますと記述されている場合

そのアカウントでログイン認証が成功した場合のみ、確認が可能
つまり、他人のアカウント情報を確認できない。

videos

videos: listの場合
これをRailsで取得するには、メソッドlist_videos利用する

使用できるpart

part名 情報
id --
snippet part=snippet と設定すると、API レスポンスにはこれらのプロパティすべてが含まれることになります。

このパラメータに子プロパティを持つプロパティが指定されている場合、その子プロパティもレスポンスに含まれます。たとえば、video リソースで、snippet プロパティに channelId、title、description、tags、categoryId などのプロパティが含まれているとします。この場合、part=snippet と設定すると、API レスポンスにはこれらのプロパティすべてが含まれることになります。

partの例
youtube.list_videos("id", オプションキー)
youtube.list_videos("snippet", オプションキー)
youtube.list_videos("contentDetail", オプションキー)
youtube.list_videos("fileDetailsn", オプションキー)
youtube.list_videos("liveStreamingDetails", オプションキー)
youtube.list_videos("player", オプションキー)
youtube.list_videos("processingDetails", オプションキー)
youtube.list_videos("recordingDetails", オプションキー)
youtube.list_videos("statistics", オプションキー)
youtube.list_videos("status", オプションキー)
youtube.list_videos("recordingDetails", オプションキー)
youtube.list_videos("suggestions", オプションキー)

オプション

list_videosのオプジョン
list_videos(part, chart: nil, hl: nil, id: nil, locale: nil, max_height: nil, max_results: nil, max_width: nil, my_rating: nil, on_behalf_of_content_owner: nil, page_token: nil, region_code: nil, video_category_id: nil, fields: nil, quota_user: nil, user_ip: nil, options: nil) 

このオプジョンが長いのでoptionを定義して、省略している例

optionを定義して省略
options = {
  :id => 'xftKTwxb5oE'
}

response = youtube.list_videos("statistics", options)

オプションに適切に承認されたリクエストでのみ使用できますと記述されている場合

そのアカウントでログイン認証が成功した場合のみ、確認が可能
つまり、他人のアカウント情報を確認できない。

実例

参考資料:Google:Auth

require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'google/apis/youtube_v3'

OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
APPLICATION_NAME = 'idolsongplaylist'
CLIENT_SECRETS_PATH = 'client_secret.json'
CREDENTIALS_PATH = File.join(Dir.home, '.credentials', "tokens.yaml")
SCOPE = [ "https://www.googleapis.com/auth/youtube" ]

# 認証メソッド
def authorize
  FileUtils.mkdir_p(File.dirname(CREDENTIALS_PATH))

  client_id = Google::Auth::ClientId.from_file(CLIENT_SECRETS_PATH)
  token_store = Google::Auth::Stores::FileTokenStore.new(file: CREDENTIALS_PATH)
  authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, token_store)
  user_id = 'default'
  credentials = authorizer.get_credentials(user_id)
  if credentials.nil?
    url = authorizer.get_authorization_url(base_url: OOB_URI)
    puts 'Open the following URL in the browser and enter the ' +
         'resulting code after authorization'
    puts url
    code = gets
    credentials = authorizer.get_and_store_credentials_from_code(
      user_id: user_id, code: code, base_url: OOB_URI)
  end
  credentials
end

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.client_options.application_name = APPLICATION_NAME #Google::Apis::Core::BaseServiceから継承したメソッド
youtube.authorization = authorize #作成したauthorizeメソッドを実施

options = {
  :id => 'xftKTwxb5oE'
}

response = youtube.list_videos("statistics", options)
pp response

参考:Ruby で YouTube Data API (v3) を使う

これらのメソッドまとめページはこちら

参考リンク

最近のGoogle API Ruby Clientを使ってYoutubeで動画を探してファイルとしてダウンロードする
Railsでyoutube APIを使ってみた
Ruby で YouTube Data API (v3) を使う
Youtubeのチャンネル登録者数を取得する
メソッド一覧
RubyとPythonでGoogle APIを叩いてみた − データベースをSpreadsheetにしてGoogle Driveで管理する

52
44
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
52
44