Rofi to select pipewire sink
This commit is contained in:
parent
5623991a73
commit
f5ab4aad25
114
rofi_sound.pl
Executable file
114
rofi_sound.pl
Executable file
@ -0,0 +1,114 @@
|
||||
#!/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'}}
|
||||
}
|
Loading…
Reference in New Issue
Block a user