diff options
author | trizen <trizen@protonmail.com> | 2020-06-05 21:17:42 +0300 |
---|---|---|
committer | Jesús <heckyel@hyperbola.info> | 2020-06-06 21:52:47 -0500 |
commit | 754e30726f3af7d28a8b6e505fc44754f3b6f353 (patch) | |
tree | 21a8849803b733c0c69db6c48546f81af679f0f7 | |
parent | 99ccfc9f20f89f0034da5647a3b8abfb5fa5387d (diff) | |
download | fair-viewer-754e30726f3af7d28a8b6e505fc44754f3b6f353.tar.lz fair-viewer-754e30726f3af7d28a8b6e505fc44754f3b6f353.tar.xz fair-viewer-754e30726f3af7d28a8b6e505fc44754f3b6f353.zip |
- Added basic support for related videos. (fixes https://github.com/trizen/straw-viewer/issues/15)
Example:
fair-viewer --related [video-id / URL]
This also implements support for `--autoplay`, which is based on related videos.
Thanks to @aearil for reporting this issue.
Signed-off-by: Jesús <heckyel@hyperbola.info>
-rwxr-xr-x | bin/fair-viewer | 10 | ||||
-rw-r--r-- | lib/WWW/FairViewer/Search.pm | 94 | ||||
-rw-r--r-- | lib/WWW/FairViewer/Utils.pm | 2 |
3 files changed, 102 insertions, 4 deletions
diff --git a/bin/fair-viewer b/bin/fair-viewer index 85244a3..7f3377c 100755 --- a/bin/fair-viewer +++ b/bin/fair-viewer @@ -3779,7 +3779,9 @@ sub print_videos { ) { if ($opt{play_backwards}) { #if (defined $info->{prevPageToken}) { - __SUB__->($yv_obj->previous_page($url), auto => 1); + if (defined($url)) { + __SUB__->($yv_obj->previous_page($url), auto => 1); + } #} #else { # $opt{play_backwards} = 0; @@ -3789,7 +3791,9 @@ sub print_videos { } else { #if (defined $info->{nextPageToken}) { + if (defined($url)) { __SUB__->($yv_obj->next_page($url), auto => 1); + } #} #else { # $opt{play_all} = 0; @@ -3844,8 +3848,10 @@ sub print_videos { } elsif ($opt =~ /^(?:n|next)\z/) { #if (defined $info->{nextPageToken}) { + if (defined($url)) { my $request = $yv_obj->next_page($url); __SUB__->($request, @keywords ? (auto => 1) : ()); + } #} #else { # warn_last_page(); @@ -3858,7 +3864,9 @@ sub print_videos { } elsif ($opt =~ /^(?:b|back|p|prev|previous)\z/) { #if (defined $info->{prevPageToken}) { + if (defined($url)) { __SUB__->($yv_obj->previous_page($url), @keywords ? (auto => 1) : ()); + } #} #else { # warn_first_page(); diff --git a/lib/WWW/FairViewer/Search.pm b/lib/WWW/FairViewer/Search.pm index 3858b39..5660218 100644 --- a/lib/WWW/FairViewer/Search.pm +++ b/lib/WWW/FairViewer/Search.pm @@ -144,8 +144,98 @@ be set to a YouTube video ID. =cut sub related_to_videoID { - my ($self, $id) = @_; - return $self->search_for('video', [], {relatedToVideoId => $id}); + my ($self, $videoID) = @_; + + my %info = $self->_get_video_info($videoID); + my $watch_next_response = $self->parse_json_string($info{watch_next_response}); + my $related = eval { $watch_next_response->{contents}{twoColumnWatchNextResults}{secondaryResults}{secondaryResults}{results} } // return { results => []}; + + my @results; + + foreach my $entry(@$related) { + + my $info = $entry->{compactVideoRenderer} // next; + my $title = $info->{title}{simpleText} // next; + + my $viewCount = 0; + + if ($info->{viewCountText}{simpleText} =~ /^([\d,]+) views/) { + $viewCount = ($1 =~ tr/,//dr); + } + + my $lengthSeconds = 0; + + if ($info->{lengthText}{simpleText} =~ /([\d:]+)/) { + my $time = $1; + my @fields = split(/:/, $time); + + my $seconds = pop(@fields) // 0; + my $minutes = pop(@fields) // 0; + my $hours = pop(@fields) // 0; + + $lengthSeconds = 3600 * $hours + 60*$minutes + $seconds; + } + + my $published = 0; + if (exists $info->{publishedTimeText} and $info->{publishedTimeText}{simpleText} =~ /(\d+)\s+(\w+)\s+ago/) { + + my $quantity = $1; + my $period = $2; + + $period =~ s/s\z//; # make it singural + + my %table = ( + year => 31556952, # seconds in a year + month => 2629743.83, # seconds in a month + week => 604800, # seconds in a week + day => 86400, # seconds in a day + minute => 60, # seconds in a minute + second => 1, # seconds in a second + ); + + if (exists $table{$period}) { + $published = int(time - $quantity * $table{$period}); + } + else { + warn "BUG: cannot parse: <<$quantity $period>>"; + } + } + + push @results, { + type => "video", + title => $title, + videoId => $info->{videoId}, + author => $info->{longBylineText}{runs}[0]{text}, + authorId => $info->{longBylineText}{runs}[0]{navigationEndpoint}{browseEndpoint}{browseId}, + #authorUrl => $info->{longBylineText}{runs}[0]{navigationEndpoint}{browseEndpoint}{browseId}, + + description => $info->{accessibility}{accessibilityData}{label}, + descriptionHtml => undef, + viewCount => $viewCount, + published => $published, + publishedText => $info->{publishedTimeText}{simpleText}, + lengthSeconds => $lengthSeconds, + liveNow => ($lengthSeconds == 0), # maybe it's live if lengthSeconds == 0? + paid => 0, + premium => 0, + + videoThumbnails => [ + map { + scalar { + quality => 'medium', + url => $_->{url}, + width => $_->{width}, + height => $_->{height}, + } + } @{$info->{thumbnail}{thumbnails}} + ], + }; + } + + return scalar { + url => undef, + results => \@results, + }; } =head1 AUTHOR diff --git a/lib/WWW/FairViewer/Utils.pm b/lib/WWW/FairViewer/Utils.pm index 01dde3b..e50bf3f 100644 --- a/lib/WWW/FairViewer/Utils.pm +++ b/lib/WWW/FairViewer/Utils.pm @@ -453,7 +453,7 @@ Get description. sub get_description { my ($self, $info) = @_; - my $desc = $info->{descriptionHtml} // ''; + my $desc = $info->{descriptionHtml} // $info->{description} // ''; require URI::Escape; require HTML::Entities; |