Generating Links to Youtube Audio
Question: I have been for a while now, as part of a larger project, trying to find a way
to stream Youtube AUDIO into an application without downloading the
corresponding file.

What I have as of now is a program that downloads the video using a web
service such as [saveyoutube.com](http://saveyoutube.com/). This, however is
not very efficient. The downloading of the video itself takes around 5
minutes, and the client may get tired of waiting and just use the Youtube
interface directly. Also, say the user of the program wishes to access a
4-hour long album. However, they want to listen only to a specific part of it,
for sake of explanation, lets say the user wants to see the video from 2 hours
onwards (for example, take [this](https://developers.google.com/youtube/)
video).

There is no doubt that my program works for this as well, but it takes
approximately 20 minutes for the music to start playing (as downloading 2
hours of audio takes alot of time). Also, I have used up around 400 megabytes
of space on the user’s computer by then. Sure, I can store the file in a
temporary folder and delete it after they close the program, but that leads to
more problems:

  1. If the program crashes at 1 minute before the download is complete because of lack of space (who knows what the client has on their computer), the client would have wasted around 20 minutes of their time for nothing.

  2. Say the next time they load the program, they wish to do the same thing. Then they have to wait ANOTHER 20 minutes. This could be countervented by adding a 'Save Audio' button to the interface, which would keep the program from deleting the file when it closes. However, the first impass remains.

So here is my question: is there a way to generate links to the AUDIO of
Youtube videos? Is there a way to obtain a url like
<http://www.youtube.com/watch?v=AOARzA8nGu4.(AUDIOEXTENSION>)? That way
skipping to a part in the soundtrack would be easier, and would not require
downloading. I have researched this for quite a while, and so far, the closest
thing to an answer WAS saveyoutube: a mp3 downloader.

Is this even possible to do? If not, is there an alternative to Youtube that
this can be done to? I have looked into the [Youtube
API](https://developers.google.com/youtube/), but that again is unfavorable,
as like most Google services, its API is limited.

Programming language is not a limitation, as most code can be translated.
However, a Python or C/C++ solution would be ideal.

Thanks in advance!

P.S. I have a server available for this, but I would be very reluctant to
download all Youtube videos onto the server. However, if there is another
solution involving a server that does not involve ripping off the entirety of
Youtube, that would be great.


Answer: After a considerable amount of more research, I found a solution. While not
obtaining LINKS to the audio, I created a program that plays the YouTube video
invisibly, and hence can play the 'AUDIO', which was my intention.

The program I wrote uses alot of the already available Python modules to
achieve the goal.

I found [this](http://www.daniweb.com/software-
development/python/threads/64949/write-a-flash-player-by-python) link, which
explains how to embed Flash into a Python application, via wxPython (found
[here](http://www.wxpython.org)). It has a activexwrapper module, which I
utilized to play the Flash.

Code:

    
    
    import  wx
    
    if wx.Platform == '__WXMSW__':
        from wx.lib.flashwin import FlashWindow
    
    
    class MyPanel(wx.Panel):
        def __init__(self, parent, id):
            wx.Panel.__init__(self, parent, -1)
            self.pdf = None
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
    
            self.flash = FlashWindow(self, style=wx.SUNKEN_BORDER)
            sizer.Add(self.flash, proportion=1, flag=wx.EXPAND)
            #sizer.Hide(0)
    
            self.SetSizer(sizer)
            self.SetAutoLayout(True)
            print "Importing Flash..."
            self.flash.LoadMovie(0, raw_input('Copy link for flash: '))
            #Used to load a flash file. You may also give a location of a specific file on disk.
            print "Done."
    
    app = wx.PySimpleApp()
    # create window/frame, no parent, -1 is default ID, title, size
    # change size as needed
    frame = wx.Frame(None, -1, "Flash Stream", size = (500, 400))
    # make instance of class, -1 is default ID
    MyPanel(frame, -1)
    # show frame
    frame.Show(True)
    #comment if you don't want to see the ui
    print "Started"
    # start event loop
    app.MainLoop()
    

That plays the video. In my case, I did not want to have the GUI, so I deleted
the '`frame.Show(True)`' line. If you wish to test it, try a link like
'[http://www.youtube.com/v/cP6lppXT-9U?version=3&hl=en_US](http://www.youtube.com/v/cP6lppXT-9U?version=3&hl=en_US)',
as I will explain later.

However, this does not allow for pausing, etc. Therefore, other methods must
be used.

To start autoplay: add a '`&autoplay=1`' to the URL

Here is how you can pause:

You can generate the video length uring the [youtube-
dl](http://rg3.github.com/youtube-dl/download.html) module, and kill the
thread when the user pauses it. However, you would store the time already
played, and the next time, you would add a '`&start=SECONDSPLAYED`', which
will effectively 'resume' the video. Details on this are found
[here](http://www.mydigitallife.info/youtube-allows-you-to-start-playing-
embed-video-at-specific-start-time/).

Also, you MUST use the YouTube embed url, which is the only one that works. An
example looks like '`http://www.youtube.com/v/cP6lppXT-9U?version=3&hl=en_US`'

**Pros**

  * Legal*
  * Fast Flash Loading Time (0.01 seconds benchmark) 
  * Does not waste space
  * Can skip to ending without downloading entire file
  * Unlimited uses, due to not using the YouTube API

*According to [YouTube's terms of service](http://www.youtube.com/static?gl=US&template=terms), section 4: General Use of the Service—Permissions and Restrictions, subsection 3.

> You agree not to access Content through any technology or means other than
> the video playback pages of the Service itself, the Embeddable Player, or
> other explicitly authorized means YouTube may designate.

Due to that the program uses an alternate interface that mainly uses the
Embeddable Player, and does not do anything outright illegal (like downloading
the file [my first idea]).

**Cons**

  * Due to the reliance on ActiveX, this application will **NOT** work on any operating system BUT Windows.
  * From the people I know, few use Internet Explorer. Alas, this program requires the INTERNET EXPLORER Flash to be installed; not Mozzila Flash, Chrome Flash. It absolutely HAS to be IE. Otherwise, the application will load, but the video will not appear.
  * wx takes a VERY long time to load (approx 10 seconds).

**Dependencies**

  * For obvious reasons, wxPython must be used.
  * Python comtypes (found [here](http://pypi.python.org/pypi/comtypes)) must be installed. Otherwise, wxPython cannot communicate with ActiveX.

**Helpful Functions**

I also created some functions to speed up the process for anyone who is doing
the same thing.

All are nice one-liner lambdas.

generate_link: returns the YouTube Embed URL, given a normal YouTube URL.

    
    
    generate_link = lambda link: 'http://www.youtube.com/v/'+re.compile(r'watch\?v=(.*?)(?:&|$)').search(link).group(1)+'?version=3&amp;hl=en_US'
    

start_from: Accepts the hour, minute, and seconds of where to start a video,
and returns a link.

    
    
    start_from = lambda hours, minutes, seconds, link: link + '&start=' + str((hours*60*60)+(minutes*60)+seconds)
    

autoplay: Probably the simplest, sets autoplay to true, and returns a link. It
accepts a link.

    
    
    autoplay = lambda link: link + '&autoplay=1'    
    

video_length: Returns the length of the video. Useful, accepts YouTube link.

    
    
    video_length = lambda video: re.compile(r'length_seconds=(.*?)\\', re.S).search(urllib2.urlopen(video).read()).group(1).strip()
    

This is meant as a workaround for the fact that licensed videos will return an
error

    
    
    status=fail&errorcode=150&reason=This+video+contains+content+from+WMG.+It+is+restricted+from+playback+on+certain+sites.%3Cbr%2F%3E%3Cu%3E%3Ca+href%3D%27http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DVALbSjayAgw%26feature%3Dplayer_embedded%27+target%3D%27_blank%27%3EWatch+on+YouTube%3C%2Fa%3E%3C%2Fu%3E
    

Therefore, I parsed the actual video page to get the length. A bit slower, but
works without fail.

