Browse Source

Added yt-dlp-gui - a GUI-wrapper writen on Perl for yt-dlp for playing videos in external mediaplayer

master
Sergey Kiselev 8 months ago
parent
commit
f08ede350a
  1. 25
      README.md
  2. BIN
      images/yt-dlp-gui.png
  3. 163
      yt-dlp-gui

25
README.md

@ -39,12 +39,33 @@ __ytdl-gui__
![](images/ytdl-gui.png) ![](images/ytdl-gui.png)
GUI-обёртка над `www/yt-dlp` для воспроизведения видео с [RuTube](https://rutube.ru) и других видеохостингов с помощью [mpv](https://mpv.io/). GUI-обёртка над `www/yt-dlp` для воспроизведения видео с
[RuTube](https://rutube.ru) и других видеохостингов с помощью
[mpv](https://mpv.io/).
Для работы скрипта требуются следующие утилиты: Для работы скрипта требуются следующие утилиты:
- `yt-dlp` (`www/yt-dlp`); - `yt-dlp` (`www/yt-dlp`);
- `yad` (`x11/yad`); - `yad` (`x11/yad`);
- `mpv` (`multimedia/mpv`) - `mpv` (`multimedia/mpv`).
---
__yt-dlp-gui__
![](images/yt-dlp-gui.png)
GUI-обёртка над `www/yt-dlp` для воспроизведения видео с
[RuTube](https://rutube.ru) и других видеохостингов с помощью
[mpv](https://mpv.io/).
В отличии от `ytdl-gui` написан на [Perl](https://www.perl.org/) и
[Gtk3](https://docs.gtk.org/gtk3/).
Для работы скрипта требуются следующие компоненты:
- `perl5` (`lang/perl5.38`);
- `p5-Gtk3` (`x11-toolkits/p5-Gtk3`);
- `p5-Glib` (`devel/p5-Glib`);
- `yt-dlp` (`www/yt-dlp`);
- `mpv` (`multimedia/mpv`).
--- ---

BIN
images/yt-dlp-gui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

163
yt-dlp-gui

@ -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…
Cancel
Save