Class: YouTubeRails

Inherits:
Object
  • Object
show all
Defined in:
lib/youtube_rails.rb

Constant Summary collapse

SCHEME_FORMAT =
%r{(https?:|)//}i
SHORTURL_DOMAIN =
'youtu.be'
DOMAIN_ALIASES =

Some URLs are interchangeable with others. The keys here are just an ID.

{
  'youtube.com' => %w{www.youtube.com
                          youtube.com
                        m.youtube.com
                      www.youtube-nocookie.com},
  SHORTURL_DOMAIN => [SHORTURL_DOMAIN],
}
DOMAIN_REGEX =
DOMAIN_ALIASES.map do |placeholder, domains|
  [placeholder, _domains_to_regex(domains)]
end.to_h
ID =

URL-safe Base64 ID

%r{(?<id>[0-9a-zA-Z_-]+)}
ANYPARAMS =

Zero or more URL parameters

%r{([^;&]*[&;])*}
URL_FORMATS =
[
  %r{^(watch|ytscreeningroom)\?#{ANYPARAMS}v=#{ID}}mi,
  %r{^(v|e|embed|shorts)/#{ID}}mi,
  %r{^oembed\?#{ANYPARAMS}url=[^&;]+watch(%3f|\?)v(=|%3d)#{ID}}mi, # accepts encoded delims
  %r{^attribution_link\?#{ANYPARAMS}u=(/|%2f)watch(%3f|\?)v(=|%3d)#{ID}}mi, # ditto
  %r{^apiplayer\?#{ANYPARAMS}video_id=#{ID}}mi,
]
SHORTURL_FORMATS =
[
  %r{^#{ID}}i,
]
INVALID_CHARS =

See reserved and unreserved characters here: www.rfc-editor.org/rfc/rfc3986#appendix-A Note, % character must also be included, as this is used in pct-encoded escapes.

%r{[^a-zA-Z0-9:/?=&$\-_.+!*'(),~#\[\]@;%]}

Class Method Summary collapse

Class Method Details

._domains_to_regex(domains) ⇒ Object

Converts a list of domains into a regex matching them at the start of a string



3
4
5
6
7
8
9
10
11
# File 'lib/youtube_rails.rb', line 3

def self._domains_to_regex(domains)
  pattern = [
    '^(',
    domains.map {|d| Regexp.quote(d) }.join('|'),
    ')/'
  ].join('')
  
  Regexp.new(pattern, Regexp::IGNORECASE | Regexp::MULTILINE)
end

.extract_video_id(youtube_url) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/youtube_rails.rb', line 49

def self.extract_video_id(youtube_url)
  return nil if has_invalid_chars?(youtube_url)
  youtube_url = youtube_url
                  .strip # remove whitespace before and after
                  .sub(%r{^#{SCHEME_FORMAT}}, '') # remove valid schemes

  # Deal with shortened URLs as a special case
  if youtube_url.sub!(DOMAIN_REGEX['youtu.be'], '')
    SHORTURL_FORMATS.each do |regex|
      match = youtube_url.match(regex)
      return match[:id] if match
    end
    return nil # No matches
  end

  # Ensure one of the regular allows domains matches
  return nil unless youtube_url.sub!(DOMAIN_REGEX['youtube.com'], '')
  
  URL_FORMATS.inject(nil) do |result, format_regex|
    match = format_regex.match(youtube_url)
    match ? match[:id] : result
  end
end

.extract_video_image(youtube_url, version = 'default') ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/youtube_rails.rb', line 92

def self.extract_video_image(youtube_url, version = 'default')
  vid_id = extract_video_id(youtube_url)
  case version
    when 'default'
      "https://i.ytimg.com/vi/#{ vid_id }/default.jpg"
    when 'medium'
      "https://i.ytimg.com/vi/#{ vid_id }/mqdefault.jpg"
    when 'high'
      "https://i.ytimg.com/vi/#{ vid_id }/hqdefault.jpg"
    when 'maximum'
      "https://i.ytimg.com/vi/#{ vid_id }/sddefault.jpg"
  end
end

.has_invalid_chars?(youtube_url) ⇒ Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/youtube_rails.rb', line 45

def self.has_invalid_chars?(youtube_url)
  !INVALID_CHARS.match(youtube_url).nil?
end

.youtube_embed_url(youtube_url, width = 420, height = 315, **options) ⇒ Object



73
74
75
# File 'lib/youtube_rails.rb', line 73

def self.youtube_embed_url(youtube_url, width = 420, height = 315, **options)
  %(<iframe width="#{width}" height="#{height}" src="#{ youtube_embed_url_only(youtube_url, **options) }" frameborder="0" allowfullscreen></iframe>)
end

.youtube_embed_url_only(youtube_url, **options) ⇒ Object



87
88
89
90
# File 'lib/youtube_rails.rb', line 87

def self.youtube_embed_url_only(youtube_url, **options)
  vid_id = extract_video_id(youtube_url)
  "http#{'s' if options[:ssl]}://www.youtube.com/embed/#{ vid_id }#{'?rel=0' if options[:disable_suggestion]}"
end

.youtube_regular_url(youtube_url, **options) ⇒ Object



77
78
79
80
# File 'lib/youtube_rails.rb', line 77

def self.youtube_regular_url(youtube_url, **options)
  vid_id = extract_video_id(youtube_url)
  "http#{'s' if options[:ssl]}://www.youtube.com/watch?v=#{ vid_id }"
end

.youtube_shortened_url(youtube_url, **options) ⇒ Object



82
83
84
85
# File 'lib/youtube_rails.rb', line 82

def self.youtube_shortened_url(youtube_url, **options)
  vid_id = extract_video_id(youtube_url)
  "http#{'s' if options[:ssl]}://youtu.be/#{ vid_id }"
end