{ me, lib, pkgs, auxiliaryPkgs, ... }: let inherit (lib) substring toUpper getExe ; # todo: move this to a utils package capitalize = str: toUpper (substring 0 1 str) + substring 1 (-1) str; user = "mel"; # per machine sunshine settings perMachine = { # wolfram has an arc b570 gpu optimized for transcoding, # and is the primary streaming machine wolfram = { adapter_name = "/dev/dri/renderD128"; # primary card should be located here encoder = "vaapi"; # or "qsv" is quicksync is better supported av1_mode = 2; }; # bismuth has a radeon rx 9070 xt, and is only # used when streaming from wolfram is impossible, # as it's my personal desktop machine. bismuth = { adapter_name = "/dev/dri/renderD128"; # primary card should be located here encoder = "amdvce"; av1_mode = 0; hevc_mode = 2; }; }; in { services.sunshine = { enable = true; autoStart = true; capSysAdmin = true; openFirewall = true; settings = { sunshine_name = capitalize me.name; # no need for encryption since we are going through a secure network anyway lan_encryption_mode = 0; wan_encryption_mode = 0; origin_web_ui_allowed = "wan"; # allow access everywhere gamepad = "auto"; # to support ds5 and steam deck controllers } // perMachine.${me.name}; applications = { env = { # give sunshine access to binaries (we can install stuff into .local/bin if we want) PATH = "$(PATH):/run/current-system/sw/bin:/etc/profiles/per-user/${user}/bin:$(HOME)/.local/bin"; }; apps = let command = name: cmd: getExe ( pkgs.writeShellApplication { inherit name; runtimeInputs = with pkgs; [ steam util-linux ]; text = "sudo -u ${user} ${cmd}"; } ); in [ # moondeck will call this app when connecting via moonlight, automatically { name = "MoonDeckStream"; cmd = "${auxiliaryPkgs.moondeck-buddy}/bin/MoonDeckStream"; image-path = "${auxiliaryPkgs.moondeck-buddy}/share/icons/hicolor/256x256/apps/moondeckbuddy.png"; exclude-global-prep-cmd = "false"; elevated = "false"; } # other applications, called manually { name = "Desktop"; image-path = "desktop.png"; # empty commands will always simply open desktop } { name = "Steam"; image-path = "steam.png"; detached = [ (command "sunshine-open-steam-bp" "steam steam://open/bigpicture") ]; prep-cmd = [ { do = ""; undo = command "sunshine-close-steam-bp" "steam steam://close/bigpicture"; # close up steam } ]; # sunshine can't track the steam startup properly, so don't. auto-detach = "true"; wait-all = "true"; exit-timeout = "5"; } ]; }; }; # run the buddy app for the moondeck for a nicer integration of sunshine/moonlight # when using a steam deck! systemd.user.services.moondeck-buddy = { description = "MoonDeck Buddy"; wantedBy = [ "graphical-session.target" ]; partOf = [ "graphical-session.target" ]; after = [ "graphical-session.target" "network-online.target" ]; serviceConfig = { ExecStart = "${getExe auxiliaryPkgs.moondeck-buddy}"; # try to stay alive even if something moondeck-buddy depends on, # like steam, crashes. Restart = "on-failure"; RestartSec = "5s"; Environment = "QT_QPA_PLATFORM=wayland"; }; }; networking.firewall.allowedTCPPorts = [ 59999 ]; # port for moondeck-buddy }