Skip to content

Commit

Permalink
find url in a new way
Browse files Browse the repository at this point in the history
also pass CI
additional test of new path
  • Loading branch information
kiwiroy committed Jun 5, 2020
1 parent 1723ef8 commit 72647c7
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 9 deletions.
6 changes: 4 additions & 2 deletions .travis.yml
@@ -1,5 +1,6 @@
---
dist: trusty
os: linux
addons:
apt:
packages:
Expand All @@ -23,12 +24,12 @@ perl:
cache:
directories:
- "~/perl5"
matrix:
jobs:
allow_failures:
- perl: blead
- perl: dev
- env: P5_YOUTUBE_NETWORK_TESTS=1
fast_finish: 1
fast_finish: true
include:
- env: COVERAGE=1
perl: "5.30"
Expand All @@ -40,6 +41,7 @@ env:
- RELEASE_TESTING=1
before_install:
- eval $(curl https://travis-perl.github.io/init) --auto --always-upgrade-modules
- cpanm -n -q Perl::Critic::Policy::ValuesAndExpressions::ProhibitAccessOfPrivateData
notifications:
email:
on_failure: always
Expand Down
2 changes: 2 additions & 0 deletions Makefile.PL
Expand Up @@ -28,6 +28,7 @@ my %WriteMakefileArgs = (
"HTTP::Request" => 0,
"JSON::MaybeXS" => 0,
"LWP::UserAgent" => 0,
"MIME::Type" => 0,
"Pod::Usage" => 0,
"Term::ANSIColor" => 0,
"Time::HiRes" => 0,
Expand All @@ -41,6 +42,7 @@ my %WriteMakefileArgs = (
"TEST_REQUIRES" => {
"ExtUtils::MakeMaker" => 0,
"File::Spec" => 0,
"Mock::Quick" => 0,
"Test::More" => 0
},
"VERSION" => "0.63",
Expand Down
57 changes: 52 additions & 5 deletions lib/WWW/YouTube/Download.pm
Expand Up @@ -12,6 +12,7 @@ use LWP::UserAgent;
use JSON::MaybeXS 'JSON';
use HTML::Entities qw/decode_entities/;
use HTTP::Request;
use MIME::Type;

$Carp::Internal{ (__PACKAGE__) }++;

Expand Down Expand Up @@ -152,10 +153,19 @@ sub prepare_download {

return $self->{cache}{$video_id} if ref $self->{cache}{$video_id} eq 'HASH';

my $content = $self->_get_content($video_id);
my $title = $self->_fetch_title($content);
my $user = $self->_fetch_user($content);
my $video_url_map = $self->_fetch_video_url_map($content);
my ($title, $user, $video_url_map);
my $content = $self->_get_content($video_id);
if ($self->_is_new($content)) {
my $args = $self->_get_args($content);
my $player_resp = JSON()->new->decode($args->{player_response});
$video_url_map = $self->_decode_player_response($player_resp);
$title = decode_entities $player_resp->{videoDetails}{title};
$user = decode_entities $player_resp->{videoDetails}{author};
} else {
$title = $self->_fetch_title($content);
$user = $self->_fetch_user($content);
$video_url_map = $self->_fetch_video_url_map($content);
}

my $fmt_list = [];
my $sorted = [
Expand Down Expand Up @@ -186,6 +196,34 @@ sub prepare_download {
};
}

sub _mime_to_suffix {
(my $mime = shift) =~ s{^([^;]+);.*}{$1};
my $stype = MIME::Type->new(type => $mime)->subType;
return $stype eq 'webm' ? 'webm'
: $stype eq 'mp4' ? 'mp4'
: $stype eq '3gp' ? '3gp'
: 'flv'
;
}

sub _decode_player_response {
my ($self, $player_data) = @_;
# need to decode $player_data->{streamingData}{formats};
my $fmt_map = { map { $_->{mimeType} => join 'x', $_->{width}, $_->{height} } @{$player_data->{streamingData}{formats}} };
my $fmt_url_map = { map { $_->{mimeType} => $_->{url} } @{$player_data->{streamingData}{formats}} };
# more formats in $player_data->{streamingData}{adaptiveFormats};
return +{
map {
$_->{fmt} => $_,
} map +{
fmt => $_,
resolution => $fmt_map->{$_},
url => $fmt_url_map->{$_},
suffix => _mime_to_suffix($_),
}, keys %$fmt_map
};
}

sub _fetch_title {
my ($self, $content) = @_;

Expand All @@ -202,7 +240,7 @@ sub _fetch_user {
return decode_entities($1);
}else{
return;
}
}
}

sub _fetch_video_url_map {
Expand Down Expand Up @@ -266,6 +304,13 @@ sub _get_args {
return $data->{args};
}

sub _is_new {
my ($self, $content) = @_;
my $args = $self->_get_args($content);
return 1 unless ($args->{fmt_list} and $args->{url_encoded_fmt_stream_map});
return 0;
}

sub _parse_fmt_map {
my $param = shift;
my $fmt_map = {};
Expand Down Expand Up @@ -578,6 +623,8 @@ Parses given URL and returns playlist ID.
Parses given URL and returns YouTube username.
=item B<get_video_id($video_id)>
=item B<get_video_url($video_id)>
=item B<get_title($video_id)>
Expand Down
1 change: 1 addition & 0 deletions t/data/player_response.html

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions t/player_response.t
@@ -0,0 +1,51 @@
use strict;
use warnings;
use Test::More;
use WWW::YouTube::Download;
use LWP::UserAgent;
use HTTP::Request;
use Mock::Quick;

my $control = qclass(
-takeover => 'WWW::YouTube::Download',
_get_content => sub {
my $content;
open my $fh, '<', 't/data/player_response.html';
$content = do { local $/; <$fh> };
return $content;
}
);

my $yt = WWW::YouTube::Download->new();

is_deeply $yt->prepare_download('Y1I1KcKvz9Q'), {
'fmt' => 'video/mp4; codecs="avc1.64001F, mp4a.40.2"',
'fmt_list' => [
'video/mp4; codecs="avc1.64001F, mp4a.40.2"',
'video/mp4; codecs="avc1.42001E, mp4a.40.2"'
],
'resolution' => '1280x720',
'suffix' => 'mp4',
'title' => "2016 -\x{200e}Perl's Worst Best Practices\x{200e} - Daina Pettit",
'user' => 'Conference in the Cloud! A Perl and Raku Conf',
'video_id' => 'Y1I1KcKvz9Q',
'video_url' => 'https://r8---sn-uo1-fabe.googlevideo.com/videoplayback?expire=1591286259&ei=k8XYXrpTgbi-BOKUl8AC&ip=222.155.23.220&id=o-ACzVrS0ntoeNxkxf5Eyq0kh40yqw_H8JvAo6oomIF0vi&itag=22&source=youtube&requiressl=yes&mh=nM&mm=31%2C29&mn=sn-uo1-fabe%2Csn-ntqe6nes&ms=au%2Crdu&mv=m&mvi=7&pl=21&initcwndbps=1255000&vprv=1&mime=video%2Fmp4&ratebypass=yes&dur=2664.791&lmt=1471517080079780&mt=1591264536&fvip=5&c=WEB&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cratebypass%2Cdur%2Clmt&sig=AOq0QJ8wRQIhAKbSlz0qjINeYyhN1BhyEcEJk6uWrx4ZAqe-EQdr4AW0AiAL68CXNXGq39ov1k0UEbYTGiKb7J6xQCYT2Me7Zk3ZRA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgSfHsoUVS7LVwrzJNCrTEJI7T9Fmj3j6Mt8bDeFrdM0ECIB6Nvdhmdk3Y929DlGC9ILinX3CRms0pGkfCmeMmd_GB',
'video_url_map' => {
'video/mp4; codecs="avc1.42001E, mp4a.40.2"' => {
'fmt' => 'video/mp4; codecs="avc1.42001E, mp4a.40.2"',
'resolution' => '640x360',
'suffix' => 'mp4',
'url' => 'https://r8---sn-uo1-fabe.googlevideo.com/videoplayback?expire=1591286259&ei=k8XYXrpTgbi-BOKUl8AC&ip=222.155.23.220&id=o-ACzVrS0ntoeNxkxf5Eyq0kh40yqw_H8JvAo6oomIF0vi&itag=18&source=youtube&requiressl=yes&mh=nM&mm=31%2C29&mn=sn-uo1-fabe%2Csn-ntqe6nes&ms=au%2Crdu&mv=m&mvi=7&pl=21&initcwndbps=1255000&vprv=1&mime=video%2Fmp4&gir=yes&clen=110597265&ratebypass=yes&dur=2664.791&lmt=1466645029886574&mt=1591264536&fvip=5&c=WEB&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cgir%2Cclen%2Cratebypass%2Cdur%2Clmt&sig=AOq0QJ8wRgIhAMgkdpjZuGCkvPMUoJ4ks1z4ZXqQCj7M8fjogmEFCiP1AiEA1UbgDHQ-c13XOlLYmAR3OQ4J-KmAo8XuAeqsxsir2V8%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgSfHsoUVS7LVwrzJNCrTEJI7T9Fmj3j6Mt8bDeFrdM0ECIB6Nvdhmdk3Y929DlGC9ILinX3CRms0pGkfCmeMmd_GB'
},
'video/mp4; codecs="avc1.64001F, mp4a.40.2"' => {
'fmt' => 'video/mp4; codecs="avc1.64001F, mp4a.40.2"',
'resolution' => '1280x720',
'suffix' => 'mp4',
'url' => 'https://r8---sn-uo1-fabe.googlevideo.com/videoplayback?expire=1591286259&ei=k8XYXrpTgbi-BOKUl8AC&ip=222.155.23.220&id=o-ACzVrS0ntoeNxkxf5Eyq0kh40yqw_H8JvAo6oomIF0vi&itag=22&source=youtube&requiressl=yes&mh=nM&mm=31%2C29&mn=sn-uo1-fabe%2Csn-ntqe6nes&ms=au%2Crdu&mv=m&mvi=7&pl=21&initcwndbps=1255000&vprv=1&mime=video%2Fmp4&ratebypass=yes&dur=2664.791&lmt=1471517080079780&mt=1591264536&fvip=5&c=WEB&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cratebypass%2Cdur%2Clmt&sig=AOq0QJ8wRQIhAKbSlz0qjINeYyhN1BhyEcEJk6uWrx4ZAqe-EQdr4AW0AiAL68CXNXGq39ov1k0UEbYTGiKb7J6xQCYT2Me7Zk3ZRA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgSfHsoUVS7LVwrzJNCrTEJI7T9Fmj3j6Mt8bDeFrdM0ECIB6Nvdhmdk3Y929DlGC9ILinX3CRms0pGkfCmeMmd_GB'
}
}
}, 'correct data structure';

done_testing;

__DATA__
4 changes: 2 additions & 2 deletions t/youtube.t
Expand Up @@ -29,10 +29,10 @@ sub check_video_fetch_url {
is $code, 200;
}

# YAPC video 1
# YAPC video 1
check_video_fetch_url('Y1I1KcKvz9Q');

# YAPC video 2
# YAPC video 2
check_video_fetch_url('oAkasBMJJ18');

done_testing;

0 comments on commit 72647c7

Please sign in to comment.