App-YTDL
view release on metacpan or search on metacpan
lib/App/YTDL/Download.pm view on Meta::CPAN
package # hide from PAUSE
App::YTDL::Download;
use warnings;
use strict;
use 5.010000;
use Exporter qw( import );
our @EXPORT_OK = qw( download );
use Term::ANSIScreen qw( :cursor :screen );
use Term::Choose qw( choose );
use App::YTDL::Helper qw( HIDE_CURSOR SHOW_CURSOR uni_system );
END { print SHOW_CURSOR }
sub _choose_fmts {
my ( $data, $ex, $up, $id, $title ) = @_;
my $fmt_to_info = $data->{$ex}{$up}{$id}{fmt_to_info};
my ( @choices, @format_ids );
if ( ( keys %$fmt_to_info )[0] =~ /^\s*\d/ ) {
no warnings 'numeric';
for my $fmt ( sort { $a <=> $b } keys %$fmt_to_info ) {
if ( $fmt_to_info->{$fmt}{format} =~ /^\Q$fmt\E\s*-\s*(.+)\z/ ) {
push @choices, sprintf '%3s - %s %s', $fmt, $1, $fmt_to_info->{$fmt}{ext};
}
else {
push @choices, $fmt_to_info->{$fmt}{format} . ' ' . $fmt_to_info->{$fmt}{ext};
}
push @format_ids, $fmt;
}
}
else {
for my $fmt ( sort { $a cmp $b } keys %$fmt_to_info ) {
push @choices, $fmt_to_info->{$fmt}{format} . ' ' . $fmt_to_info->{$fmt}{ext};
push @format_ids, $fmt;
}
}
my @relative_formats = ( 'best', 'bestaudio' );
push @choices, @relative_formats;
push @format_ids, @relative_formats;
my @fmt_data;
while ( 1 ) {
my $prompt = 'Fmt: ';
my @pre = ( undef );
my $menu = [ @pre, @choices ];
# Choose
my $idx = choose(
$menu,
{ prompt => $prompt . join( '', @fmt_data ), index => 1, order => 1, undef => '<<', info => $title }
);
if ( ! defined $idx || ! defined $menu->[$idx] ) {
return if ! @fmt_data;
pop @fmt_data;
pop @fmt_data;
next;
}
push @fmt_data, @format_ids[ $idx - @pre ];
my $enough = ' OK';
@pre = ( undef, $enough );
my $ops = [
[ '+', " + " ],
[ ',', " , " ],
[ '/', " / " ],
];
$menu = [ @pre, map( $_->[1], @$ops ) ];
# Choose
( run in 2.317 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )