module Yt::Annotations::For

Provides a method to fetch annotations and cards for a YouTube video.

Public Instance Methods

for(video_id) click to toggle source

@param [String] video_id the unique ID of a YouTube video. @return [Array<Yt::Annotation>] the annotations/end cards of the video.

# File lib/yt/annotations/for.rb, line 20
def for(video_id)
  (annotations(video_id) + end_screens(video_id)).sort_by(&:starts_at)
end

Private Instance Methods

annotation_class(data) click to toggle source
# File lib/yt/annotations/for.rb, line 57
def annotation_class(data)
  case data['style']
    when 'anchored', 'speech' then Annotations::Speech
    when 'branding' then Annotations::Branding
    when 'highlightText' then Annotations::Spotlight
    when 'label' then Annotations::Label
    when 'popup' then Annotations::Note
    when 'title' then Annotations::Title
    else case data['type']
      when 'card' then Annotations::Card
      when 'pause' then Annotations::Pause
      when 'promotion' then Annotations::Promotion
    end
  end
end
annotations(video_id) click to toggle source
# File lib/yt/annotations/for.rb, line 26
def annotations(video_id)
  data = fetch "/annotations_invideo?video_id=#{video_id}"
  xml_to_annotations(Hash.from_xml data)
end
end_screens(video_id) click to toggle source
# File lib/yt/annotations/for.rb, line 31
def end_screens(video_id)
  data = fetch "/get_endscreen?v=#{video_id}"
  data = data.partition("\n").last
  data.present? ? json_to_annotations(JSON data) : []
end
exclude_drawers(annotations) click to toggle source
# File lib/yt/annotations/for.rb, line 73
def exclude_drawers(annotations)
  annotations.reject{|a| a['type'] == 'drawer'}
end
fetch(path) click to toggle source
# File lib/yt/annotations/for.rb, line 37
def fetch(path)
  request = Net::HTTP::Get.new path
  options = ['www.youtube.com', 443, {use_ssl: true}]
  response = Net::HTTP.start(*options) {|http| http.request request}
  response.body
end
json_to_annotations(json) click to toggle source
# File lib/yt/annotations/for.rb, line 52
def json_to_annotations(json)
  annotations = json['elements']
  annotations.map{|data| Annotations::EndScreen.new data['endscreenElementRenderer']}
end
merge_highlights(annotations) click to toggle source
# File lib/yt/annotations/for.rb, line 77
def merge_highlights(annotations)
  highlights, others = annotations.partition{|a| a['type'] == 'highlight'}
  highlights.each do |highlight|
    match = others.find do |a|
      (a['segment'] || {})['spaceRelative'] == highlight['id']
    end
    match.merge! highlight if match
  end
  others
end
xml_to_annotations(xml) click to toggle source
# File lib/yt/annotations/for.rb, line 44
def xml_to_annotations(xml)
  annotations = xml['document']['annotations']
  annotations = Array.wrap (annotations || {})['annotation']
  annotations = merge_highlights annotations
  annotations = exclude_drawers annotations
  annotations.map{|data| annotation_class(data).new data}
end