1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

YouTubeDataAPIを用いた複数チャンネルのライブ配信ステータス取得において、リクエストの上限制限を回避する

Posted at

概要

  • YouTubeDataAPIでは一日の上限Queries(呼び出し回数 × Cost)が制限されているため、「任意の配信者の動画一覧を取得し、その配信者が現在配信中の動画のリアルタイム情報(視聴者数など)を毎分APIを通して監視しよう」と考えるとすぐにAPI上限に達してしまう
  • YouTubeが公開しているRSSフィード用のURL経由で最新動画1件のvideo_idを調べ、そのidの動画情報のみをAPIを用いて取得することで、Queries上限に達しないよう節約している

使用環境

  • Rails 6.0.4.1
  • YouTube Data API v3
  • MariaDb Ver 15.1

データベース

配信者テーブル (streamers)

id title channel_code description
1 YouTubeアカウント名 チャンネルID チャンネル概要
2 27歳高学歴ニートさの UCmFq0wZGLfjtXdUINyOZ7hQ 毎日たのしく生きてたら大卒27歳職歴なしになってしまいました。
3 レンジの中に毒を持て UCfBjINK2PzS432RihFow99w ポーカーで生きる人間の業

動画テーブル (streamer_videos)

id streamer_id title video_code audience
1 外部キー 動画タイトル 動画ID 視聴者数
2 2 最速で慶應ロースクールに落ちました UbHSJapfMSAM 258
3 3 Piosolverと配信デート DfG32VJMZV0 1120

対応方針

以下のRSSフィード用URLを用いて最新動画の動画IDを取得することで、「任意の配信者の動画一覧を取得する」というフローのAPI実行を削減している

https://www.youtube.com/feeds/videos.xml?channel_id=チャンネルID

実装のイメージは以下です

本質的な処理だけ抽出しているので、実際のソースコードとは異なります。

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

    Streamer.all.each do |streamer|
      # YouTubeが公開しているRSSフィード用のURLは以下
      feed_url = "https://www.youtube.com/feeds/videos.xml?channel_id=#{streamer.channel_code}"
      xml = URI.open(feed_url)
      parsed_xml = Nokogiri::HTML.parse(xml, nil, 'utf-8')
      video_ids = parsed_xml.xpath('//entry/videoid').map{|v| v.text}

      # データベースに保存している最新動画と、RSSフィードで取得した最新動画を突き合わせる
      saved_latest = streamer.streamer_videos.order(created_at: :desc).first
      if saved_latest
        saved_index = video_ids.index(saved_latest.video_code)        
        # 最新動画がすでに保存されているアーカイブ動画である場合は無視
        next if saved_index == 0 && saved_latest.uploaded?
      end

      # 最新1件の動画に対して、動画情報を取得するAPI実行
      response = youtube.list_videos('snippet, liveStreamingDetails, contentDetails', {:id => video_ids[0]})
      video = StreamerVideo.find_or_initialize_by(video_code: response.items[0])

      if video.new_record?
        video.streamer_id = streamer.id
        video.title = r.snippet.title
        video.description = r.snippet.description
      end

      case r.snippet.live_broadcast_content
      when "live" then # ライブ配信中の動画は、ここで毎分視聴者数を取得して更新している
        video.video_type = "live"
        video.audience = r.live_streaming_details.concurrent_viewers.to_i
      when "none" then # ライブ配信ではない動画は、ここでデータを登録して以降処理を行わない
        video.video_type = "uploaded"
      end

      video.save!
    end
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?