video_info 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +24 -0
- data/.travis.yml +10 -0
- data/Gemfile +11 -0
- data/Guardfile +8 -0
- data/{LICENSE → LICENSE.txt} +2 -0
- data/README.md +42 -43
- data/Rakefile +5 -0
- data/lib/video_info/provider.rb +36 -26
- data/lib/video_info/providers/vimeo.rb +45 -27
- data/lib/video_info/providers/vkontakte.rb +114 -0
- data/lib/video_info/providers/youtube.rb +62 -23
- data/lib/video_info/version.rb +1 -1
- data/lib/video_info.rb +1 -1
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/date/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/description/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/duration/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/embed_code/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/embed_url/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/height/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/keywords/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/provider/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/thumbnail_large/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/thumbnail_medium/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/thumbnail_small/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/title/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/url/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/video_id/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/view_count/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029/width/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029_and_iframe_attributes/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029_and_url_attributes/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029_in_/group/_url/provider/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029_in_/group/_url/video_id/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029_in_text/provider/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vimeo/with_video_898029_in_text/video_id/.yml +69 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/date/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/description/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/duration/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/embed_code/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/embed_url/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/height/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/provider/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/title/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/url/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/video_id/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/video_owner/.yml +1369 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/view_count/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_39576223_108370515/width/.yml +1410 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_arbitrary_iframe_attributes/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_arbitrary_iframe_attributes/provider/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_iframe_attributes/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_iframe_attributes/provider/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_JM9NgvjjVng_in_youtu_be_url/provider/.yml +65 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_JM9NgvjjVng_in_youtu_be_url/video_id/.yml +65 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_after_params/provider/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_after_params/url/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_after_params/video_id/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_in_e_path/provider/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_in_e_path/video_id/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_in_embed_path/provider/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_in_embed_path/video_id/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_in_path/provider/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_in_path/video_id/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_in_user_url/provider/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_in_user_url/url/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_VeasFckfMHY_in_user_url/video_id/.yml +66 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_Xp6CXF-Cesg/provider/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_Xp6CXF-Cesg/video_id/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/date/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/description/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/duration/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/embed_code/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/embed_url/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/height/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/keywords/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/provider/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/thumbnail_large/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/thumbnail_medium/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/thumbnail_small/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/title/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/url/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/video_id/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/view_count/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_mZqGqE0D0n4/width/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_oQ49W_xKzKA/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_oQ49W_xKzKA/provider/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_oQ49W_xKzKA/video_id/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_url_in_text/provider/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/with_video_url_in_text/video_id/.yml +62 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/without_http_or_www/provider/.yml +65 -0
- data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Youtube/without_http_or_www/video_id/.yml +65 -0
- data/spec/lib/video_info/provider_spec.rb +44 -0
- data/spec/lib/video_info/providers/vimeo_spec.rb +74 -0
- data/spec/lib/video_info/providers/vkontakte_spec.rb +38 -0
- data/spec/lib/video_info/providers/youtube_spec.rb +138 -0
- data/spec/lib/video_info_spec.rb +50 -0
- data/spec/spec_helper.rb +22 -0
- data/video_info.gemspec +29 -0
- metadata +219 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f5bfff718ac239bdc03fcb92af2455394dd97d05
|
|
4
|
+
data.tar.gz: 556d2e23987b37bc175ce9603a0a367aa986fac8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ea918f3867fe980ea5f86e415ab672ddb3e78a6a01f4ddb3ef13121c7f86e08e5ada9d243c4d9e36cdf29ca358b6fc676a544d50b44bb1b5cfa4a77a3e3874b0
|
|
7
|
+
data.tar.gz: ef6e684d5c501b35af781265a0ad0f7efdc2ca0e5403652895d02c9e0398c1393820205bd816cffaf83182225c1a079204662c788e072e03f8a631ef47082784
|
data/.gitignore
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## MAC OS
|
|
2
|
+
.DS_Store
|
|
3
|
+
|
|
4
|
+
## TEXTMATE
|
|
5
|
+
*.tmproj
|
|
6
|
+
tmtags
|
|
7
|
+
|
|
8
|
+
## EMACS
|
|
9
|
+
*~
|
|
10
|
+
\#*
|
|
11
|
+
.\#*
|
|
12
|
+
|
|
13
|
+
## VIM
|
|
14
|
+
*.swp
|
|
15
|
+
|
|
16
|
+
## PROJECT::GENERAL
|
|
17
|
+
coverage
|
|
18
|
+
rdoc
|
|
19
|
+
pkg
|
|
20
|
+
Gemfile.lock
|
|
21
|
+
|
|
22
|
+
## PROJECT::SPECIFIC
|
|
23
|
+
.bundle/config
|
|
24
|
+
vendor/bundle/
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/{LICENSE → LICENSE.txt}
RENAMED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Copyright (c) 2013 Thibaud Guillaume-Gentil
|
|
2
2
|
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
3
5
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
6
|
a copy of this software and associated documentation files (the
|
|
5
7
|
"Software"), to deal in the Software without restriction, including
|
data/README.md
CHANGED
|
@@ -1,65 +1,66 @@
|
|
|
1
|
-
# VideoInfo
|
|
1
|
+
# VideoInfo
|
|
2
|
+
|
|
3
|
+
[](http://badge.fury.io/rb/video_info) [](https://travis-ci.org/thibaudgg/video_info) [](https://gemnasium.com/thibaudgg/video_info) [](https://codeclimate.com/github/thibaudgg/video_info) [](https://coveralls.io/r/thibaudgg/video_info)
|
|
4
|
+
|
|
5
|
+
Simple Ruby Gem to get video info from YouTube and Vimeo url.
|
|
2
6
|
|
|
3
|
-
Simple Ruby Gem to get video info from youtube and vimeo url.
|
|
4
7
|
Tested against Ruby 1.8.7, 1.9.3, 2.0.0 and the latest versions of JRuby & Rubinius.
|
|
5
8
|
|
|
6
9
|
Install
|
|
7
10
|
--------
|
|
8
11
|
|
|
9
12
|
``` bash
|
|
10
|
-
|
|
13
|
+
gem install video_info
|
|
11
14
|
```
|
|
12
15
|
|
|
13
16
|
Usage
|
|
14
17
|
-----
|
|
15
18
|
|
|
16
19
|
``` ruby
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# video.embed_url => "http://player.vimeo.com/video/898029"
|
|
46
|
-
# video.embed_code => "'<iframe src="http://player.vimeo.com/video/898029?title=0&byline=0&portrait=0&autoplay=0" frameborder="0"></iframe>'"
|
|
20
|
+
video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4")
|
|
21
|
+
# video.video_id => "mZqGqE0D0n4"
|
|
22
|
+
# video.provider => "YouTube"
|
|
23
|
+
# video.title => "Cherry Bloom - King Of The Knife"
|
|
24
|
+
# video.description => "The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net"
|
|
25
|
+
# video.duration => 175 (in seconds)
|
|
26
|
+
# video.date => Sat Apr 12 22:25:35 UTC 2008
|
|
27
|
+
# video.thumbnail_small => "http://i.ytimg.com/vi/mZqGqE0D0n4/default.jpg"
|
|
28
|
+
# video.thumbnail_medium => "http://i.ytimg.com/vi/mZqGqE0D0n4/mqdefault.jpg"
|
|
29
|
+
# video.thumbnail_large => "http://i.ytimg.com/vi/mZqGqE0D0n4/hqdefault.jpg"
|
|
30
|
+
# video.embed_url => "http://www.youtube.com/embed/mZqGqE0D0n4"
|
|
31
|
+
# video.embed_code => "'<iframe src="http://www.youtube.com/embed/mZqGqE0D0n4" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'"
|
|
32
|
+
|
|
33
|
+
video = VideoInfo.get("http://vimeo.com/898029")
|
|
34
|
+
# video.video_id => "898029"
|
|
35
|
+
# video.provider => "Vimeo"
|
|
36
|
+
# video.title => "Cherry Bloom - King Of The Knife"
|
|
37
|
+
# video.description => "The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net"
|
|
38
|
+
# video.keywords => "alternative, bloom, cherry, clip, drum, guitar, king, knife, of, Paris-Forum, rock, the, tremplin"
|
|
39
|
+
# video.duration => 175 (in seconds)
|
|
40
|
+
# video.date => Mon Apr 14 13:10:39 +0200 2008
|
|
41
|
+
# video.width => 640
|
|
42
|
+
# video.height => 360
|
|
43
|
+
# video.thumbnail_small => "http://b.vimeocdn.com/ts/343/731/34373130_100.jpg"
|
|
44
|
+
# video.thumbnail_medium => "http://b.vimeocdn.com/ts/343/731/34373130_200.jpg"
|
|
45
|
+
# video.thumbnail_large => "http://b.vimeocdn.com/ts/343/731/34373130_640.jpg"
|
|
46
|
+
# video.embed_url => "http://player.vimeo.com/video/898029"
|
|
47
|
+
# video.embed_code => "'<iframe src="http://player.vimeo.com/video/898029?title=0&byline=0&portrait=0&autoplay=0" frameborder="0"></iframe>'"
|
|
47
48
|
```
|
|
48
49
|
|
|
49
50
|
Options
|
|
50
51
|
-------
|
|
51
52
|
|
|
52
53
|
``` ruby
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4", "User-Agent" => "My YouTube Mashup Robot/1.0")
|
|
55
|
+
video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/")
|
|
56
|
+
video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/",
|
|
57
|
+
"User-Agent" => "My YouTube Mashup Robot/1.0")
|
|
57
58
|
```
|
|
58
59
|
You can also use **symbols** instead of strings (any non-word (`/[^a-z]/i`) character would be converted to hyphen).
|
|
59
60
|
|
|
60
61
|
``` ruby
|
|
61
|
-
|
|
62
|
-
:user_agent => "My
|
|
62
|
+
video = VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4", :referer => "http://my-youtube-mashup.com/",
|
|
63
|
+
:user_agent => "My YouTube Mashup Robot/1.0")
|
|
63
64
|
```
|
|
64
65
|
|
|
65
66
|
User-Agent when empty defaults to "VideoInfo/VERSION" - where version is current VideoInfo version, e.g. **"VideoInfo/0.2.7"**.
|
|
@@ -76,15 +77,13 @@ VideoInfo.get("http://www.youtube.com/watch?v=mZqGqE0D0n4").embed_code(:iframe_a
|
|
|
76
77
|
=> '<iframe src="http://www.youtube.com/embed/mZqGqE0D0n4?autoplay=1" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
81
80
|
Author
|
|
82
81
|
------
|
|
83
82
|
|
|
84
|
-
[Thibaud Guillaume-Gentil](https://github.com/thibaudgg) ([@thibaudgg](
|
|
83
|
+
[Thibaud Guillaume-Gentil](https://github.com/thibaudgg) ([@thibaudgg](https://twitter.com/thibaudgg))
|
|
85
84
|
|
|
86
85
|
Contributors
|
|
87
86
|
------------
|
|
88
87
|
|
|
89
|
-
[https://github.com/thibaudgg/video_info/contributors](https://github.com/thibaudgg/video_info/contributors)
|
|
88
|
+
[https://github.com/thibaudgg/video_info/graphs/contributors](https://github.com/thibaudgg/video_info/graphs/contributors)
|
|
90
89
|
|
data/Rakefile
ADDED
data/lib/video_info/provider.rb
CHANGED
|
@@ -2,12 +2,7 @@ require "addressable/uri"
|
|
|
2
2
|
|
|
3
3
|
module VideoInfo
|
|
4
4
|
class Provider
|
|
5
|
-
|
|
6
|
-
attr_accessor :url, :options, :iframe_attributes, :video_id
|
|
7
|
-
attr_accessor :embed_url, :provider, :title, :description, :keywords,
|
|
8
|
-
:duration, :date, :width, :height,
|
|
9
|
-
:thumbnail_small, :thumbnail_medium, :thumbnail_large,
|
|
10
|
-
:view_count
|
|
5
|
+
attr_accessor :url, :options, :iframe_attributes, :video_id, :video
|
|
11
6
|
|
|
12
7
|
def initialize(url, options = {})
|
|
13
8
|
@options = _clean_options(options)
|
|
@@ -21,22 +16,39 @@ module VideoInfo
|
|
|
21
16
|
end
|
|
22
17
|
|
|
23
18
|
def embed_code(options = {})
|
|
24
|
-
url_attributes = options.fetch(:url_attributes, {})
|
|
25
|
-
url_attrs = default_url_attributes.merge(url_attributes)
|
|
26
|
-
|
|
27
|
-
url = embed_url
|
|
28
|
-
url += "?#{_hash_to_params(url_attrs)}" unless url_attrs.empty?
|
|
29
|
-
|
|
30
|
-
iframe_attrs = ["src=\"#{url}\"", "frameborder=\"0\""]
|
|
31
|
-
|
|
32
19
|
iframe_attributes = options.fetch(:iframe_attributes, {})
|
|
33
|
-
iframe_attrs
|
|
20
|
+
iframe_attrs = ["src=\"#{_embed_url(options)}\"", "frameborder=\"0\""]
|
|
21
|
+
iframe_attrs << _hash_to_attributes(_default_iframe_attributes.merge(iframe_attributes))
|
|
34
22
|
|
|
35
23
|
"<iframe #{iframe_attrs.reject(&:empty?).join(" ")}></iframe>"
|
|
36
24
|
end
|
|
37
25
|
|
|
38
26
|
private
|
|
39
27
|
|
|
28
|
+
def _clean_options(options)
|
|
29
|
+
options = { 'User-Agent' => "VideoInfo/#{VideoInfo::VERSION}" }.merge(options)
|
|
30
|
+
options.dup.each do |key, value|
|
|
31
|
+
if _not_openuri_option_symbol?(key)
|
|
32
|
+
options[_http_header_field(key)] = value
|
|
33
|
+
options.delete key
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
options
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def _set_info_from_api
|
|
40
|
+
uri = open(_api_url, options)
|
|
41
|
+
@video = MultiJson.load(uri.read)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def _not_openuri_option_symbol?(key)
|
|
45
|
+
key.is_a?(Symbol) && !OpenURI::Options.keys.include?(key)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def _http_header_field(key)
|
|
49
|
+
key.to_s.split(/[^a-z]/i).map(&:capitalize).join('-')
|
|
50
|
+
end
|
|
51
|
+
|
|
40
52
|
def _set_video_id_from_url
|
|
41
53
|
url.gsub(_url_regex) { @video_id = $1 || $2 || $3 }
|
|
42
54
|
end
|
|
@@ -49,19 +61,17 @@ module VideoInfo
|
|
|
49
61
|
raise NotImplementedError.new('Provider class must implement #_url_regex private method')
|
|
50
62
|
end
|
|
51
63
|
|
|
52
|
-
def
|
|
53
|
-
raise NotImplementedError.new('Provider class must implement #
|
|
64
|
+
def _api_url
|
|
65
|
+
raise NotImplementedError.new('Provider class must implement #_api_url private method')
|
|
54
66
|
end
|
|
55
67
|
|
|
56
|
-
def
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
end
|
|
64
|
-
options
|
|
68
|
+
def _embed_url(options)
|
|
69
|
+
url_attrs = options.fetch(:url_attributes, {})
|
|
70
|
+
url_attrs = _default_url_attributes.merge(url_attrs)
|
|
71
|
+
|
|
72
|
+
url = embed_url
|
|
73
|
+
url += "?#{_hash_to_params(url_attrs)}" unless url_attrs.empty?
|
|
74
|
+
url
|
|
65
75
|
end
|
|
66
76
|
|
|
67
77
|
def _hash_to_attributes(hash)
|
|
@@ -9,15 +9,40 @@ module VideoInfo
|
|
|
9
9
|
url =~ /vimeo\.com/
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def
|
|
13
|
-
|
|
12
|
+
def provider
|
|
13
|
+
'Vimeo'
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
def url
|
|
17
|
+
video ? video['url'] : @url
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
%w[title description thumbnail_small thumbnail_medium thumbnail_large].each do |method|
|
|
21
|
+
define_method(method) { video[method] }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
%w[duration width height].each do |method|
|
|
25
|
+
define_method(method) { video[method].to_i }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def keywords
|
|
29
|
+
video['tags']
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def embed_url
|
|
33
|
+
"http://player.vimeo.com/video/#{video_id}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def date
|
|
37
|
+
Time.parse(video['upload_date'], Time.now.utc).utc
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def view_count
|
|
41
|
+
video['stats_number_of_plays'].to_i
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def video
|
|
45
|
+
@video && @video.first
|
|
21
46
|
end
|
|
22
47
|
|
|
23
48
|
private
|
|
@@ -26,26 +51,19 @@ module VideoInfo
|
|
|
26
51
|
/.*\.com\/(?:(?:groups\/[^\/]+\/videos\/)|(?:video\/))?([0-9]+).*$/i
|
|
27
52
|
end
|
|
28
53
|
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
@date = Time.parse(video['upload_date'], Time.now.utc).utc
|
|
43
|
-
@thumbnail_small = video['thumbnail_small']
|
|
44
|
-
@thumbnail_medium = video['thumbnail_medium']
|
|
45
|
-
@thumbnail_large = video['thumbnail_large']
|
|
46
|
-
@view_count = video['stats_number_of_plays'].to_i
|
|
47
|
-
rescue
|
|
48
|
-
nil
|
|
54
|
+
def _api_url
|
|
55
|
+
"http://vimeo.com/api/v2/video/#{video_id}.json"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def _default_iframe_attributes
|
|
59
|
+
{}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def _default_url_attributes
|
|
63
|
+
{ :title => 0,
|
|
64
|
+
:byline => 0,
|
|
65
|
+
:portrait => 0,
|
|
66
|
+
:autoplay => 0 }
|
|
49
67
|
end
|
|
50
68
|
|
|
51
69
|
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require 'open-uri'
|
|
4
|
+
require 'multi_json'
|
|
5
|
+
require 'htmlentities'
|
|
6
|
+
|
|
7
|
+
if RUBY_VERSION.to_i < 2
|
|
8
|
+
require 'iconv'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module VideoInfo
|
|
12
|
+
module Providers
|
|
13
|
+
class Vkontakte < Provider
|
|
14
|
+
attr_accessor :video_owner
|
|
15
|
+
|
|
16
|
+
def self.usable?(url)
|
|
17
|
+
url =~ /(vk\.com)|(vkontakte\.ru)/
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def provider
|
|
21
|
+
'Vkontakte'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
%w[description keywords].each do |method|
|
|
25
|
+
define_method(method) { HTMLEntities.new.decode(video[:description]) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
%w[width height duration view_count].each do |method|
|
|
29
|
+
define_method(method) { video[method.to_sym].to_i }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def title
|
|
33
|
+
video[:title]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def embed_url
|
|
37
|
+
"http://vk.com/video_ext.php?oid=#{video_owner}&id=#{video_id}&hash=#{video[:hash]}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def _parse_hash
|
|
43
|
+
@html[/hash2\\":\\"(\w+)/,1]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def _parse_view_count
|
|
47
|
+
@html[/mv_num_views\\"><b>(\d+)/,1].to_i
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def _parse_title
|
|
51
|
+
@html[/<title>(.*)<\/title>/,1].gsub(" | ВКонтакте", "")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def _parse_duration
|
|
55
|
+
@html[/"duration":(\d+)/,1].to_i
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def _parse_height
|
|
59
|
+
@html[/url(\d+)/,1].to_i
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def _get_width(height)
|
|
63
|
+
{ 240 => 320,
|
|
64
|
+
360 => 480,
|
|
65
|
+
480 => 640,
|
|
66
|
+
720 => 1280
|
|
67
|
+
}[height]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def _parse_description
|
|
71
|
+
@html[/<meta name="description" content="(.*)" \/>/,1]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def _set_info_from_api
|
|
75
|
+
uri = open(_api_url, options)
|
|
76
|
+
if RUBY_VERSION.to_i < 2
|
|
77
|
+
@html = Iconv.iconv('utf-8', 'cp1251', uri.read)[0]
|
|
78
|
+
else
|
|
79
|
+
@html = uri.read.encode("UTF-8")
|
|
80
|
+
end
|
|
81
|
+
@video = {
|
|
82
|
+
:hash => _parse_hash,
|
|
83
|
+
:view_count => _parse_view_count,
|
|
84
|
+
:title => _parse_title,
|
|
85
|
+
:duration => _parse_duration,
|
|
86
|
+
:width => _get_width(_parse_height),
|
|
87
|
+
:height => _parse_height,
|
|
88
|
+
:description => _parse_description
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def _set_video_id_from_url
|
|
93
|
+
url.gsub(_url_regex) { @video_owner, @video_id = ($1 || $2 || $3).split('_') }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def _url_regex
|
|
97
|
+
/(?:vkontakte\.ru\/video|vk\.com\/video)(\d+_\d+)/i
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def _api_url
|
|
101
|
+
"http://vk.com/video#{video_owner}_#{video_id}"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def _default_iframe_attributes
|
|
105
|
+
{ :allowfullscreen => "allowfullscreen" }
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def _default_url_attributes
|
|
109
|
+
{}
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -9,12 +9,48 @@ module VideoInfo
|
|
|
9
9
|
url =~ /(youtube\.com)|(youtu\.be)/
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def
|
|
13
|
-
|
|
12
|
+
def provider
|
|
13
|
+
'YouTube'
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def
|
|
17
|
-
|
|
16
|
+
def title
|
|
17
|
+
_video_entry['title']['$t']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
%w[description keywords].each do |method|
|
|
21
|
+
define_method(method) { _video_media_group["media$#{method}"]['$t'] }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
%w[width height].each do |method|
|
|
25
|
+
define_method(method) { nil }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def duration
|
|
29
|
+
_video_media_group['yt$duration']['seconds'].to_i
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def embed_url
|
|
33
|
+
"http://www.youtube.com/embed/#{video_id}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def date
|
|
37
|
+
Time.parse(_video_entry['published']['$t'], Time.now.utc)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def thumbnail_small
|
|
41
|
+
_video_thumbnail(0)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def thumbnail_medium
|
|
45
|
+
_video_thumbnail(1)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def thumbnail_large
|
|
49
|
+
_video_thumbnail(2)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def view_count
|
|
53
|
+
_video_entry['yt$statistics'] ? _video_entry['yt$statistics']['viewCount'].to_i : 0
|
|
18
54
|
end
|
|
19
55
|
|
|
20
56
|
private
|
|
@@ -23,25 +59,28 @@ module VideoInfo
|
|
|
23
59
|
/(?:youtube(?:-nocookie)?\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i
|
|
24
60
|
end
|
|
25
61
|
|
|
26
|
-
def
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
def _api_url
|
|
63
|
+
"http://gdata.youtube.com/feeds/api/videos/#{video_id}?v=2&alt=json"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def _default_iframe_attributes
|
|
67
|
+
{ :allowfullscreen => "allowfullscreen" }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def _default_url_attributes
|
|
71
|
+
{}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def _video_entry
|
|
75
|
+
video['entry']
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def _video_media_group
|
|
79
|
+
video['entry']['media$group']
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def _video_thumbnail(id)
|
|
83
|
+
_video_entry['media$group']['media$thumbnail'][id]['url']
|
|
45
84
|
end
|
|
46
85
|
|
|
47
86
|
end
|
data/lib/video_info/version.rb
CHANGED
data/lib/video_info.rb
CHANGED