+ my $id;
+ my $res;
+
+ my $url =~ m|$pattern|;
+ my $url = $1;
+ my $id = $2;
+
+ $self->debug("Matched id %s from pattern %s", $id, $pattern);
+
+ $res = $self->_parse_by_video_info($url, $id);
+ if (defined($res) && ref($res)) {
+ return $res;
+ } else {
+ $res = $self->_parse_by_scrape($url, $id);
+ }
+
+ return $res;
+}
+
+sub _parse_by_video_info {
+ my $self = shift;
+ my $url = shift;
+ my $id = shift;
+ my $quality = $self->_getval('QUALITY');
+ my $metadata;
+ my $videourl;
+ my $ua = $self->ua();
+ my $preflist;
+ my $r;
+ my $content;
+ my $urls;
+
+ $metadata->{'URL'} = $url;
+ $metadata->{'ID'} = $id;
+ $metadata->{'TYPE'} = 'video';
+ $metadata->{'SOURCE'} = $self->{'NAME'};
+ $metadata->{'TITLE'} = undef;
+ $metadata->{'DLURL'} = undef;
+ $metadata->{'COOKIE'} = undef;
+
+ $preflist = $preflist{$quality};
+ $self->debug("Quality: %s, preflist: [%s]", $quality, join(", ", @{$preflist}));
+
+ $videourl = sprintf('https://www.youtube.com/get_video_info?video_id=%s&eurl=%s',
+ $id, 'http%3A%2F%2Fwww%2Eyoutube%2Ecom%2F');
+ $self->debug("Video info URL: %s", $videourl);
+
+ $r = $ua->get($videourl);
+ unless($r->is_success()) {
+ $self->debug('Could not download %s: %s', $videourl, $r->code());
+ return undef;
+ }
+
+ $content = $r->content();
+ $self->debug('Content from get_video_info: %s', $content);
+
+ # Decode content
+ $content = { split /[&=]/, $content };
+
+ if ($content->{'status'} ne 'ok') {
+ $self->debug("Non OK status code found: %s", $content->{'status'});
+ return undef;
+ }
+
+ unless(exists($content->{'fmt_url_map'}) and exists($content->{'title'})) {
+ $self->debug("No fmt_url_map or no title found");
+ return undef;
+ }
+
+ # Decode fmt_url_map
+ $urls = $content->{'fmt_url_map'};
+ $urls =~ s/%(..)/chr(hex($1))/ge;
+ $urls = { split /[\|,]/, $urls };
+
+ $self->__pick_url($urls, $preflist, $metadata);
+
+ $metadata->{'TITLE'} = $content->{'title'};
+ $metadata->{'TITLE'} =~ s/\+/ /g;
+ $metadata->{'TITLE'} =~ s/%(..)/chr(hex($1))/ge;
+ $metadata->{'TITLE'} = decode("utf8", $metadata->{'TITLE'});
+
+ $self->debug('Title found: %s', $metadata->{'TITLE'});
+
+ unless(defined($metadata->{'DLURL'}) && defined($metadata->{'TITLE'})) {
+ $self->error('Could not determine download URL');
+ return undef;
+ }
+
+ return $metadata;
+}
+
+sub _parse_by_scrape {
+ my $self = shift;
+ my $url = shift;
+ my $id = shift;