Sergey Kiselev
8 months ago
3 changed files with 186 additions and 2 deletions
After Width: | Height: | Size: 24 KiB |
@ -0,0 +1,163 @@ |
|||||
|
#!/usr/local/bin/perl |
||||
|
|
||||
|
use strict; |
||||
|
use warnings; |
||||
|
|
||||
|
use utf8; |
||||
|
use open qw/:std :encoding(utf8)/; |
||||
|
binmode(STDOUT, ":utf8"); |
||||
|
|
||||
|
use Gtk3 '-init'; |
||||
|
use Glib "TRUE", "FALSE"; |
||||
|
|
||||
|
my $wnd = Gtk3::Window::new(); |
||||
|
my @labels = undef; |
||||
|
my %chks = ( |
||||
|
ontop => { o => 1, opt => ' --ontop', lbl => 'On-Top', chk => undef }, |
||||
|
border => { o => 2, opt => ' --no-border', lbl => 'Without borders', chk => undef }, |
||||
|
alldesk => { o => 3, opt => ' --on-all-workspaces', lbl => 'On all workspaces', chk => undef} |
||||
|
); |
||||
|
my $txt_URL = Gtk3::Entry->new(); |
||||
|
my $txt_Title = Gtk3::Entry->new(); |
||||
|
my $cb_Resolution = Gtk3::ComboBoxText->new(); |
||||
|
my $cb_Scale = Gtk3::ComboBoxText->new(); |
||||
|
my $btn_Get = Gtk3::Button->new_from_icon_name("gtk-find", 4); |
||||
|
|
||||
|
_ui(); |
||||
|
|
||||
|
Gtk3::main(); |
||||
|
|
||||
|
sub _ui { |
||||
|
my $vbox = Gtk3::VBox::new(); |
||||
|
my $grid = Gtk3::Grid->new(); |
||||
|
my $grid_btn = Gtk3::Grid->new(); |
||||
|
my $grid_opt = Gtk3::Grid->new(); |
||||
|
my $grid_header = Gtk3::Grid->new(); |
||||
|
|
||||
|
my $btn_Cancel = Gtk3::Button->new_from_stock("gtk-cancel"); |
||||
|
my $btn_Ok = Gtk3::Button->new_from_stock("gtk-ok"); |
||||
|
|
||||
|
my $img = Gtk3::Image->new_from_icon_name("youtube", 6); |
||||
|
$img->set_halign("start"); |
||||
|
|
||||
|
$wnd->set_title("yt-dlp GUI"); |
||||
|
$wnd->set_default_size(480, 240); |
||||
|
$wnd->set_icon_name("youtube"); |
||||
|
$wnd->set_position("center"); |
||||
|
$wnd->set_border_width(20); |
||||
|
$wnd->set_resizable(FALSE); |
||||
|
$wnd->signal_connect( destroy => sub { Gtk3->main_quit } ); |
||||
|
|
||||
|
$grid->set_column_spacing(10); |
||||
|
$grid->set_row_spacing(10); |
||||
|
$grid->set_hexpand(TRUE); |
||||
|
|
||||
|
$grid_btn->set_column_spacing(10); |
||||
|
$grid_btn->set_row_spacing(10); |
||||
|
$grid_btn->set_halign("end"); |
||||
|
$grid_btn->set_valign("end"); |
||||
|
|
||||
|
$grid_opt->set_column_spacing(10); |
||||
|
$grid_opt->set_row_spacing(10); |
||||
|
$grid_opt->set_hexpand(TRUE); |
||||
|
|
||||
|
$grid_header->set_column_spacing(10); |
||||
|
$grid_header->set_row_spacing(0); |
||||
|
$grid_header->set_hexpand(TRUE); |
||||
|
|
||||
|
foreach ( "Video URL:", "Title:", "Resolution:", "Scale:" ) { |
||||
|
push(@labels, Gtk3::Label->new($_)); |
||||
|
$labels[$#labels]->set_halign("start"); |
||||
|
$grid->attach($labels[$#labels], 0, $#labels, 1, 1); |
||||
|
} |
||||
|
|
||||
|
my @k = ( sort { $chks{$a}{o} <=> $chks{$b}{o} } keys %chks ); |
||||
|
while ( my ($i, $k) = each @k ) { |
||||
|
$chks{$k}{chk} = Gtk3::CheckButton->new_with_label($chks{$k}{lbl}); |
||||
|
$grid_opt->attach($chks{$k}{chk}, 0, $i, 1, 1); |
||||
|
} |
||||
|
|
||||
|
foreach ( "x0.5", "x1", "x2" ) { |
||||
|
$cb_Scale->append_text( $_ ); |
||||
|
} |
||||
|
$cb_Scale->set_active(1); |
||||
|
|
||||
|
$txt_URL->set_halign("fill"); |
||||
|
$txt_URL->set_hexpand(TRUE); |
||||
|
$txt_Title->set_halign("fill"); |
||||
|
$txt_Title->set_hexpand(TRUE); |
||||
|
$cb_Resolution->set_halign("start"); |
||||
|
$cb_Resolution->set_hexpand(FALSE); |
||||
|
$cb_Scale->set_halign("start"); |
||||
|
$cb_Scale->set_hexpand(FALSE); |
||||
|
|
||||
|
$btn_Get->signal_connect( clicked => \&_get_info ); |
||||
|
$btn_Cancel->signal_connect( clicked => sub { $wnd->destroy } ); |
||||
|
$btn_Ok->signal_connect( clicked => \&_play ); |
||||
|
|
||||
|
$grid_header->attach($img, 0, 1, 1, 1); |
||||
|
$grid_header->attach(Gtk3::Label->new("Please enter video URL"), 1, 1, 1, 1); |
||||
|
|
||||
|
$grid->attach($txt_URL, 1, 1, 2, 1); |
||||
|
$grid->attach($btn_Get, 3, 1, 1, 1); |
||||
|
$grid->attach($txt_Title, 1, 2, 3, 1); |
||||
|
$grid->attach($cb_Resolution, 1, 3, 1, 1); |
||||
|
$grid->attach($cb_Scale, 1, 4, 1, 1); |
||||
|
$grid->attach($grid_opt, 2, 3, 1, 4); |
||||
|
|
||||
|
$grid_btn->attach($btn_Ok, 0, 1, 1, 1); |
||||
|
$grid_btn->attach($btn_Cancel, 1, 1, 1, 1); |
||||
|
|
||||
|
$vbox->add($grid_header); |
||||
|
$vbox->add($grid); |
||||
|
$vbox->add($grid_btn); |
||||
|
|
||||
|
$wnd->add($vbox); |
||||
|
|
||||
|
$wnd->show_all; |
||||
|
} |
||||
|
|
||||
|
sub _get_info { |
||||
|
my $url = $txt_URL->get_text(); |
||||
|
my @out = qx{yt-dlp --no-warnings --quiet --list-formats "$url" | grep -v "audio" | awk '\$2=="mp4" {print \$3}' | uniq | awk -F'x' '{print \$2"p"}'}; |
||||
|
my $title = qx{yt-dlp --no-warnings --quiet --get-title "$url"}; |
||||
|
|
||||
|
foreach ( @out ) { |
||||
|
$_ =~ s/[\r\n]+$//; |
||||
|
$cb_Resolution->append_text( $_ ); |
||||
|
} |
||||
|
|
||||
|
$cb_Resolution->set_active(0); |
||||
|
|
||||
|
$txt_Title->set_text($title); |
||||
|
} |
||||
|
|
||||
|
sub _play { |
||||
|
my $res = $cb_Resolution->get_active_text(); |
||||
|
$res =~ s/p$//; |
||||
|
my $scale = $cb_Scale->get_active_text(); |
||||
|
$scale =~ s/^x//; |
||||
|
|
||||
|
my $opts = "--no-terminal"; |
||||
|
|
||||
|
my @k = ( sort { $chks{$a}{o} <=> $chks{$b}{o} } keys %chks ); |
||||
|
while ( my ($i, $k) = each @k ) { |
||||
|
if ( $chks{$k}{chk}->get_active ) { |
||||
|
$opts .= $chks{$k}{opt}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$opts .= " --window-scale=" . $scale; |
||||
|
|
||||
|
$opts .= " --ytdl-format=\"bv*[height<=$res]+ba/b[height<=$res] / wv*+ba/w\""; |
||||
|
|
||||
|
my $url = "\"" . $txt_URL->get_text() . "\""; |
||||
|
|
||||
|
my $cmd = "mpv $opts $url"; |
||||
|
|
||||
|
{ exec ($cmd) }; print STDERR "Couldn't exec mpv: $!"; |
||||
|
|
||||
|
$wnd->destroy(); |
||||
|
|
||||
|
exit 0; |
||||
|
} |
Loading…
Reference in new issue