115 lines
2.5 KiB
Perl
115 lines
2.5 KiB
Perl
|
#!/usr/bin/env perl
|
||
|
|
||
|
use strict;
|
||
|
use warnings;
|
||
|
use Data::Dumper;
|
||
|
|
||
|
my $selection = $ARGV[0];
|
||
|
|
||
|
my $app = {};
|
||
|
|
||
|
if (defined $selection) {
|
||
|
select_sink($app, $selection);
|
||
|
} else {
|
||
|
show_sinks($app);
|
||
|
}
|
||
|
|
||
|
# -----------
|
||
|
# Subroutines
|
||
|
# -----------
|
||
|
sub show_sinks {
|
||
|
my ($app) = @_;
|
||
|
|
||
|
my @sinks = get_sinks($app);
|
||
|
print join("\n", @sinks);
|
||
|
}
|
||
|
|
||
|
# -----------
|
||
|
sub select_sink {
|
||
|
my ($app, $sink) = @_;
|
||
|
|
||
|
my $wp_h;
|
||
|
my ($id,$name) = $sink =~ /(\d+):(.*)/;
|
||
|
my $seld_sink = "NONE";
|
||
|
my $seld_id = "NONE";
|
||
|
|
||
|
open($wp_h, "pw-cli info $id |") or die "Could not run pw-cli command";
|
||
|
|
||
|
while (my $ln = <$wp_h>) {
|
||
|
if (my ($node_name) = $ln =~ /node.name\s*=\s*"(.*)"/) {
|
||
|
warn "Selected [$id] ($name) - $node_name\n";
|
||
|
$seld_sink = $node_name;
|
||
|
$seld_id = $id;
|
||
|
last;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
enable_sink($app, $seld_sink, $seld_id);
|
||
|
}
|
||
|
|
||
|
# -----------
|
||
|
sub enable_sink {
|
||
|
my ($app, $sink, $id) = @_;
|
||
|
|
||
|
`wpctl set-default $id`;
|
||
|
unmute_master($app);
|
||
|
}
|
||
|
|
||
|
# -----------
|
||
|
sub unmute_master {
|
||
|
my ($app) = @_;
|
||
|
|
||
|
`amixer -c 0 set Master unmute`;
|
||
|
}
|
||
|
|
||
|
# -----------
|
||
|
sub parse_wpctl {
|
||
|
my $wp_h;
|
||
|
|
||
|
open($wp_h, "wpctl status |") or die "Could not run wpctl command";
|
||
|
|
||
|
my @lines = <$wp_h>;
|
||
|
|
||
|
my $section = "None";
|
||
|
my $sub_section = "None";
|
||
|
my $wp_data = {};
|
||
|
|
||
|
foreach my $ln (@lines) {
|
||
|
# Section
|
||
|
if (my ($mat) = $ln =~ /(^(PipeWire)|^(\w+)$)/) {
|
||
|
$section = $mat;
|
||
|
$wp_data->{$section} = {} unless (exists $wp_data->{$section});
|
||
|
}
|
||
|
|
||
|
# Sub-section
|
||
|
if (my ($mat) = $ln =~ /\s+(\w+):$/) {
|
||
|
$sub_section = $mat;
|
||
|
$wp_data->{$section}->{$sub_section} = [] unless (exists $wp_data->{$section}->{$sub_section});
|
||
|
}
|
||
|
|
||
|
# Entries
|
||
|
if (($section ne "None") && ($sub_section ne "None")) {
|
||
|
if (my ($sel, $id, $name) = $ln =~ /\s+(\*)?\s+(\d+)\.\s+(.*?)(\[|$)/) {
|
||
|
my $seld = (defined $sel) ? 1 : 0;
|
||
|
$name =~ s/^\s*//; $name =~ s/\s*$//;
|
||
|
push(@{$wp_data->{$section}->{$sub_section}}, {
|
||
|
'sel' => $seld,
|
||
|
'id' => $id,
|
||
|
'name' => $name
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$app->{'wp_data'} = $wp_data;
|
||
|
}
|
||
|
|
||
|
# -----------
|
||
|
sub get_sinks {
|
||
|
my ($app) = @_;
|
||
|
|
||
|
parse_wpctl($app);
|
||
|
# warn Data::Dumper->Dump([$app->{'wp_data'}]);
|
||
|
|
||
|
return map { "$_->{'id'}:$_->{'name'}" } @{$app->{'wp_data'}->{'Audio'}->{'Sinks'}}
|
||
|
}
|