Videos

Yt::Video represents a YouTube video. You can initialize one using either the YouTube ID or URL:

video = Yt::Video.new id:  'BPNYv0vd78A'
# => #<Yt::Video:0x... @id="BPNYv0vd78A">

Some methods from other classes also return a Yt::Video object (e.g.: Yt::Account#upload_video) or a collection of Yt::Video objects (e.g.: #videos from Yt::Account, Yt::Channel and Yt::Playlist).


Authentication

Most methods of Yt::Video retrieve public data from YouTube (e.g.: fetch a video’s title and description).
To use these methods (marked with   below), you only need to get a Server API key from Google and configure:

Yt.configuration.api_key = "<your api key>" ## replace with your API key

video = Yt::Video.new id: 'BPNYv0vd78A'     ## use any public video ID
video.description
# => "A test video for the Yt gem"

Other methods acts on behalf of YouTube accounts (e.g.: like a video, mark a video as private).
To use these methods (marked with   below), you need to get an API Client ID/Secret from Google, obtain an access or refresh token from the account you want to act as, and pass the account as the :auth parameter:

Yt.configuration.client_id = "<your ID>"           ## replace with your client ID
Yt.configuration.client_secret = "<your secret>"   ## replace with your client secret
account = Yt::Account.new refresh_token: "<token>" ## use the account’s refresh token

video = Yt::Video.new id: 'BPNYv0vd78A', auth: account
video.like
# => true (the video was liked on on behalf of the account)

Lastly, some methods acts on behalf of YouTube content owners (e.g.: fetch the earnings of a video).
To use these methods (marked with   below), you need to get an API Client ID/Secret from Google, obtain an access or refresh token from the content owner, and pass the content owner as the :auth parameter:

Yt.configuration.client_id = "<your ID>"           ## replace with your client ID
Yt.configuration.client_secret = "<your secret>"   ## replace with your client secret
owner = Yt::ContentOwner.new owner_name: "<name>", ## replace with owner’s credentials
                             refresh_token: "<token>"

video = Yt::Video.new id: 'BPNYv0vd78A', auth: owner
video.estimated_revenue since: 3.days.ago
# => {Wed, 8 May 2014 => 12.3, Thu, 9 May 2014 => 3.7, Fri, 10 May 2014 => …}

List of Yt::Video methods

any authentication works Video’s Snippet
→ Yt docsvideo.id # => "BPNYv0vd78A"
→ Yt docsvideo.title # => "Yt info"
→ Yt docsvideo.description # => "A test video for the Yt gem"
→ Yt docsvideo.published_at # => 2015-03-31 06:46:46 UTC
→ Yt docsvideo.thumbnail_url # => "https://i.ytimg.com/vi/BPNYv0vd78A/default.jpg"
→ Yt docsvideo.channel_id # => "UCwCnUcLcb9-eSrHa_RQGkQQ"
→ Yt docsvideo.channel_title # => "Yt test Channel"
→ Yt docsvideo.category_id # => "22"
→ Yt docsvideo.category_title # => "People & Blogs"
must authenticate as the video’s account Video’s Tags
→ Yt docsvideo.tags # => ["test", "video"]
any authentication works Video’s Statistics
→ Yt docsvideo.view_count # => 9
→ Yt docsvideo.like_count # => 1
→ Yt docsvideo.dislike_count # => 0
→ Yt docsvideo.favorite_count # => 3
→ Yt docsvideo.comment_count # => 1
any authentication works (for public videos) Video’s Privacy Status
→ Yt docsvideo.privacy_status # => "public"
→ Yt docsvideo.public? # => true
→ Yt docsvideo.unlisted? # => false
→ Yt docsvideo.private? # => false
must authenticate as a YouTube account Video’s Rating
→ Yt docsvideo.like # => true
→ Yt docsvideo.dislike # => true
→ Yt docsvideo.unlike # => true
→ Yt docsvideo.liked? # => false
must authenticate as the video’s account or content owner Video’s Updates
→ Yt docsvideo.update title: "New title", license: "youtube", tags: ["new"] # => true
→ Yt docsvideo.upload_thumbnail "http://example.com/new_thumbnail.jpg" # => true
→ Yt docsvideo.delete # => false
any authentication works Video’s License
→ Yt docsvideo.license # => "youtube"
→ Yt docsvideo.licensed_as_creative_commons? # => false
→ Yt docsvideo.licensed_as_standard_youtube? # => true
any authentication works Video’s Content Details
→ Yt docsvideo.duration # => 321
→ Yt docsvideo.length # => "05:21"
→ Yt docsvideo.stereoscopic? # => false
→ Yt docsvideo.hd? # => false
→ Yt docsvideo.captioned? # => true
→ Yt docsvideo.licensed? # => false
→ Yt docsvideo.age_restricted? # => false
must authenticate as the video’s account Video’s File Details
→ Yt docsvideo.file_size # => 8000000
→ Yt docsvideo.file_type # => "video"
→ Yt docsvideo.container # => "mov"
any authentication works Video’s Player
→ Yt docsvideo.embed_html # => "<iframe type='text/html' src='https://www.youtube…>"
any authentication works Video’s Live Broadcast Details
→ Yt docsvideo.live_broadcast_content # => "live"
→ Yt docsvideo.scheduled_start_time # => 2015-03-31 06:16:46 UTC
→ Yt docsvideo.scheduled_end_time # => 2015-03-31 07:16:46 UTC
→ Yt docsvideo.actual_start_time # => 2015-03-31 06:16:48 UTC
→ Yt docsvideo.actual_end_time # => nil
→ Yt docsvideo.concurrent_viewers # => 12
any authentication works Video’s Upload Details
→ Yt docsvideo.deleted? # => false
→ Yt docsvideo.failed? # => false
→ Yt docsvideo.processed? # => true
→ Yt docsvideo.rejected? # => false
→ Yt docsvideo.uploading? # => false
any authentication works Video’s Failure Reasons
→ Yt docsvideo.uses_unsupported_codec? # => false
→ Yt docsvideo.has_failed_conversion? # => false
→ Yt docsvideo.empty? # => false
→ Yt docsvideo.invalid? # => false
→ Yt docsvideo.too_small? # => false
→ Yt docsvideo.aborted? # => false
any authentication works Video’s Rejection Reasons
→ Yt docsvideo.claimed? # => false
→ Yt docsvideo.infringes_copyright? # => false
→ Yt docsvideo.duplicate? # => false
→ Yt docsvideo.too_long? # => false
→ Yt docsvideo.violates_terms_of_use? # => false
→ Yt docsvideo.inappropriate? # => false
→ Yt docsvideo.infringes_trademark? # => false
→ Yt docsvideo.belongs_to_closed_account? # => false
→ Yt docsvideo.belongs_to_suspended_account? # => false
any authentication works Video’s Visibility Status
→ Yt docsvideo.scheduled? # => true
→ Yt docsvideo.scheduled_at # => 2015-03-31 06:46:46 UTC
→ Yt docsvideo.embeddable? # => true
→ Yt docsvideo.has_public_stats_viewable? # => true
any authentication works Video’s Associations
→ Yt docsvideo.annotations # => #<Yt::Collections::Annotations …>
must authenticate as the video’s content owner Video’s Monetization
→ Yt docsvideo.ad_formats # => ["standard_instream", "trueview_instream"]
→ Yt docsvideo.estimated_revenue # => {Fri, 14 Oct 2016 => 455.1, …}
→ Yt docsvideo.ad_impressions # => {Fri, 14 Oct 2016 => 84734, …}
→ Yt docsvideo.playback_based_cpm # => {Wed, 8 May 2014 => 1.24, Thu, 9 May 2014 => …}
→ Yt docsvideo.monetized_playbacks # => {Wed, 8 May 2014 => 53345, …}

Notes about Yt::Video analytics methods

By default, analytics methods return the total value for the lifetime of a video.

video.views # => {total: 949}

To set specific starting and ending dates, pass the :since and :until options (either as Date or String).

video.views since: '2014-03-31', until: 1.month.ago # => {total: 429}

To obtain one value per each day or month of the range you specify (rather than the total), use the :by option.

video.views by: :day # => {Wed, 8 May 2014 => 6, Thu, 9 May 2014 => 7, …}
video.views by: :month # => {Fri, 01 May 2015..Sun, 31 May 2015=>130192, …}

To limit the results to a specific country or US state, use the :in option.
Note that only some methods can be limited by US state; check the docs for details.

video.views in: 'FR' # => {total: 45}
video.views in: {country: 'US'} # => {total: 113}
video.views in: {state: 'TX'} # => {total: 11}

For brevity, the options above are omitted in the examples below.

must authenticate as the video’s account or content owner Video’s Analytics
→ Yt docsvideo.views # => {total: 3453}
→ Yt docsvideo.comments # => {total: 304}
→ Yt docsvideo.likes # => {total: 459}
→ Yt docsvideo.dislikes # => {total: 923}
→ Yt docsvideo.shares # => {total: 223}
→ Yt docsvideo.subscribers_gained # => {total: 232}
→ Yt docsvideo.subscribers_lost # => {total: 904}
→ Yt docsvideo.videos_added_to_playlists # => {total: 224}
→ Yt docsvideo.videos_removed_from_playlists # => {total: 322}
→ Yt docsvideo.average_view_duration # => {total: 23}
→ Yt docsvideo.average_view_percentage # => {total: 2.45}
→ Yt docsvideo.annotation_clicks # => {total: 723}
→ Yt docsvideo.annotation_click_through_rate # => {total: 8.34}
→ Yt docsvideo.annotation_close_rate # => {total: 0.34}
→ Yt docsvideo.estimated_minutes_watched # => {total: 4}
→ Yt docsvideo.card_impressions # => {total: 3}
→ Yt docsvideo.card_clicks # => {total: 3}
→ Yt docsvideo.card_click_rate # => {total: 0.65}
→ Yt docsvideo.card_teaser_impressions # => {total: 3}
→ Yt docsvideo.card_teaser_clicks # => {total: 3}
→ Yt docsvideo.card_teaser_click_rate # => {total: 0.65}

→ Yt docsvideo.views by: :country # => {"US" => 12, "IT" => 9, …}
→ Yt docsvideo.comments by: :country # => {"US" => 7, "IT" => 5, …}
→ Yt docsvideo.likes by: :country # => {"US" => 32, "IT" => 8, …}
→ Yt docsvideo.dislikes by: :country # => {"US" => 87, "IT" => 6, …}
→ Yt docsvideo.shares by: :country # => {"US" => 44, "IT" => 3, …}
→ Yt docsvideo.subscribers_gained by: :country # => {"US" => 32, …}
→ Yt docsvideo.subscribers_lost by: :country # => {"US" => 1, …}
→ Yt docsvideo.favorites_added by: :country # => {"US" => 181, …}
→ Yt docsvideo.favorites_removed by: :country # => {"US" => 0, …}
→ Yt docsvideo.videos_added_to_playlists by: :country # => {"US" => 181, …}
→ Yt docsvideo.videos_removed_from_playlists by: :country # => {"US" => 0, …}
→ Yt docsvideo.average_view_duration by: :country # => {"US" => 456, …}
→ Yt docsvideo.average_view_percentage by: :country # => {"US" => 38.85, …}
→ Yt docsvideo.annotation_clicks by: :country # => {"US" => 329, …}
→ Yt docsvideo.annotation_click_through_rate by: :country # => {"US" => 0.3, …}
→ Yt docsvideo.annotation_close_rate by: :country # => {"US" => 0.1, …}
→ Yt docsvideo.estimated_minutes_watched by: :country # => {"US" => 124, …}

→ Yt docsvideo.views by: :state # => {"TX" => 12, "ND" => 9, …}
→ Yt docsvideo.average_view_duration by: :state # => {"TX" => 456, …}
→ Yt docsvideo.average_view_percentage by: :state # => {"TX" => 38.85, …}
→ Yt docsvideo.annotation_clicks by: :state # => {"TX" => 329, …}
→ Yt docsvideo.annotation_click_through_rate by: :state # => {"TX" => 0.3, …}
→ Yt docsvideo.annotation_close_rate by: :state # => {"TX" => 0.1, …}
→ Yt docsvideo.estimated_minutes_watched by: :state # => {"TX" => 124, …}

→ Yt docsvideo.views by: :playback_location # => {watch: 467, embedded: 53, …}
→ Yt docsvideo.views by: :embedded_player_location # => {"fullscreen.net" => 92, …}
→ Yt docsvideo.views by: :related_video, includes: [:status] # => {#<Yt::Video> => …}
→ Yt docsvideo.views by: :device_type # => {mobile: 457, tv: 954, …}
→ Yt docsvideo.views by: :subscribed_status # => {subscribed: 57, unsubscribed: 54}
→ Yt docsvideo.views by: :traffic_source # => {advertising: 53, channel: 7, …}
→ Yt docsvideo.views by: :search_term # => {"fullscreen" => 7, "music" => 3, …}
→ Yt docsvideo.views by: :referrer # => {"Google Search" => 7, "ytimg.com" => 3, …}

→ Yt docsvideo.estimated_minutes_watched by: :playback_location # => {watch: 17, …}
→ Yt docsvideo.estimated_minutes_watched by: :embedded_player_location # => {"t.co"…}
→ Yt docsvideo.estimated_minutes_watched by: :related_video # => {#<Yt::Video>…}
→ Yt docsvideo.estimated_minutes_watched by: :device_type # => {mobile: 57, …}
→ Yt docsvideo.estimated_minutes_watched by: :traffic_source # => {search: 3, …}
→ Yt docsvideo.estimated_minutes_watched by: :search_term # => {"music" => 7, …}
→ Yt docsvideo.estimated_minutes_watched by: :referrer # => {"Facebook" => 7, …}

→ Yt docsvideo.viewer_percentage # => {female: {'18-24' => 4.12, '25-34' => …}, …}
→ Yt docsvideo.viewer_percentage by: :gender # => {female: 12.3, male: 87.7}
→ Yt docsvideo.viewer_percentage by: :age_group # => {'18-24' => 4.1, '25-34' => …}

→ Yt docsvideo.reports only: [:views, :shares] # => {views: {…}, shares: {…}}