Downloading age-restricted videos from YouTube

booTube.png

First off, I'd like to compliment Yuji Shimada on his fantastic module WWW::YouTube::Download. I'm sure the module requires a lot of maintenance (as sites like YouTube can change their design quite a bit) and for that I'm grateful.

Now, the module worked perfectly for my downloading needs *except* that I could not fetch age-restricted videos. Instead I received a message that the module could not find any video URLs. The bright side to this problem was that Shimada's module made it *very* easy to come to a solution, thanks to the module's ua method which accepts a LWP::UserAgent object.

TL;DR - cookies

In my case, I was using Mechanize, so I passed the Mech object to the ua method, like so:


my $youtube = WWW::YouTube::Download->new;
my $mech    = WWW::Mechanize->new(           #
    cookie_jar => {file => '~/.youtube.dat', autosave => 1},
);
$youtube->ua($mech);

Then from there I had to reproduce a browser login to YouTube:


sub login {
    my $uri = URI->new('https://accounts.google.com/ServiceLogin');
    $uri->query_form(
        {   continue => 'http://www.youtube.com/signin',
            service  => 'youtube',
            passive  => 'true',
            hl       => 'en',
        }
    );
    $mech->get($uri->as_string);
    $mech->form_number(1); # lazy
    $mech->field(Email  => 'foobar@gmail.com');
    $mech->field(Passwd => 'mylongpassword');
    $mech->submit;
}

after login() subroutine is called, Mech will store cookies and we should be logged in the next time we view a video. So the next part is easy:

$youtube->download('4loJ5b102PU'); # video ID

Note:

Keep in mind that if the YouTube account you are using has never viewed an age-restricted video, you will need to click the Accept button (or something similar) once (and only once) before WWW::YouTube::Download can fetch these videos.

5 Comments

Thanks for the tip. A workaround, but as long as it works...

Odd. You may want to try my own tool for the purpose, which has never had an issue with downloading age-restricted videos even without any login credentials.

(Though it has to be noted that it cannot download those videos which use the inscrutable hash signature Youtube introduced half a year ago or so. However, they never did seem to use it very widely, and it has been a while now since I last encountered such a video. When one does, the only recourse is the age-old one: load the page in the browser, bring up the network inspector, and grab the file after Youtube’s player has done the work to pull it.)

(You can do this even with age-restricted videos, because Youtube demands the login only when you play the video inside Youtube’s UI. If you change the /watch?v=eLeVEnChaRs part of the URL to just /v/eLeVEnChaRs, you get a full-window embedded player which never asks for a login.)

jwz's youtubedown works fine for these cases as well, and it is updated quite often.

Last I knew it only sort-of worked fine. I had looked at his code to potentially steal the solution for mine, since I maintain mine actively too – I rely on it daily, so I notice and fix any breakage quickly. But his first iterations didn’t work reliably enough for my taste, so I waited.

Then he added some insane hackery that transpiles YouTube’s Javascript to Perl with regexps, of which I don’t know how reliably it works. But it’s so over-the-top whacky that I preferred to remain in wait of some saner solution.

And in the half-year-plus meantime since, I haven’t run into a single hash signature protected video again. So the itch just hasn’t been there any more. And I hope to get away with that.

Because the reason I use my script is that I like the way it’s architected better than any of the other popular ones. In jwz’s case, he takes a low-level brute force approach with fewer dependencies; I prefer to use actual parsers and write for expression of intent. Hence my reluctance to imitate his crazywhack hackery for the hash signature nonsense. (This is not a criticism; his way works, I just don’t like it.)

So the reason I mentioned this hash signature business at all is because it’s a potential caveat: maybe there are hash-signed videos out there that I simply haven’t been running into. If so then I’d love to hear about it and will want to do something about it. But if it’s unnecessary – and it may be – then I’m content to keep the code clear and simple.

Leave a comment

About curtis

user-pic github.com/aggrolite