This commit is contained in:
Erwin Boskma 2021-12-06 09:58:39 +01:00
parent 3fa467e483
commit 875a74c99b
Signed by: erwin
GPG key ID: 270B20D17394F7E5
25 changed files with 201 additions and 209 deletions

View file

@ -105,7 +105,6 @@
(import (./machines/loki/configuration.nix) { inherit self; }) (import (./machines/loki/configuration.nix) { inherit self; })
]; ];
}; };
}; };
} // } //
(flake-utils.lib.eachSystem [ "aarch64-linux" "x86_64-linux" ]) (flake-utils.lib.eachSystem [ "aarch64-linux" "x86_64-linux" ])
@ -128,11 +127,13 @@
packages = flake-utils.lib.flattenTree { packages = flake-utils.lib.flattenTree {
rofi-wayland = pkgs.rofi-wayland; rofi-wayland = pkgs.rofi-wayland;
nix-plugins = pkgs.nix-plugins; nix-plugins = pkgs.nix-plugins;
backscrub = pkgs.backscrub;
}; };
apps = { apps = {
rofi-wayland = flake-utils.lib.mkApp { drv = packages.rofi-wayland; }; rofi-wayland = flake-utils.lib.mkApp { drv = packages.rofi-wayland; };
nix-plugins = flake-utils.lib.mkApp { drv = packages.nix-plugins; }; nix-plugins = flake-utils.lib.mkApp { drv = packages.nix-plugins; };
backscrub = flake-utils.lib.mkApp { drv = packages.backscrub; };
}; };
devShell = with pkgs; mkShell { devShell = with pkgs; mkShell {

View file

@ -36,7 +36,7 @@ in
separator_color = "frame"; separator_color = "frame";
sort = "yes"; sort = "yes";
idle_threshold = 120; idle_threshold = 120;
font = "Iosevka Nerd Font 10"; font = "Meslo Nerd Font 10";
line_height = 0; line_height = 0;
markup = "full"; markup = "full";
format = "%s %p\\n%b"; format = "%s %p\\n%b";

View file

@ -10,8 +10,8 @@ in
}; };
config = mkIf (cfg.enable) { config = mkIf (cfg.enable) {
home.file.electron_conf = mkIf (cfg.wayland) { xdg.configFile.electron_conf = mkIf (cfg.wayland) {
target = ".config/electron-flags.conf"; target = "electron-flags.conf";
text = '' text = ''
--enable-features=UseOzonePlatform --enable-features=UseOzonePlatform
--ozone-platform=wayland --ozone-platform=wayland

View file

@ -35,8 +35,8 @@ in
# code = "${pkgs.vscode}/bin/code --enable-features=UseOzonePlatform --ozone-platform=wayland"; # code = "${pkgs.vscode}/bin/code --enable-features=UseOzonePlatform --ozone-platform=wayland";
ls = "${pkgs.exa}/bin/exa -Fb"; ls = "${pkgs.exa}/bin/exa -Fb";
}; };
# interactiveShellInit = '' interactiveShellInit = ''
# ''; '';
}; };
programs.starship = { programs.starship = {

View file

@ -103,6 +103,11 @@ in
enable = true; enable = true;
settings = { settings = {
git_protocol = "ssh"; git_protocol = "ssh";
editor = "nvim";
prompt = "enabled";
pager = "bat";
http_unix_socket = "";
browser = "";
}; };
}; };
}; };

View file

@ -120,6 +120,7 @@ in
"${mod}+7" = "workspace number 7"; "${mod}+7" = "workspace number 7";
"${mod}+8" = "workspace number 8"; "${mod}+8" = "workspace number 8";
"${mod}+9" = "workspace number 9"; "${mod}+9" = "workspace number 9";
"${mod}+0" = "workspace number 10";
"${mod}+Shift+1" = "${mod}+Shift+1" =
"move container to workspace number 1"; "move container to workspace number 1";
@ -139,6 +140,8 @@ in
"move container to workspace number 8"; "move container to workspace number 8";
"${mod}+Shift+9" = "${mod}+Shift+9" =
"move container to workspace number 9"; "move container to workspace number 9";
"${mod}+Shift+0" =
"move container to workspace number 10";
"${mod}+Shift+minus" = "move scratchpad"; "${mod}+Shift+minus" = "move scratchpad";
"${mod}+minus" = "scratchpad show"; "${mod}+minus" = "scratchpad show";
@ -180,12 +183,13 @@ in
for_window [app_id="^.*"] inhibit_idle fullscreen for_window [app_id="^.*"] inhibit_idle fullscreen
for_window [class="^.*"] inhibit_idle fullscreen for_window [class="^.*"] inhibit_idle fullscreen
for_window [app_id="gnome-calculator"] floating enable for_window [app_id="gnome-calculator"] floating enable
for_window [shell="xwayland"] title_format "%title [XWayland]"
# exec_always --no-startup-id systemctl --user import-environment _JAVA_AWT_WM_NONREPARENTING MOZ_ENABLE_WAYLAND MOZ_DBUS_REMOTE QT_QPA_PLATFORM QT_WAYLAND_DISABLE_WINDOWDECORATION QT_QPA_PLATFORMTHEME SDL_VIDEODRIVER SSH_AUTH_SOCK # exec_always --no-startup-id systemctl --user import-environment _JAVA_AWT_WM_NONREPARENTING MOZ_ENABLE_WAYLAND MOZ_DBUS_REMOTE QT_QPA_PLATFORM QT_WAYLAND_DISABLE_WINDOWDECORATION QT_QPA_PLATFORMTHEME SDL_VIDEODRIVER SSH_AUTH_SOCK
# exec_always --no-startup-id dbus-update-activation-environment --systemd _JAVA_AWT_WM_NONREPARENTING MOZ_ENABLE_WAYLAND MOZ_DBUS_REMOTE QT_QPA_PLATFORM QT_WAYLAND_DISABLE_WINDOWDECORATION QT_QPA_PLATFORMTHEME SDL_VIDEODRIVER SSH_AUTH_SOCK # exec_always --no-startup-id dbus-update-activation-environment --systemd _JAVA_AWT_WM_NONREPARENTING MOZ_ENABLE_WAYLAND MOZ_DBUS_REMOTE QT_QPA_PLATFORM QT_WAYLAND_DISABLE_WINDOWDECORATION QT_QPA_PLATFORMTHEME SDL_VIDEODRIVER SSH_AUTH_SOCK
exec --no-startup-id ${pkgs.networkmanagerapplet}/bin/nm-applet --indicator exec --no-startup-id ${pkgs.networkmanagerapplet}/bin/nm-applet --indicator
exec --no-startup-id ${pkgs.swayidle}/bin/swayidle -w timeout 900 ${swaylockcmd}; exec --no-startup-id ${pkgs.swayidle}/bin/swayidle -w timeout 900 -- ${swaylockcmd}
exec --no-startup-id ${pkgs.swayidle}/bin/swayidle -w 1200 ${pkgs.sway}/bin/swaymsg 'output * dpms off' resume ${pkgs.sway}/bin/swaymsg 'output * dpms off'; exec --no-startup-id ${pkgs.swayidle}/bin/swayidle -w 1200 -- ${pkgs.sway}/bin/swaymsg 'output * dpms off' resume ${pkgs.sway}/bin/swaymsg 'output * dpms off'
include /etc/sway/config.d/* include /etc/sway/config.d/*
''; '';

View file

@ -1,7 +1,9 @@
{ {
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.fontFamily": "Iosevka Nerd Font", "editor.fontFamily": "Iosevka Nerd Font",
"workbench.iconTheme": "vscode-icons", "workbench.iconTheme": "Monokai Pro Icons",
"workbench.enableExperiments": false,
"workbench.preferredDarkColorTheme": "Monokai Pro",
"editor.fontLigatures": true, "editor.fontLigatures": true,
"vsicons.dontShowNewVersionMessage": true, "vsicons.dontShowNewVersionMessage": true,
"workbench.startupEditor": "newUntitledFile", "workbench.startupEditor": "newUntitledFile",
@ -422,6 +424,10 @@
"editor.wordSeparators": "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-", "editor.wordSeparators": "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-",
"editor.wordWrap": "off", "editor.wordWrap": "off",
"editor.tabSize": 2, "editor.tabSize": 2,
"editor.minimap.enabled": false,
"editor.bracketPairColorization.enabled": true,
"python.formatting.provider": "black",
"telemetry.telemetryLevel": "off",
"[typescript]": { "[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features" "editor.defaultFormatter": "vscode.typescript-language-features"
}, },
@ -455,11 +461,10 @@
"[python]": { "[python]": {
"editor.tabSize": 4 "editor.tabSize": 4
}, },
"editor.minimap.enabled": false,
"editor.bracketPairColorization.enabled": true,
"[nix]": { "[nix]": {
"editor.defaultFormatter": "aaronduino.nix-lsp" "editor.defaultFormatter": "aaronduino.nix-lsp"
}, },
"python.formatting.provider": "black", "[rust]": {
"telemetry.telemetryLevel": "off" "editor.tabSize": 4
}
} }

View file

@ -3,6 +3,7 @@
imports = [ ./hardware-configuration.nix ../../users/erwin ../../users/root ]; imports = [ ./hardware-configuration.nix ../../users/erwin ../../users/root ];
eboskma = { eboskma = {
backscrub.enable = true;
base = { base = {
plymouth.enable = true; plymouth.enable = true;
work = false; work = false;
@ -23,11 +24,15 @@
networking = { networking = {
enable = true; enable = true;
dhcpInterfaces = [ "enp4s0" ]; dhcpInterfaces = [ "enp4s0" ];
hosts = {
"10.0.0.252" = [ "pve.datarift.nl" ];
};
}; };
nix-common = { nix-common = {
enable = true; enable = true;
}; };
sound.enable = true; sound.enable = true;
systemd.enable = true;
}; };
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;

View file

@ -5,7 +5,8 @@
{ {
imports = imports =
[ (modulesPath + "/installer/scan/not-detected.nix") [
(modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ]; boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
@ -14,23 +15,25 @@
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
fileSystems."/" = fileSystems."/" =
{ device = "/dev/disk/by-uuid/42065c7e-d0aa-4de8-a913-014cf59d48ac"; {
device = "/dev/disk/by-uuid/42065c7e-d0aa-4de8-a913-014cf59d48ac";
fsType = "ext4"; fsType = "ext4";
}; };
fileSystems."/boot" = fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/4064-A1BE"; {
device = "/dev/disk/by-uuid/4064-A1BE";
fsType = "vfat"; fsType = "vfat";
}; };
fileSystems."/home" = fileSystems."/home" =
{ device = "/dev/disk/by-uuid/36d7ee19-f591-4c29-b7da-cafd9bf2c7f6"; {
device = "/dev/disk/by-uuid/36d7ee19-f591-4c29-b7da-cafd9bf2c7f6";
fsType = "ext4"; fsType = "ext4";
}; };
swapDevices = swapDevices =
[ { device = "/dev/disk/by-uuid/d93788f7-1b94-4687-8313-055d17f42b7e"; } [{ device = "/dev/disk/by-uuid/d93788f7-1b94-4687-8313-055d17f42b7e"; }];
];
# high-resolution display # high-resolution display
hardware.video.hidpi.enable = lib.mkDefault true; hardware.video.hidpi.enable = lib.mkDefault true;

View file

@ -1,12 +1,13 @@
ha_now_playing_token: ENC[AES256_GCM,data:2NKdfEn0tQx+DTE6HBVo79Ico8+afqJ2XFaBVOgIikaL4eMa34CqHwhX91T64VVdmWyjvhaC1kRzxsALoJvw1ZHEnSG2va6lX0vN36j/n8R3ulcX23ZJetMHYQQE6ss7A+gvnBHTnTBG+F9XyrPFT7xnfQ363lWHQ3nRFiGAZJjj6eYqLxSuG7KMWHtfSozy5gSy2JKoxyV4KnqpDs39PhBmNA7OSh3FRYZPIaq+i4qhdCfHRET+,iv:Znl6IW36aqhL/KBr0cRgPBPtqkhuc1GtoqCQEQJ/cXI=,tag:ubvLck9m9qiutU2zcQtdDw==,type:str] ha_now_playing_token: ENC[AES256_GCM,data:2NKdfEn0tQx+DTE6HBVo79Ico8+afqJ2XFaBVOgIikaL4eMa34CqHwhX91T64VVdmWyjvhaC1kRzxsALoJvw1ZHEnSG2va6lX0vN36j/n8R3ulcX23ZJetMHYQQE6ss7A+gvnBHTnTBG+F9XyrPFT7xnfQ363lWHQ3nRFiGAZJjj6eYqLxSuG7KMWHtfSozy5gSy2JKoxyV4KnqpDs39PhBmNA7OSh3FRYZPIaq+i4qhdCfHRET+,iv:Znl6IW36aqhL/KBr0cRgPBPtqkhuc1GtoqCQEQJ/cXI=,tag:ubvLck9m9qiutU2zcQtdDw==,type:str]
gh_token: ENC[AES256_GCM,data:7DBVEdZLReJQsyUoO9fITtHhE0UFcHr7XWod5XiaQ5iiwcI01tUdRA==,iv:HY82pn2rp9zf+xHWRg6Zwbl5V2qgp+67LghxHRQjiMI=,tag:OrkwDDYpJLXnsWZvqBtY9g==,type:str]
sops: sops:
kms: [] kms: []
gcp_kms: [] gcp_kms: []
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2021-11-25T22:00:28Z" lastmodified: "2021-11-29T09:10:11Z"
mac: ENC[AES256_GCM,data:yhO2fjE5BwdAF9Hj69k2tTgxr/gOVTZrkWNCJD/bkSX6rZLuMWQ4XqUSPiZ1/lRTliUnvnpOWqm3Fnvh7Nbhydyd6wyzwI799mSczLu4OUAImpCAfF6X95RGJ50lXQE+e/rO6+YwuWqS8FaRdgjWRBT3fvqoSYhqypiTRxVw0ew=,iv:+XxbiT49RnC+lqrbnLvzkH1nljNindQjYiCZ2cPyHDE=,tag:k3WIVby2WjSpDrv4SjYoRQ==,type:str] mac: ENC[AES256_GCM,data:TLXP58YOqyrHx3u//bK64yOsgmzaP8GPyCSMdABeQKMeejVwavNtQS+b2zuq8/58T/AYPajhmmPznoChpSrzqUk51pLclAG/jWAZ5Z/tv7sOv7q4zak4+HZx38zfuKNqr7U4cuo5n/vWhnXiJRNN9vz4OzXNBn4gUm+FTGX98Gg=,iv:iCY+pFC4JNtMPwtqeBLdJ2t6fxgVJrqU3LLhLgXT/xY=,tag:gIz59GuqjSul4CPsUYPT2g==,type:str]
pgp: pgp:
- created_at: "2021-11-25T22:00:17Z" - created_at: "2021-11-25T22:00:17Z"
enc: | enc: |

View file

@ -0,0 +1,27 @@
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.eboskma.backscrub;
in
{
options.eboskma.backscrub = {
enable = mkEnableOption "enable v4l2loopback kernel module";
};
config = mkIf (cfg.enable) {
boot.extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ];
# Register a v4l2loopback device at boot
boot.kernelModules = [
"v4l2loopback"
];
boot.extraModprobeConfig = ''
options v4l2loopback max_buffers=2
options v4l2loopback exclusive_caps=1
options v4l2loopback video_nr=10
options v4l2loopback card_label="VirtualCam"
'';
environment.systemPackages = with pkgs; [ backscrub ];
};
}

View file

@ -38,8 +38,11 @@ in
programs.fish.enable = true; programs.fish.enable = true;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
dig
dogdns dogdns
file file
usbutils
ht-rust
]; ];
}; };
} }

View file

@ -72,7 +72,8 @@ in
fd fd
git git
gnome.nautilus gnome.nautilus
jetbrains.clion imagemagick
(jetbrains.clion.override { jdk = pkgs.jetbrains.jdk; })
neovim neovim
nomachine-client nomachine-client
pamedia pamedia
@ -164,6 +165,7 @@ in
services = { services = {
dbus.packages = [ pkgs.gcr ]; dbus.packages = [ pkgs.gcr ];
avahi.publish.workstation = true;
}; };
security = { security = {

View file

@ -17,6 +17,7 @@ in
dejavu_fonts dejavu_fonts
google-fonts google-fonts
kochi-substitute kochi-substitute
material-icons
noto-fonts-emoji noto-fonts-emoji
corefonts corefonts
recursive recursive

View file

@ -10,6 +10,11 @@ in
description = "list of interfaces to enable DHCP on"; description = "list of interfaces to enable DHCP on";
type = types.listOf types.nonEmptyStr; type = types.listOf types.nonEmptyStr;
}; };
hosts = mkOption {
description = "Additional entries to the hosts file";
type = types.attrsOf (types.listOf types.str);
};
}; };
config = mkIf (cfg.enable) { config = mkIf (cfg.enable) {
@ -21,7 +26,17 @@ in
value = { useDHCP = true; }; value = { useDHCP = true; };
}) })
cfg.dhcpInterfaces); cfg.dhcpInterfaces);
hosts = cfg.hosts;
}; };
users.extraUsers.${config.eboskma.var.mainUser}.extraGroups = [ "networkmanager" ]; users.extraUsers.${config.eboskma.var.mainUser}.extraGroups = [ "networkmanager" ];
services.avahi = {
enable = true;
nssmdns = true;
publish = {
enable = true;
domain = true;
};
};
}; };
} }

View file

@ -0,0 +1,16 @@
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.eboskma.systemd;
in
{
options.eboskma.systemd = {
enable = mkEnableOption "activate systemd settings";
};
config = mkIf (cfg.enable) {
services.resolved = {
enable = true;
};
};
}

View file

@ -1,13 +1,9 @@
final: prev: { final: prev: {
rofi-wayland = prev.pkgs.callPackage ../pkgs/rofi-wayland { }; rofi-wayland = prev.pkgs.callPackage ../pkgs/rofi-wayland { };
nix-plugins = prev.pkgs.callPackage ../pkgs/nix-plugins { }; nix-plugins = prev.pkgs.callPackage ../pkgs/nix-plugins { };
lunarvim = prev.pkgs.callPackage ../../pkgs/lunarvim { }; lunarvim = prev.pkgs.callPackage ../pkgs/lunarvim { };
# pamedia = prev.pkgs.callPackage ../pkgs/pamedia { backscrub = prev.pkgs.callPackage ../pkgs/backscrub
# buildPythonPackage = prev.pkgs.python3.pkgs.buildPythonPackage; {
# pulsectl = prev.pkgs.python39Packages.pulsectl; inherit (prev.pkgs) gcc cmake opencv curl stdenv git tensorflow-lite flatbuffers;
# pygobject3 = prev.pkgs.python39Packages.pygobject3; };
# gobject-introspection = prev.pkgs.gobject-introspection;
# libnotify = prev.pkgs.libnotify;
# lib = prev.pkgs.lib;
# };
} }

View file

@ -0,0 +1,17 @@
{ stdenv, fetchFromGitHub, cmake, opencv, gcc, curl, git, tensorflow-lite, flatbuffers }:
stdenv.mkDerivation {
name = "backscrub";
pname = "backscrub";
src = fetchFromGitHub {
owner = "floe";
repo = "backscrub";
rev = "6fc5d8d6c022ad38f98d90a24b861f12a8773a47";
fetchSubmodules = false;
sha256 = "14gd77m7dy0wg15y0i8zhki8cm7np2spx7yi162b2xqaav04b1cj";
};
nativeBuildInputs = [ gcc cmake git ];
buildInputs = [ opencv curl tensorflow-lite flatbuffers ];
patches = [ ./fix-cmake-for-nixos.patch ];
}

View file

@ -0,0 +1,69 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b7b425e..deff68d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,10 +7,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# allow override of Tensorflow location
-if(NOT DEFINED TENSORFLOW)
- set(TENSORFLOW tensorflow)
- set(TF_CHECKOUT true)
-endif()
+#if(NOT DEFINED TENSORFLOW)
+# set(TENSORFLOW tensorflow)
+# set(TF_CHECKOUT true)
+#endif()
# find Git and use it to get backscrub version
find_package(Git)
@@ -31,16 +31,16 @@ set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs video videoio highgui)
# use .gitmodules defined Tensorflow version unless a path was provided
-if (TF_CHECKOUT)
- if (GIT_FOUND)
- message(STATUS "Updating Tensorflow source")
- execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive)
- else()
- message(FATAL_ERROR "Git not found. Unable to checkout required Tensorflow version")
- endif()
-else()
- message(STATUS "Using specified Tensorflow: ${TENSORFLOW}")
-endif(TF_CHECKOUT)
+#if (TF_CHECKOUT)
+# if (GIT_FOUND)
+# message(STATUS "Updating Tensorflow source")
+# execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive)
+# else()
+# message(FATAL_ERROR "Git not found. Unable to checkout required Tensorflow version")
+# endif()
+#else()
+# message(STATUS "Using specified Tensorflow: ${TENSORFLOW}")
+#endif(TF_CHECKOUT)
# force compilation of XNNPACK delegate (without this the too clever-by-half use
# of weak/strong symbol linking fails in a static library)
@@ -52,8 +52,12 @@ set(CONFU_DEPENDENCIES_SOURCE_DIR ${CMAKE_BINARY_DIR})
set(CONFU_DEPENDENCIES_BINARY_DIR ${CMAKE_BINARY_DIR}/_deps)
# pull in Tensorflow Lite source build
-add_subdirectory(${TENSORFLOW}/tensorflow/lite
- "${CMAKE_CURRENT_BINARY_DIR}/tensorflow-lite" EXCLUDE_FROM_ALL)
+#add_subdirectory(${TENSORFLOW}/tensorflow/lite
+# "${CMAKE_CURRENT_BINARY_DIR}/tensorflow-lite" EXCLUDE_FROM_ALL)
+
+find_library(tensorflow-lite NAMES tensorflow-lite REQUIRED)
+
+find_package(Threads REQUIRED)
# build backscrub code
add_compile_definitions(DEEPSEG_VERSION=${DEEPSEG_VERSION})
@@ -91,6 +95,7 @@ target_link_libraries(deepseg
opencv_imgproc
opencv_imgcodecs
opencv_highgui
+ Threads::Threads
)
endif()

View file

@ -1,28 +0,0 @@
{ pkgs, ... }:
with pkgs;
let
buildPythonPackage = python3.pkgs.buildPythonPackage;
pulsectl = python3.pkgs.pulsectl;
pygobject3 = python3.pkgs.pygobject3;
in
buildPythonPackage rec {
pname = "pamedia";
version = "0.1.0";
src = ./src;
buildInputs = [
gobject-introspection
libnotify
];
propagatedBuildInputs = [
pulsectl
pygobject3
];
meta = {
description = "Change volume of the PulseAudio default sink";
license = lib.licenses.mit;
};
}

View file

@ -1,123 +0,0 @@
#!/usr/bin/env python3
import argparse
import pulsectl
import gi
gi.require_version("Notify", "0.7")
from gi.repository import GLib
from gi.repository import Notify
class PAMedia:
def __init__(self, sink=None):
self.client = pulsectl.Pulse("volumectl")
sinks = self.client.sink_list()
if sink == None:
self.sink = self.client.get_sink_by_name(
self.client.server_info().default_sink_name
)
else:
if sink > len(sinks):
notification = Notify.Notification.new(
"Volume", f"Unknown sink index '{sink}', using default sink"
)
notification.show()
self.sink = self.client.get_sink_by_name(
self.client.server_info().default_sink_name
)
self.sink = sinks[sink]
def toggle_mute(self):
self.client.mute(self.sink, mute=not self.sink.mute)
def volume_up(self):
self.client.mute(self.sink, mute=False)
self.client.volume_change_all_chans(self.sink, 0.05)
def volume_down(self):
self.client.mute(self.sink, mute=False)
self.client.volume_change_all_chans(self.sink, -0.05)
def volume_set(self, new_volume):
new_volume = min(100, max(0, int(new_volume)))
self.client.volume_set_all_chans(self.sink, new_volume / 100.0)
def list_sinks(self):
for num, sink in enumerate(self.client.sink_list()):
print(f"[{num}] {sink.description}")
def icon(self):
if self.sink.mute:
return "muted"
elif self.sink.volume.value_flat <= 0.3:
return "low"
elif self.sink.volume.value_flat <= 0.7:
return "medium"
else:
return "high"
def notify(self):
icon = f"audio-volume-{self.icon()}"
title = f"Volume"
if self.sink.mute:
title = "Muted"
notification = Notify.Notification.new(title, "", icon)
if not self.sink.mute:
notification.set_hint(
"x-canonical-private-synchronous", GLib.Variant.new_string("audio")
)
notification.set_hint("value", GLib.Variant.new_int32(round(self.volume())))
notification.show()
def volume(self):
return self.sink.volume.value_flat * 100
def volume_format(self):
volume = round(self.volume())
return f"{volume}%"
def main():
parser = argparse.ArgumentParser(description="PulseAudio volume control")
parser.add_argument("-s", "--sink", type=int, help="Select output sink to control")
parser.add_argument(
"command",
metavar="CMD",
type=str,
nargs="+",
help="Command, one of: mute, up, down, set, get, sinks",
)
args = parser.parse_args()
ctl = PAMedia(sink=args.sink)
Notify.init("volumectl")
if args.command[0] == "mute":
ctl.toggle_mute()
elif args.command[0] == "up":
ctl.volume_up()
elif args.command[0] == "down":
ctl.volume_down()
elif args.command[0] == "get":
print(f"Volume: {ctl.volume_format()}")
exit(0)
elif args.command[0] == "set" and len(args.command) >= 2:
ctl.volume_set(args.command[1])
elif args.command[0] == "sinks":
ctl.list_sinks()
exit(0)
else:
print(f"Unknown command '{args.command}'")
parser.print_help()
exit(1)
ctl.notify()

View file

@ -1,5 +0,0 @@
from . import main
if __name__ == '__main__':
main()

View file

@ -1,3 +0,0 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

View file

@ -1,15 +0,0 @@
[metadata]
name = pamedia
version = 0.1.0
description = Small utility to control the volume of the default PulseAudio sink, including notifications. Also compatible with Pipewire with the PulseAudio compatibility interface
author = "Erwin Boskma <erwin@datarift.nl>"
[options]
packages = pamedia
install_requires =
pulsectl
PyGObject
[options.entry_points]
console_scripts =
pamedia = pamedia:main

View file

@ -1,4 +0,0 @@
from setuptools import setup
if __name__ == "__main__":
setup()