Fix Vimeo grabber, support SD only video
[videosite.git] / videosite / VimeoGrabber.pm
1 # (c) 2007 by Ralf Ertzinger <ralf@camperquake.de>
2 # licensed under GNU GPL v2
3 #
4 # Grabber for vimeo.com
5
6 package videosite::VimeoGrabber;
7
8 use videosite::GrabberBase;
9 @ISA = qw(videosite::GrabberBase);
10
11 use HTML::TokeParser;
12 use videosite::JSArrayParser;
13 use Data::Dumper;
14
15 use strict;
16
17 sub new {
18     my $class = shift;
19     my $self = $class->SUPER::new();
20
21     $self->{'NAME'} = 'vimeo';
22     $self->{_SELFTESTURL} = 'http://vimeo.com/35055590';
23     $self->{_SELFTESTTITLE} = 'Hello';
24     $self->{'PATTERNS'} = ['(http://(?:[-a-zA-Z0-9_.]+\.)*vimeo.com/(?:m/)?(\d+))'];
25
26     bless($self, $class);
27     $self->_prepare_parameters();
28
29     return $self;
30 }
31
32 sub _parse {
33     my $self = shift;
34     my $url = shift;
35     my $pattern = shift;
36     my $content;
37     my $metadata = {};
38     my $p;
39     my $e;
40     my $dlurl;
41     my $hd;
42     my $dlpath;
43     my $timestamp;
44     my $hash;
45
46     $url =~ m|$pattern|;
47     $url = $1;
48
49     $metadata->{'URL'} = $url;
50     $metadata->{'ID'} = $2;
51     $metadata->{'TYPE'} = 'video';
52     $metadata->{'SOURCE'} = $self->{'NAME'};
53     $metadata->{'TITLE'} = undef;
54     $metadata->{'DLURL'} = undef;
55
56     # Get the XML file containing the video metadata
57     unless(defined($content = $self->simple_get(sprintf('http://vimeo.com/%s', $2)))) {
58         $self->error('Could not download site');
59         return undef;
60     }
61
62     $p = HTML::TokeParser->new(\$content);
63
64     while ($e = $p->get_tag('script')) {
65         if ($e->[0] eq 'script') {
66             my $t = $p->get_text();
67
68             if ($t =~ m|clip\d+_\d+ = (.*\});Player|s) {
69                 my $jsp = videosite::JSArrayParser->new();
70                 my $r;
71
72                 $self->debug("Found raw config: %s", $1);
73                 $r = $jsp->parse($1);
74
75                 unless(defined($r)) {
76                     $self->error("Found information hash, but could not parse");
77                     return undef;
78                 }
79
80                 $self->debug("Found parsed config: %s", Dumper($r));
81
82                 unless(exists($r->{'config'}->{'request'})) {
83                     $self->error("Required information not found in hash");
84                     return undef;
85                 }
86
87                 $metadata->{'TITLE'} = $r->{'config'}->{'video'}->{'title'};
88                 $hd = grep { $_ eq 'hd' } @{$r->{'config'}->{'video'}->{'files'}->{'h264'}};
89                 $self->debug("HD: %d", $hd);
90                 $r = $r->{'config'}->{'request'};
91
92                 $metadata->{'DLURL'} = sprintf("http://%s/play_redirect?clip_id=%d&sig=%s&time=%d&quality=%s&codecs=H264,VP8,VP6",
93                         $r->{'player_url'},
94                         $metadata->{'ID'},
95                         $r->{'signature'},
96                         $r->{'timestamp'},
97                         $hd?'hd':'sd',
98                         );
99             }
100         }
101     }
102
103     unless(defined($metadata->{'DLURL'}) && defined($metadata->{'TITLE'})) {
104         $self->error('Could not extract download URL and title');
105         return undef;
106     }
107
108     return $metadata;
109 }
110
111 1;