aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortrizen <trizen@protonmail.com>2020-06-05 21:17:42 +0300
committerJesús <heckyel@hyperbola.info>2020-06-06 21:52:47 -0500
commit754e30726f3af7d28a8b6e505fc44754f3b6f353 (patch)
tree21a8849803b733c0c69db6c48546f81af679f0f7
parent99ccfc9f20f89f0034da5647a3b8abfb5fa5387d (diff)
downloadfair-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-xbin/fair-viewer10
-rw-r--r--lib/WWW/FairViewer/Search.pm94
-rw-r--r--lib/WWW/FairViewer/Utils.pm2
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;