Steam-Headless / docker-steam-headless

A Headless Steam Docker image supporting NVIDIA GPU and accessible via Web UI
GNU General Public License v2.0
730 stars 79 forks source link

Add local audio support for HDMI output. #143

Open tornadox opened 2 months ago

tornadox commented 2 months ago

Is your feature request related to a problem?

I have a fanless mini pc on N5105 chip, I would like to use it as a small media/streaming/light gaming device connected to my TV. It doesn't support properly GPU passtrough via VFIO, but I can get sound from unraid sound-driver https://github.com/ich777/unraid-sound-driver However what I tried I can't get sound in the container to work.

What is your feature request?

Please add audio passthrough to be used on HDMI output.

Are there any workarounds?

No response

Additional Context

No response

ehfd commented 2 months ago

To @Josh5 : There are manuals to do this in the x11docker wiki. I started off my project in 2020 from there.

Freddy-0 commented 1 week ago

I was playing around with this a few months ago. I got it working after some time. Since then I didn't have a proper setup to do some further testing. I will upload a cleaned documentation of my steps and I would love to get this tested and implemented at a later point. Which OS are you running?

tornadox commented 1 week ago

I was playing around with this a few months ago. I got it working after some time. Since then I didn't have a proper setup to do some further testing. I will upload a cleaned documentation of my steps and I would love to get this tested and implemented at a later point. Which OS are you running?

Unraid

Trozmagon commented 1 week ago

@Freddy-0 Unraid here also and an help test

Freddy-0 commented 1 week ago

Perfect. Same is true for me. When I cleaned the docs I will report back and hope we will get this working. Can you please give me some more informations on your system. Gpu(s), unraid version, anything you already did trying to get this working...

Trozmagon commented 1 week ago

I tried getting it working about 12 months ago but gave up and just went back to a VM, can't remember what I tried back then.

I have 2 GPUs I can test with, an Intel UHD 750 & an RTX 3090. Unraid version is 6.12.10

tornadox commented 1 week ago

Perfect. Same is true for me. When I cleaned the docs I will report back and hope we will get this working. Can you please give me some more informations on your system. Gpu(s), unraid version, anything you already did trying to get this working...

I have 2 configs One is that has VFIO working it's an i5-6600 with r9 270, well windows in vm works, I don't remember trying to get steam headless there at all. The daily setup that I wanted to use for some retro gaming is a fanless mini pc on N5105. Unraid is cool. But I'm fine switching to another OS, as this is not a NAS in my usual understanding.

Freddy-0 commented 1 week ago

To follow up on this. I am running a Unraid box with a gt710 as a primary GPU and a RTX 2070 as a secondary gpu. I obviously play games on the 2070. I tried to recreate all the steps i took to get Unraid working as a host for my "gaming tv"

I do not have a spare server atm to test this with, so i would be happy if you tested this config and gave me some feedback. Assuming a "fresh" System

Step 1: Install Nvidia Driver

Via the Plugins Tab

  1. Install un-get: Download and install un-get using the following URL:
    https://raw.githubusercontent.com/ich777/un-get/master/un-get.plg

Step 2: Install Audio Dependencies

Install Required Dependencies for PulseAudio and ALSA

Run the following command to update un-get and install the necessary packages:

un-get update && 
un-get install pulseaudio pavucontrol alsa-plugins libsndfile orc speexdsp doxygen libasyncns flac libvorbis opus libogg bluez sbc gstreamer alsa-lib alsa-utils alsa-oss

Optional: Install Bluetooth Firmware

To install Bluetooth firmware, if not already installed, run:

un-get install bluez-firmware

Step 3: Install Unraid Sound Driver

Via the Plugins Tab

  1. Download and install the Unraid Sound Driver Plugin:
    https://raw.githubusercontent.com/ich777/unraid-sound-driver/master/sound-driver.plg

Step 4: Install Userscripts

Add the Custom Script

  1. Create a script to be executed at the first array startup or on demand before starting the Steam-Headless docker. Use the following script content:

    #!/bin/bash
    
    # Custom Pulseaudio file
    CONTENT="#!/usr/bin/pulseaudio -nF
    .fail
    load-module module-device-restore
    load-module module-stream-restore
    load-module module-card-restore
    load-module module-augment-properties
    load-module module-switch-on-port-available
    .ifexists module-udev-detect.so
    load-module module-udev-detect
    .else
    load-module module-detect
    .endif
    .ifexists module-jackdbus-detect.so
    .nofail
    load-module module-jackdbus-detect channels=2
    .fail
    .endif
    .ifexists module-esound-protocol-unix.so
    load-module module-esound-protocol-unix
    .endif
    .ifexists module-gsettings.so
    .nofail
    load-module module-gsettings
    .fail
    .endif
    load-module module-default-device-restore
    load-module module-always-sink
    load-module module-intended-roles
    load-module module-suspend-on-idle
    .ifexists module-console-kit.so
    load-module module-console-kit
    .endif
    .ifexists module-systemd-login.so
    load-module module-systemd-login
    .endif
    load-module module-position-event-sounds
    load-module module-role-cork
    load-module module-filter-heuristics
    load-module module-filter-apply
    .nofail"
    
    # Filename
    FILENAME="/boot/config/pulseaudio.pa"
    
    # Check if the file exists
    echo "$CONTENT" > "$FILENAME"
    echo "Config file for Pulseaudio created: $FILENAME"
    
    # Disable Autospawn
    echo autospawn = no > /etc/pulse/client.conf
    echo allow-autospawn-for-root = no >> /etc/pulse/client.conf
    echo "Autospawn disabled in /etc/pulse/client.conf"
    
    # Remove any dangling pulseaudio socket
    rm /tmp/pulseaudio.socket/ -r
    
    # Configure Pulseaudio to use the custom config file
    echo default-script-file = /boot/config/pulseaudio.pa > /etc/pulse/daemon.conf
    echo "Pulseaudio configured to use the custom config file"
    
    # Start Pulseaudio as a daemon that never exits on idle
    pulseaudio -v --exit-idle-time=-1 -D
    echo "Pulseaudio started as a daemon"
    
    # Create the socket that the docker is going to connect to
    pacmd load-module module-native-protocol-unix auth-anonymous=true socket=/tmp/pulseaudio.socket
    echo "Socket created for docker to connect"
    
    sleep 15
    
    # Check if Pulseaudio is running
    pulseaudio --check -v

Step 5: Advanced Docker Configuration

Configure the Docker Container

In the advanced Docker editing mode, add the following extra parameters to run the container unprivileged:

--env PULSE_SERVER=unix:/tmp/pulseaudio.socket --volume /tmp/pulseaudio.socket:/tmp/pulseaudio.socket --device='/dev/snd' --runtime='nvidia'

Step 6: Verify Audio Configuration

Check HDMI Output Availability

Run the following command in the Docker terminal to check if a display is connected:

pactl list cards | grep hdmi-output | sed -e '/not available/s/.*/\x1b[31m&\x1b[0m/' -e '/available/s/.*/\x1b[32m&\x1b[0m/'
Trozmagon commented 1 week ago

I can give this a test on Thursday I reckon, I've just had a drive die and need to rebuild before hand. I'll let you know how I go with it.

Trozmagon commented 6 days ago

To follow up on this. I am running a Unraid box with a gt710 as a primary GPU and a RTX 2070 as a secondary gpu. I obviously play games on the 2070. I tried to recreate all the steps i took to get Unraid working as a host for my "gaming tv"

I do not have a spare server atm to test this with, so i would be happy if you tested this config and gave me some feedback. Assuming a "fresh" System

Step 1: Install Nvidia Driver

Via the Plugins Tab

  1. Install un-get: Download and install un-get using the following URL:
    https://raw.githubusercontent.com/ich777/un-get/master/un-get.plg

Step 2: Install Audio Dependencies

Install Required Dependencies for PulseAudio and ALSA

Run the following command to update un-get and install the necessary packages:

un-get update && 
un-get install pulseaudio pavucontrol alsa-plugins libsndfile orc speexdsp doxygen libasyncns flac libvorbis opus libogg bluez sbc gstreamer alsa-lib alsa-utils alsa-oss

Optional: Install Bluetooth Firmware

To install Bluetooth firmware, if not already installed, run:

un-get install bluez-firmware

Step 3: Install Unraid Sound Driver

Via the Plugins Tab

  1. Download and install the Unraid Sound Driver Plugin:
    https://raw.githubusercontent.com/ich777/unraid-sound-driver/master/sound-driver.plg

Step 4: Install Userscripts

Add the Custom Script

  1. Create a script to be executed at the first array startup or on demand before starting the Steam-Headless docker. Use the following script content:

    #!/bin/bash
    
    # Custom Pulseaudio file
    CONTENT="#!/usr/bin/pulseaudio -nF
    .fail
    load-module module-device-restore
    load-module module-stream-restore
    load-module module-card-restore
    load-module module-augment-properties
    load-module module-switch-on-port-available
    .ifexists module-udev-detect.so
    load-module module-udev-detect
    .else
    load-module module-detect
    .endif
    .ifexists module-jackdbus-detect.so
    .nofail
    load-module module-jackdbus-detect channels=2
    .fail
    .endif
    .ifexists module-esound-protocol-unix.so
    load-module module-esound-protocol-unix
    .endif
    .ifexists module-gsettings.so
    .nofail
    load-module module-gsettings
    .fail
    .endif
    load-module module-default-device-restore
    load-module module-always-sink
    load-module module-intended-roles
    load-module module-suspend-on-idle
    .ifexists module-console-kit.so
    load-module module-console-kit
    .endif
    .ifexists module-systemd-login.so
    load-module module-systemd-login
    .endif
    load-module module-position-event-sounds
    load-module module-role-cork
    load-module module-filter-heuristics
    load-module module-filter-apply
    .nofail"
    
    # Filename
    FILENAME="/boot/config/pulseaudio.pa"
    
    # Check if the file exists
    echo "$CONTENT" > "$FILENAME"
    echo "Config file for Pulseaudio created: $FILENAME"
    
    # Disable Autospawn
    echo autospawn = no > /etc/pulse/client.conf
    echo allow-autospawn-for-root = no >> /etc/pulse/client.conf
    echo "Autospawn disabled in /etc/pulse/client.conf"
    
    # Remove any dangling pulseaudio socket
    rm /tmp/pulseaudio.socket/ -r
    
    # Configure Pulseaudio to use the custom config file
    echo default-script-file = /boot/config/pulseaudio.pa > /etc/pulse/daemon.conf
    echo "Pulseaudio configured to use the custom config file"
    
    # Start Pulseaudio as a daemon that never exits on idle
    pulseaudio -v --exit-idle-time=-1 -D
    echo "Pulseaudio started as a daemon"
    
    # Create the socket that the docker is going to connect to
    pacmd load-module module-native-protocol-unix auth-anonymous=true socket=/tmp/pulseaudio.socket
    echo "Socket created for docker to connect"
    
    sleep 15
    
    # Check if Pulseaudio is running
    pulseaudio --check -v

Step 5: Advanced Docker Configuration

Configure the Docker Container

In the advanced Docker editing mode, add the following extra parameters to run the container unprivileged:

--env PULSE_SERVER=unix:/tmp/pulseaudio.socket --volume /tmp/pulseaudio.socket:/tmp/pulseaudio.socket --device='/dev/snd' --runtime='nvidia'

Step 6: Verify Audio Configuration

Check HDMI Output Availability

Run the following command in the Docker terminal to check if a display is connected:

pactl list cards | grep hdmi-output | sed -e '/not available/s/.*/\x1b[31m&\x1b[0m/' -e '/available/s/.*/\x1b[32m&\x1b[0m/'

Amazing work mate! I managed to squeeze this in today and it's working wonderfully except for one point: "ENABLE_VNC_AUDIO" needs to be set to false, it doesn't work if it's set to true.

I'll see if I can test it later today or tomorrow on intel.

Freddy-0 commented 6 days ago

Amazing that this works. Are you able to test this with one change: try removing the GPU you are not directly connected to. I will be having a look on how we can integrate this functionality in the project / docs on the weekend and maybe get a test server set up myself.

Freddy-0 commented 6 days ago

Also I have a script that sets the default sound source upon container startup. Is yours also switching away from the last selected source or is the startup source the right one?

Trozmagon commented 6 days ago

I haven't had a chance to look in to it yet but thought I would update you that I've noticed pulse is absolutely slamming my syslog, although audio is still working with the errors:

image

I'll update again when I've had time to look.

Freddy-0 commented 6 days ago

I have also installed this, but I thought it might not be needed. Maybe it helps though. If you want, give it a try

Driver: GitHub - thesofproject/sof-bin: Firmware and topology binaries

wget https://github.com/thesofproject/sof-bin/releases/download/v2023.12.1/sof-bin-2023.12.1.tar.gz
tar zxf sof-bin-2023.09.tar.gz
cd sof-bin-2023.09
sudo ./install.sh
Trozmagon commented 5 days ago

Amazing that this works. Are you able to test this with one change: try removing the GPU you are not directly connected to. I will be having a look on how we can integrate this functionality in the project

I've just tested on my primary GPU (Intel UHD 750) which is primarily reserved for for my KVM in case Unraid crashes while I'm travelling and it's working great as well.

I have also installed this, but I thought it might not be needed. Maybe it helps though. If you want, give it a try

Driver: GitHub - thesofproject/sof-bin: Firmware and topology binaries

wget https://github.com/thesofproject/sof-bin/releases/download/v2023.12.1/sof-bin-2023.12.1.tar.gz
tar zxf sof-bin-2023.09.tar.gz
cd sof-bin-2023.09
sudo ./install.sh

I've attempted to install this but with the latest version: v2024.03 and after running the install script nothing happens, no confirmation that it was installed or error that it didn't so I'm not quite sure what's happened with it yet.

Also I have a script that sets the default sound source upon container startup. Is yours also switching away from the last selected source or is the startup source the right one?

As far as I can tell there is only a single sound source on container start up so there shouldn't be any switching going on: image

I'm still testing here and there when I can, but I've attached Unraid syslog from container start to running, the no such file or directory errors I posted yesterday I suspect were happening when I rebooted Unraid, I will test this again later today to confirm and report back :

syslog.log

Freddy-0 commented 5 days ago

Nice, if I see and understand correctly there are no more errors in the logs after a reboot. Does this setup have more than 1 GPU? Is IOMMU enabled? Is the GPU used by any other Docker?

For me all of the above are true and the Docker is running on the secondary GPU.

The main Server is running 2 GPU's, IOMMU enabled and vfio pcie acs override applied to some extend.

I am currently fiddling around with a temporary test server with 1 GPU, but I am having some problems with getting video out at all.

Trozmagon commented 5 days ago

Nice, if I see and understand correctly there are no more errors in the logs after a reboot. Does this setup have more than 1 GPU? Is IOMMU enabled? Is the GPU used by any other Docker?

For me all of the above are true and the Docker is running on the secondary GPU.

The main Server is running 2 GPU's, IOMMU enabled and vfio pcie acs override applied to some extend.

I am currently fiddling around with a temporary test server with 1 GPU, but I am having some problems with getting video out at all.

Nah the errors are still there but I suspect they happen during the unraid boot process (I haven't tested yet to confirm this theory, it's just that the times in the syslog were about the time I had to reboot yesterday).