A Ruby Interface to the YouTube API

Posted by shane
on Wednesday, September 27

Update: Version 0.8.0 has been released.

We have mashups using maps, links, events, photos, Amazon items, and eBay auctions. What is the next logic step? Video ofcourse! Learn from the Myspace kids. They are the future after all.

I present to all of you, my dead simple Ruby interface to the YouTube REST API. Install with:

gem install youtube

Want to get the URLs for the top featured YouTube videos?

1
2
3
4
5
require 'youtube'

youtube = YouTube::Client.new 'developer id'
videos = youtube.featured_videos
videos.each { |video| print video.url }

How about the titles of videos with tags ‘heel toe technique’?

videos = youtube.videos_by_tag('heel toe technique')
videos.each { |video| print video.title }

Please check out the source at RubyForge for all available methods. Also check out the original YouTube API functions. The interface implements all the YouTube functions currently available. You will need a YouTube Developer ID.

This is a very early version and not used on any production sites yet. If you run into any issues please let me know. The YouTube API itself has a couple of inconsistencies that I accounted for, but there may be things I missed.

I suppose many of you will use this to find videos to embed on your site. The video URLs returned from the REST interface are made to point to viewable videos on YouTube, and don’t work with the embed tag. Therefore, I created a method on Video called embed_url which will return the URL in the right form. So make sure you use that one when embedding.

I will put up a page soon with the Rdoc documentation, but the source should be pretty self-explanatory. Thanks to flickr.rb by Scott Raymond for the inspiration.

This could be used for more than just mashups ofcourse. The most obvious use is to easily integrate YouTube with your Rails app.

Subversion repository: svn://rubyforge.org/var/svn/youtube

Comments

Leave a response

  1. johanSeptember 27, 2006 @ 10:18 PM
    youtube = new YouTube 'developer id' uhhhm? been coding too much non-ruby lately? ;)
  2. Scott RaymondSeptember 28, 2006 @ 03:59 AM
    Looks nice!
  3. shaneSeptember 28, 2006 @ 04:02 AM
    Thanks Johan! It's fixed. Yes, I am a Java developer by day :) If you think that was bad, you should see me typing .each to iterate an ArrayList in Java :)
  4. DannoHungSeptember 29, 2006 @ 04:38 PM
    I thought he'd just defined a convenience dispatcher into Kernel... << >> <<
  5. Ruby LiciousSeptember 29, 2006 @ 06:41 PM
    .. and here I was thinking scrapping youtube just a couple of weeks ago. nice work.
  6. MarcelOctober 12, 2006 @ 09:09 AM
    Hi, first of all: very nice lib! But I'm a noob, so I don't know if there's a method to create a Video object with only the id of the video? I tried to implement it myself, but I failed miserably ^^ Can you help a fellow Java programmer?
  7. DarshanOctober 17, 2006 @ 07:45 PM
    Just what I wanted. You saved me some time. Great job.
  8. shaneOctober 17, 2006 @ 07:56 PM
    Marcel, where are you getting the id of the video from? The methods on YouTube should already populate all the fields of the Video objects for you. If you want the details of a certain video, all you have to do is video.details. The methods which implement the list API calls automatically populate the id for you.
  9. MarcelOctober 19, 2006 @ 12:33 PM
    Thanks Shane. video.details works great for my purpose :)
  10. shevOctober 26, 2006 @ 10:01 AM
    very very cool thing exactly these little snippets are what will make ruby own java in the long run. after discovering the gruff library (wrapper) 2 weeks ago, now a little youtube API to use ... nifty :)
  11. PaulOctober 27, 2006 @ 11:43 AM
    Great library! Is there any way to get a video by id? I notice this in the Video class, but it seems to not be exposed? response = videos_get_details(:video_id => @id)
  12. shaneOctober 27, 2006 @ 07:01 PM
    Paul, When you retrieve a list of videos using either favorite\_videos, videos\_by\_*, or featured\_videos, each field in each Video object will be fully populated for you. Then if you want further details of a Video, just do video.details. No need to pass in an id. All the API methods are implemented via method\_missing(), which encapsulates the request/response cycle to the YouTube server. So in the case of Video.details, the videos\_get\_details method gets transformed to videos.get\_details</codes>, and gets passed along in the HTTP GET request query string.
  13. PaulOctober 30, 2006 @ 03:07 PM
    Thanks Shane, I can see how to do that - maybe I'm thinking about it wrongly but I have this situation: in the controller: find a list of videos in the view: display the videos in a list, with a link for each video to an action. Now in the action link, as I understand it I cant pass an actual video obejct, only the id right? <%= link_to 'Add this clip..', :action => 'make_clip', :id => video.id, :video => video %> in the linked action: now I have an :id param, but I cant find the video by id. So I would have to get the list again, traverse it looking for the one with the right id? Maybe I'm being dumb here - is it possible to pass the object back serialized or something (seems to be a string)? The pattern in ruby seems to be 'send the id, look it up'. I'm very new to Ruby so I apologize if I'm wasting anyone's time. Thanks Paul
  14. MarcelNovember 01, 2006 @ 01:15 AM
    Paul, if you already have the video's ID you can do it like that: youtube = YouTube.new 'your_api_key' videodetails = youtube.video_details video_id Works for me.
  15. MarcelNovember 01, 2006 @ 01:17 AM
    hmm, somehow the formatting got lost. youtube = YouTube.new 'yourapikey' videodetails = youtube.videodetails videoid
  16. neilNovember 09, 2006 @ 10:14 AM
    apparently we cannot upload videos to youtube using this api!! anyidea that might be available to the developer community??
  17. neilNovember 09, 2006 @ 10:14 AM
    apparently we cannot upload videos to youtube using this api!! anyidea that might be available to the developer community??
  18. shaneNovember 17, 2006 @ 07:26 PM
    Paul- Sorry for the super late reply. I just released a new version of the library that is a little more intuitive. I will blog about the changes soon, but if you are brave, try the new version (0.8.0). Neil- YouTube's API doesn't allow uploads right now. I doubt they ever will. They want people to keep visiting the site.
  19. carlosNovember 24, 2006 @ 10:50 AM
    How would you sort the list in: videos = youtube.videos\_by\_user('user\_name') ? Thanks... great tool!
  20. carlosNovember 24, 2006 @ 10:50 AM
    How would you sort the list in: videos = youtube.videos\_by\_user('user\_name') ? Thanks... great tool!
  21. carlosNovember 24, 2006 @ 11:03 AM
    Never mind... solved it with: video_array = youtube.videos\_by\_user('user\_name') videos = video\_array.sort\_by \{ |video\_sorted| video\_sorted.view\_count \}
  22. carlosNovember 24, 2006 @ 11:06 AM
    And to sort descending, try this: video_array = youtube.videos\_by\_user('user\_name') videos = video\_array.sort\_by \{ |video\_sorted| video\_sorted.view\_count \}.reverse
  23. shaneNovember 24, 2006 @ 03:19 PM
    Carlos, thanks for sharing the tip on sorting by view count. One line of Ruby can go a long way.
  24. carlosNovember 24, 2006 @ 04:14 PM
    Yeah... it's amazing. Took me all day, though (I'm pretty new at this Ruby stuff). I had to pore through the pickaxe book (Programming Ruby - Thomas) and the Agile Web Development with Rails (Pragmatic). I eventually found this article: Sorting an Array of Hashes with Ruby and Enumerable - at the O'Reilly website. I'd leave a link but your comment system won't allow me. and kept experimenting from there. It took me a while to figure out I had to use video\_sorted.view\_count instead of video\_sorted\[:view\_count\]. But there you go... one line does it all.
  25. carlosNovember 24, 2006 @ 04:29 PM
    And, not to be a nuisance, but you can sort using only ONE line of code with: videos = youtube.videos\_by\_user\('user\_name'\).sort\_by \{ |video\_sorted| video\_sorted.view\_count \}.reverse Note: That should all go on one line...
  26. FerryNovember 25, 2006 @ 09:15 AM
    Hi Shane! I don't understand how your component works. 1. Is it possible to retrieve the url of the real FLV file, in a simple manner? 2. It parses the HTML to retrieve the FLV url? 3. From the response header? Simple: Is it possible at all to load the movie into the default MM flv player? In the XML_RPC interface on youtube there is no such a param, only the url to the HTML page www.youtube.com/watch?v=EvBwZqUAyj8 . How can I retrieve the subdomain (in this example: ash-v35.ash) ash-v35.ash.youtube.com/get_video?video_id=EvBwZqUAyj8 p.s. I'm working in AS2.0. I know, the question is not Ruby specific but anyway thx for the answer.
  27. FerryNovember 25, 2006 @ 09:17 AM
    and thx for the component, of course... :-))
  28. FerryNovember 25, 2006 @ 09:39 AM
    Or how can I retrieve this value: www.youtube.com/get_video?video_id=EvBwZqUAyj8&t=OEgsToPDskLXwoDuVZbwzROPRCnH2ORX
  29. carlosNovember 27, 2006 @ 12:32 AM
    Is videos\_by\_user.tags a string? I'd like to get a list of the individual tags assigned to a video, but if they're all stuffed into a string it's impossible, since some tags include spaces between words. PS: You REALLY need to fix your comment system.
  30. carlosNovember 27, 2006 @ 12:36 AM
    Hmmm... I just checked the YouTube videos and it seems spaces are NOT used, so I should be able to extract this information from the String after all.
  31. EduardoDecember 08, 2006 @ 03:39 AM
    Hi, I'm having some problems with youtube interface. Do you guys have any clue?
    NoMethodError (undefined method `compact' for nil:NilClass):
        /home/shiftk/.gems/gems/youtube-0.8.0/lib/youtube.rb:85:in `videos_by_user'
        /app/models/user.rb:56:in `get_videos'
        /app/controllers/videos_controller.rb:8:in `index'
        /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in `send'
    
    
  32. EduardoDecember 08, 2006 @ 04:40 AM
    I'm pretty sure that this is related to gems path, something like that
  33. Daniel InsleyDecember 23, 2006 @ 06:59 AM
    Eduardo, I came across the same problem when no results were returned from Youtube for an application i'm building. I fixed the problem locally so that it returns an empty array when no results returned from their side. I've also updated the tests to reflect these changes. (though, I had to throw Mocha in there in order to write the tests properly because nothing is currently being mocked in the tests) Shane, If you want to get ahold of me I can shoot him over some diff files of the changes I made. Not any big changes, but might save you some time. :)
  34. Ahsan GillFebruary 06, 2008 @ 05:39 AM

    Hi everyone,

    I think I can get help from this forum. I want to validate if the user supplied youtube link is valid or not. Can anyone here help me out, please?

    Thanks

Comment