p5-www-youtube-download
p5-www-youtube-download copied to clipboard
unexpected end of string while parsing JSON string
youtube-download.pl https://www.youtube.com/watch?v=NqVE9qfg7yI unexpected end of string while parsing JSON string, at character offset 2 (before "rgs:{raw_player_resp...") at E:\Downloads\youtube-download.pl line 61.
I tried with a different video and it also dies like this. I don't have the bandwidth to fix it, but I'd welcome a PR for this.
The code was changed and now it looks like we have vars instead of the needed data in the JSON structure. I also had to change the regex to match on it.
{args:{raw_player_response:window.ytplayer.bootstrapPlayerResponse}}
This will fix the reported bug and it does start downloading but VERY slowly. I suspect there's some throttle we need to manipulate on the download.
diff --git a/lib/WWW/YouTube/Download.pm b/lib/WWW/YouTube/Download.pm
index b00d2a6..b01d33f 100644
--- a/lib/WWW/YouTube/Download.pm
+++ b/lib/WWW/YouTube/Download.pm
@@ -157,8 +157,7 @@ sub prepare_download {
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});
+ my $player_resp = $self->_get_player_response($content);
$video_url_map = $self->_decode_player_response($player_resp);
$title = decode_entities $player_resp->{videoDetails}{title};
$user = decode_entities $player_resp->{videoDetails}{author};
@@ -285,7 +284,7 @@ sub _get_content {
return $res->content;
}
-sub _get_args {
+sub _get_player_response {
my ($self, $content) = @_;
my $data;
@@ -294,15 +293,15 @@ sub _get_args {
if ($line =~ /the uploader has not made this video available in your country/i) {
croak 'Video not available in your country';
}
- elsif ($line =~ /^.+ytplayer\.config\s*=\s*(\{.*})/) {
- ($data, undef) = JSON->new->utf8(1)->decode_prefix($1);
+ elsif ($line =~ /^.+ytInitialPlayerResponse\s*=\s*(\{.*});/) {
+ ($data, undef) = JSON->new->utf8(1)->decode_prefix($1);
last;
}
}
- croak 'failed to extract JSON data' unless $data->{args};
+ croak 'failed to extract JSON data' unless $data;
- return $data->{args};
+ return $data;
}
sub _is_new {
@toddr do you want to create a PR?
I see someone talking about having to re-start the download. that'd be a different case.
Try the newest version of Youtube-dl. I was under the impression that they circumvented much of the throttling in later versions (by automatically re-connecting when the speed goes down. Apparently the first few seconds of the connection isn't throttled, as I understand it.)
@toddr do you want to create a PR?
I'm only hacking downloads. looks like I'd have to fix all of the get_args callers and fix a lot of tests.
Whatever works, but if you want to make it less broken than it currently is, that's a start. :)