App-MediaPi
view release on metacpan or search on metacpan
script/mediapi view on Meta::CPAN
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use lib '/usr/local/lib/perl5'; # To be used together with the cpanm command given in the README.md file.
BEGIN {
$ENV{DISPLAY} //= ':0';
}
use IPC::Run;
use Tkx;
use X11::Protocol;
$| = 1; # auto-flush
my ($screen_x, $screen_y);
{
my $X = X11::Protocol->new();
$screen_x = $X->{screens}[0]{width_in_pixels} // 320;
$screen_y = $X->{screens}[0]{height_in_pixels} // 240;
}
open my $pigpio, '>', '/dev/pigpio';
my $wnd = Tkx::widget->new('.');
# fullscreen removes the border of the window but does not actually make it
# fullscreen (maybe because we donât have a real window manager... which also
# means that we donât have a border anyway).
$wnd->g_wm_attribute(-fullscreen => 1, -topmost => 1);
$wnd->g_wm_resizable(0, 0);
$wnd->configure(-cursor => 'none');
$wnd->g_wm_geometry("${screen_x}x${screen_y}");
my $media_control_frame = $wnd->new_ttk__frame(-borderwidth => 5); # The border is here only to debug
$media_control_frame->g_grid(-column => 0, -row => 0, -sticky => 'nswe');
$wnd->g_grid_columnconfigure(0, -weight => 1);
$wnd->g_grid_rowconfigure(0, -weight => 1);
# The default font does not have the media control glyphs. So letâs create a
# style using Unifont that has almost all glyphs.
# Useful link: https://en.wikipedia.org/wiki/Media_control_symbols
Tkx::ttk__style_configure('Unicode.TButton', -font => 'Unifont 15');
$media_control_frame->g_grid_columnconfigure(0, -weight => 1);
$media_control_frame->g_grid_columnconfigure(1, -weight => 1);
$media_control_frame->g_grid_rowconfigure(0, -weight => 1);
$media_control_frame->g_grid_rowconfigure(1, -weight => 1);
my $vlc_in;
my $vlc_out;
# my $vlc = IPC::Run::start ['vlc', '--intf', 'rc', '--alsa-audio-device', 'dac'], $vlc_in;
my $vlc = IPC::Run::start ['vlc', '--intf', 'rc'], $vlc_in, \$vlc_out;
$vlc_in = '';
$vlc_out = '';
# Itâs unclear what is the default volume and what is the real max level that can
# be set. So, for now, we do nothing.
my $cmd_sent = 0;
my $cmd_read = 0;
my %cmd_cb;
sub send_cmd {
my ($cmd, $sub) = @_;
if ($cmd_read < $cmd_sent) {
# In theory we could send multiple command. Unfortunately, in practice, VLC
# will sometime answer with multiple answers in a row, without the
# separating carret. So letâs slow down.
Tkx::after('idle', sub { send_cmd($cmd, $sub) });
return;
}
$vlc_in .= $cmd."\n" if defined $cmd;
$cmd_sent++;
print "Sending command ${cmd_sent}\n";
if (defined $sub) {
$cmd_cb{$cmd_sent} = $sub;
}
pump_vlc_in();
}
sub pump_vlc_in {
print "pumping: $vlc_in\n";
IPC::Run::pump $vlc if length $vlc_in;
print "pump! ($vlc_in)\n";
if (length $vlc_in) {
Tkx::after('idle', \&pump_vlc_in);
} else {
pump_vlc_out();
}
}
sub pump_vlc_out {
IPC::Run::pump_nb $vlc;
print "pumping (read): -->${vlc_out}<--\n";
if ($vlc_out =~ m/^> /m) {
$cmd_read++;
my $cmd_out = substr $vlc_out, 0, $-[0];
substr $vlc_out, 0, $+[0], '';
print "Read command output (${cmd_read})\n";
if (my $cb = delete $cmd_cb{$cmd_read}) {
$cb->($cmd_out);
( run in 0.540 second using v1.01-cache-2.11-cpan-5735350b133 )