module VideoInfo::Providers::YoutubeScraper

Constants

BASE_URL
CHANNEL_URL
THUMB_DEFAULT_SIZE

Public Instance Methods

author() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 21
def author
  meta_node_value(channel_meta_nodes, "og:title")
end
author_thumbnail() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 25
def author_thumbnail
  image_hq_url = meta_node_value(channel_meta_nodes, "og:image")

  resize_thumb(image_hq_url, THUMB_DEFAULT_SIZE)
end
author_url() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 39
def author_url
  URI.join(CHANNEL_URL, channel_id).to_s
end
available?() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 11
def available?
  !!title
end
channel_id() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 31
def channel_id
  # NOTE the previous implementation, based on itemprop_node_value("channelId"),
  # does not work well, probably due to some YouTube change
  page_content = data.to_s
  matches = page_content.match(/"channelId":"([a-zA-Z0-9_-]+)"/)
  matches[1] if matches
end
date() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 15
def date
  date = itemprop_node_value("datePublished")

  Time.parse(date) if date
end
description() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 43
def description
  meta_node_value(video_meta_nodes, "og:description")
end
duration() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 47
def duration
  duration = itemprop_node_value("duration")

  if duration
    ISO8601::Duration.new(duration).to_seconds.to_i
  else
    0
  end
end
keywords() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 57
def keywords
  return unless available?

  value = meta_node_value(video_meta_nodes, "keywords")

  value&.split(", ")
end
stats() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 74
def stats
  {
    "viewCount" => view_count
  }
end
title() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 65
def title
  return if meta_node_value(video_meta_nodes, "title").empty?
  meta_node_value(video_meta_nodes, "title")
end
view_count() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 70
def view_count
  itemprop_node_value("interactionCount").to_i
end

Private Instance Methods

_api_url() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 125
def _api_url
  uri = URI.parse(@url)

  unless uri.scheme
    uri.path = uri.path.prepend("//")
  end

  uri.scheme = "https"

  uri.to_s
end
_set_data_from_api_impl(api_url) click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 114
def _set_data_from_api_impl(api_url)
  # handle fullscreen video URLs
  if url.include?(".com/v/")
    video_id = url.split("/v/")[1].split("?")[0]
    new_url = "https://www.youtube.com/watch?v=" + video_id
    Oga.parse_html(URI.parse(new_url).read)
  else
    Oga.parse_html(URI.parse(api_url).read)
  end
end
channel_data() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 90
def channel_data
  @channel_data ||= Oga.parse_html(URI.parse(author_url).read)
end
channel_meta_nodes() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 86
def channel_meta_nodes
  @channel_meta_nodes ||= channel_data.css("meta")
end
itemprop_node_value(name) click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 103
def itemprop_node_value(name)
  node = video_meta_nodes.detect do |m|
    itemprop_attr = m.attr("itemprop")

    itemprop_attr.value == name if itemprop_attr
  end

  return unless node
  node.attr("content").value
end
meta_node_value(meta_nodes, name) click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 94
def meta_node_value(meta_nodes, name)
  node = meta_nodes.detect do |n|
    n.attr("name")&.value == name || n.attr("property")&.value == name
  end

  return unless node
  node&.attr("content") && node.attr("content").value
end
video_meta_nodes() click to toggle source
# File lib/video_info/providers/youtube_scraper.rb, line 82
def video_meta_nodes
  @video_meta_nodes ||= data.css("meta")
end