Skip to content

Commit

Permalink
- Added support for changing the youtube-dl command.
Browse files Browse the repository at this point in the history
Provided via the 'ytdl_cmd' config-option.

- Added support for disabling the use of youtube-dl.

When enabled (default), youtube-dl will be used for extracting info for videos with encrypted signatures.
When disabled, invidious instances will be used instead.

Provided via the `ytdl` config-option and the `--ytdl` and `--no-ytdl` command-line options.
  • Loading branch information
trizen committed Oct 10, 2020
1 parent 404fe98 commit 6e41b9c
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 25 deletions.
22 changes: 18 additions & 4 deletions bin/gtk2-youtube-viewer
Expand Up @@ -15,7 +15,7 @@
#-------------------------------------------------------
# GTK YouTube Viewer
# Created on: 12 September 2010
# Latest edit on: 17 September 2020
# Latest edit on: 10 October 2020
# https://github.com/trizen/youtube-viewer
#-------------------------------------------------------

Expand Down Expand Up @@ -225,6 +225,10 @@ my %CONFIG = (
fullscreen => 0,
audio_only => 0,

# youtube-dl support
ytdl => 1,
ytdl_cmd => undef, # auto-detect

tooltips => 1,
tooltip_max_len => 512, # max length of description in tooltips

Expand Down Expand Up @@ -668,6 +672,16 @@ foreach my $path ($CONFIG{cache_dir}) {
}
}

# Locate youtube-dl
if (not defined $CONFIG{ytdl_cmd}) {
if (defined(my $path = which_command('youtube-dl'))) {
$CONFIG{ytdl_cmd} = $path;
}
else {
$CONFIG{ytdl_cmd} = 'youtube-dl';
}
}

# Locate video player
if (not $CONFIG{video_player_selected}) {

Expand Down Expand Up @@ -815,8 +829,8 @@ sub apply_configuration {
publishedAfter publishedBefore
regionCode videoCategoryId
debug http_proxy user_agent
timeout cookie_file prefer_mp4
prefer_av1
timeout cookie_file ytdl ytdl_cmd
prefer_mp4 prefer_av1
)
) {

Expand Down Expand Up @@ -2973,7 +2987,7 @@ sub get_player_command {
);

if ($streaming->{streaming}{url} =~ m{^https://www\.youtube\.com/watch\?v=}) {
$cmd =~ s{ --no-ytdl\b}{ }g;
$cmd =~ s{\s*--no-ytdl\b}{ }g;
}

$has_video ? $cmd : join(' ', $cmd, quotemeta($streaming->{streaming}{url}));
Expand Down
22 changes: 18 additions & 4 deletions bin/gtk3-youtube-viewer
Expand Up @@ -15,7 +15,7 @@
#-------------------------------------------------------
# GTK YouTube Viewer
# Created on: 12 September 2010
# Latest edit on: 17 September 2020
# Latest edit on: 10 October 2020
# https://github.com/trizen/youtube-viewer
#-------------------------------------------------------

Expand Down Expand Up @@ -226,6 +226,10 @@ my %CONFIG = (
fullscreen => 0,
audio_only => 0,

# youtube-dl support
ytdl => 1,
ytdl_cmd => undef, # auto-detect

tooltips => 1,
tooltip_max_len => 512, # max length of description in tooltips

Expand Down Expand Up @@ -739,6 +743,16 @@ foreach my $path ($CONFIG{cache_dir}) {
}
}

# Locate youtube-dl
if (not defined $CONFIG{ytdl_cmd}) {
if (defined(my $path = which_command('youtube-dl'))) {
$CONFIG{ytdl_cmd} = $path;
}
else {
$CONFIG{ytdl_cmd} = 'youtube-dl';
}
}

# Locate video player
if (not $CONFIG{video_player_selected}) {

Expand Down Expand Up @@ -887,8 +901,8 @@ sub apply_configuration {
publishedAfter publishedBefore
regionCode videoCategoryId
debug http_proxy user_agent
timeout cookie_file prefer_mp4
prefer_av1
timeout cookie_file ytdl ytdl_cmd
prefer_mp4 prefer_av1
)
) {

Expand Down Expand Up @@ -3120,7 +3134,7 @@ sub get_player_command {
);

if ($streaming->{streaming}{url} =~ m{^https://www\.youtube\.com/watch\?v=}) {
$cmd =~ s{ --no-ytdl\b}{ }g;
$cmd =~ s{\s*--no-ytdl\b}{ }g;
}

$has_video ? $cmd : join(' ', $cmd, quotemeta($streaming->{streaming}{url}));
Expand Down
38 changes: 32 additions & 6 deletions bin/youtube-viewer
Expand Up @@ -15,7 +15,7 @@
#-------------------------------------------------------
# youtube-viewer
# Created on: 02 June 2010
# Latest edit on: 17 September 2020
# Latest edit on: 10 October 2020
# https://github.com/trizen/youtube-viewer
#-------------------------------------------------------

Expand Down Expand Up @@ -267,6 +267,10 @@ my %CONFIG = (
convert_cmd => 'ffmpeg -i *IN* *OUT*',
convert_to => undef,

# youtube-dl support
ytdl => 1,
ytdl_cmd => undef, # auto-defined

custom_layout => undef, # auto-defined
custom_layout_format => [{width => 3, align => "right", color => "bold", text => "*NO*.",},
{width => "55%", align => "left", color => "bold blue", text => "*TITLE*",},
Expand Down Expand Up @@ -462,7 +466,7 @@ sub load_config {
$update_config = 1;
}

# Locating a video player
# Locate video player
if (not $CONFIG{video_player_selected}) {

foreach my $key (sort keys %{$CONFIG{video_players}}) {
Expand All @@ -480,6 +484,21 @@ sub load_config {
}
}

# Locate youtube-dl
if (not defined($CONFIG{ytdl_cmd})) {

my $ytdl_path = which_command('youtube-dl');

if (defined($ytdl_path)) {
$CONFIG{ytdl_cmd} = $ytdl_path;
}
else {
$CONFIG{ytdl_cmd} = 'youtube-dl';
}

$update_config = 1;
}

# Download with wget if it is installed
if (not defined $CONFIG{download_with_wget}) {

Expand Down Expand Up @@ -850,7 +869,9 @@ usage: $execname [options] ([url] | [keywords])
--dash! : include or exclude the DASH itags
--dash-mp4a! : include or exclude the itags for MP4 audio streams
--dash-segmented! : include or exclude segmented DASH streams
--ytdl! : use youtube-dl for videos with encrypted signatures
`--no-ytdl` will use invidious instances
--ytdl-cmd=s : youtube-dl command (default: youtube-dl)
Help options:
-T --tricks : show more 'hidden' features of $execname
Expand Down Expand Up @@ -1145,12 +1166,13 @@ sub apply_configuration {
safeSearch regionCode debug hl
http_proxy page comments_order
subscriptions_order user_agent
cookie_file timeout prefer_mp4
prefer_av1
cookie_file timeout ytdl ytdl_cmd
prefer_mp4 prefer_av1
)
) {

if (defined $opt->{$option_name}) {

my $code = \&{"WWW::YoutubeViewer::set_$option_name"};
my $value = delete $opt->{$option_name};
my $set_value = $yv_obj->$code($value);
Expand Down Expand Up @@ -1656,6 +1678,9 @@ sub parse_arguments {
'pos|position=i' => \$opt{position},
'ps|playlist-save=s' => \$opt{playlist_save},

'ytdl!' => \$opt{ytdl},
'ytdl-cmd=s' => \$opt{ytdl_cmd},

'quiet|q!' => \$opt{quiet},
'really-quiet!' => \$opt{really_quiet},
'video-info!' => \$opt{show_video_info},
Expand Down Expand Up @@ -3315,6 +3340,7 @@ sub download_video {

# Convert the downloaded video
if (defined $opt{convert_to}) {

my $convert_filename = catfile($opt{downloads_dir}, "$naked_filename.$opt{convert_to}");
my $convert_cmd = $opt{convert_cmd};

Expand Down Expand Up @@ -3435,7 +3461,7 @@ sub get_player_command {
);

if ($streaming->{streaming}{url} =~ m{^https://www\.youtube\.com/watch\?v=}) {
$cmd =~ s{ --no-ytdl\b}{ }g;
$cmd =~ s{\s*--no-ytdl\b}{ }g;
}

$has_video ? $cmd : join(' ', $cmd, quotemeta($streaming->{streaming}{url}));
Expand Down
32 changes: 21 additions & 11 deletions lib/WWW/YoutubeViewer.pm
Expand Up @@ -7,6 +7,7 @@ use warnings;
use Memoize;

memoize('_get_video_info');
memoize('_ytdl_is_available');
memoize('_extract_from_ytdl');
memoize('_extract_from_invidious');

Expand Down Expand Up @@ -85,6 +86,10 @@ my %valid_options = (
cache_dir => {valid => qr/^./, default => q{.}},
cookie_file => {valid => qr/^./, default => undef},

# Support for youtube-dl
ytdl => {valid => [1, 0], default => 1},
ytdl_cmd => {valid => qr/\w/, default => "youtube-dl"},

# Booleans
env_proxy => {valid => [1, 0], default => 1},
escape_utf8 => {valid => [1, 0], default => 0},
Expand Down Expand Up @@ -242,7 +247,7 @@ sub set_lwp_useragent {
// do { require LWP::UserAgent; 'LWP::UserAgent' }
);

$self->{lwp} = $lwp->new(
my $agent = $lwp->new(

cookie_jar => {}, # temporary cookies
timeout => $self->get_timeout,
Expand Down Expand Up @@ -288,7 +293,6 @@ sub set_lwp_useragent {
HTTP::Message::decodable();
};

my $agent = $self->{lwp};
$agent->ssl_opts(Timeout => $self->get_timeout);
$agent->default_header('Accept-Encoding' => $accepted_encodings);
$agent->conn_cache($cache);
Expand Down Expand Up @@ -325,8 +329,9 @@ sub set_lwp_useragent {
$agent->cookie_jar($cookies);
}

push @{$self->{lwp}->requests_redirectable}, 'POST';
return $self->{lwp};
push @{$agent->requests_redirectable}, 'POST';
$self->{lwp} = $agent;
return $agent;
}

=head2 prepare_access_token()
Expand Down Expand Up @@ -572,7 +577,7 @@ sub select_good_invidious_instances {

my %ignored = (
'yewtu.be' => 1,
'invidiou.site' => 0,
'invidiou.site' => 1,
'invidious.xyz' => 1,
'vid.mint.lgbt' => 1,
'invidious.ggc-project.de' => 1,
Expand All @@ -586,7 +591,11 @@ sub select_good_invidious_instances {
grep { lc($_->[1]{type} // '') eq 'https' } @$instances;

if ($self->get_debug) {
print STDERR ":: Found ", scalar(@candidates), " invidious instances.\n";

my @hosts = map { $_->[0] } @candidates;
my $count = scalar(@candidates);

print STDERR ":: Found $count invidious instances: @hosts\n";
}

return @candidates;
Expand All @@ -601,15 +610,13 @@ sub _extract_from_invidious {
require List::Util;
@instances = List::Util::shuffle(map { $_->[0] } @instances);
push @instances, 'invidious.snopyta.org';
push @instances, 'invidious.13ad.de';
}
else {
@instances = qw(
invidious.tube
invidious.site
invidious.fdn.fr
invidious.snopyta.org
invidious.13ad.de
);
}

Expand Down Expand Up @@ -649,15 +656,16 @@ sub _extract_from_invidious {
}

sub _ytdl_is_available {
(state $x = system('youtube-dl', '--version')) == 0;
my ($self) = @_;
($self->proxy_stdout($self->get_ytdl_cmd(), '--version') // '') =~ /\d/;
}

sub _extract_from_ytdl {
my ($self, $videoID) = @_;

$self->_ytdl_is_available() || return;

my @ytdl_cmd = ('youtube-dl', '--all-formats', '--dump-single-json');
my @ytdl_cmd = ($self->get_ytdl_cmd(), '--all-formats', '--dump-single-json');

my $cookie_file = $self->get_cookie_file;

Expand Down Expand Up @@ -693,7 +701,7 @@ sub _fallback_extract_urls {
my @formats;

# Use youtube-dl
if ($self->_ytdl_is_available) {
if ($self->get_ytdl and $self->_ytdl_is_available) {

if ($self->get_debug) {
say STDERR ":: Using youtube-dl to extract the streaming URLs...";
Expand Down Expand Up @@ -1116,6 +1124,8 @@ sub from_page_token {
local $ENV{HTTP_PROXY} = $self->{lwp}->proxy('http');
local $ENV{HTTPS_PROXY} = $self->{lwp}->proxy('https');

local $" = " ";

$name eq 'exec' ? exec(@args)
: $name eq 'system' ? system(@args)
: $name eq 'stdout' ? qx(@args)
Expand Down

0 comments on commit 6e41b9c

Please sign in to comment.