owntone / owntone-server

Linux/FreeBSD DAAP (iTunes) and MPD audio server with support for AirPlay 1 and 2 speakers (multiroom), Apple Remote (and compatibles), Chromecast, Spotify and internet radio.
https://owntone.github.io/owntone-server
GNU General Public License v2.0
2.1k stars 237 forks source link

Help wanted: local audio from inside docker #1117

Closed jptrsn closed 4 years ago

jptrsn commented 4 years ago

I'm trying to accomplish a pretty specific thing in order to achieve a pretty obscure goal, so I figured I'd reach out here for some help.

I currently am running the linuxserver/daapd docker image, as well as a container running LedFX (ahodges9/LedFX) on a single x86_64 machine. I have managed to configure audio access to the container running LedFX properly, but I can't figure out the alsa configuration for forked-daapd.

I have the following output from running the command aplay -l on the host machine:

List of PLAYBACK Hardware Devices card 0: SB [HDA ATI SB], device 0: 92HD89E2 Analog [92HD89E2 Analog] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: SB [HDA ATI SB], device 1: 92HD89E2 Digital [92HD89E2 Digital] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 8: HDMI 2 [HDMI 2] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 9: HDMI 3 [HDMI 3] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 10: HDMI 4 [HDMI 4] Subdevices: 1/1 Subdevice #0: subdevice #0

Also, taking a look at the output from running amixer I can see that PCM is defined, and I've verified that it's the correct output.

List of PLAYBACK Hardware Devices card 0: SB [HDA ATI SB], device 0: 92HD89E2 Analog [92HD89E2 Analog] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: SB [HDA ATI SB], device 1: 92HD89E2 Digital [92HD89E2 Digital] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 8: HDMI 2 [HDMI 2] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 9: HDMI 3 [HDMI 3] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: NVidia [HDA NVidia], device 10: HDMI 4 [HDMI 4] Subdevices: 1/1 Subdevice #0: subdevice #0

speaker-test works as well.

From within the container shell, I get the same results. So far, everything is looking good, and from what I can tell, I want to use card 0, subdevice 0. That's going to be the analog output on the rear panel of the motherboard, I think, which was the device that I tested with speaker-test and confirmed as working.

My forked-daapd.conf audio section looks like this:

audio {
  nickname = "Server"
  type = "alsa"
  card = "hw:0,0"
}

However, I can see in the logs the two following lines, which indicate that it's not gonna work, and indeed, it doesn't.

[ WARN] laudio: Failed to probe ALSA card=0 - No such file or directory [ INFO] laudio: Adding ALSA device 'hw:0,0' with name 'Server'

I would expect that to be enough, but it doesn't work. I've tried different variations of card, including default hw:0 hw:1 all with the same result. The logs always show the same warning, and only the device name changes in the info log entry.

I don't know what I'm doing wrong, or what to try next.

ejurgensen commented 4 years ago

speaker-test uses default, so if that works I would suggest you also set forked-daapd's configuration to that (even if it produces the warning). Contrary to forked-daapd, speaker-test does not open a mixer, so my guess would be that it is the mixer settings that are the issue. I'm not much of an ALSA expert though, so with regard to finding the right mixer settings I can only refer you to this part of the ALSA readme.

whatdoineed2do commented 4 years ago

Look at this specific section - we added a way for the server to INFO log what mixers are avAilable for your machines visible soundcards that you can use as config values

https://github.com/ejurgensen/forked-daapd/blob/master/README_ALSA.md#automatically-determine-all-relevant-the-sound-card-information

jptrsn commented 4 years ago

I set log level to info, but I haven't seen any entries in the logs other than the two laudio messages posted in the original post. I'm running version 27.2. Here's what logs look like after a restart:

[2020-11-04 09:16:19] [ LOG] main: Forked Media Server Version 27.2 taking off [2020-11-04 09:16:19] [ LOG] main: Built with: [2020-11-04 09:16:19] [ LOG] main: - ffmpeg [2020-11-04 09:16:19] [ LOG] main: - iTunes XML [2020-11-04 09:16:19] [ LOG] main: - Spotify [2020-11-04 09:16:19] [ LOG] main: - LastFM [2020-11-04 09:16:19] [ LOG] main: - Chromecast [2020-11-04 09:16:19] [ LOG] main: - MPD [2020-11-04 09:16:19] [ LOG] main: - Device verification [2020-11-04 09:16:19] [ LOG] main: - Websockets [2020-11-04 09:16:19] [ LOG] main: - ALSA [2020-11-04 09:16:19] [ LOG] main: - Webinterface [2020-11-04 09:16:19] [ INFO] main: Initialized with ffmpeg 4.3.1 [2020-11-04 09:16:19] [ LOG] main: mDNS init [2020-11-04 09:16:19] [ LOG] mdns: Avahi state change: Client registering [2020-11-04 09:16:19] [ INFO] main: Initializing database [2020-11-04 09:16:19] [ LOG] db: Configured to use database file '/config/dbase_and_logs/songs3.db' [2020-11-04 09:16:19] [ LOG] db: Now vacuuming database, this may take some time... [2020-11-04 09:16:19] [ LOG] db: Database OK with 2785 active files and 18 active playlists [2020-11-04 09:16:19] [ INFO] cache: cache thread init [2020-11-04 09:16:19] [ INFO] spotify: Spotify session init [2020-11-04 09:16:19] [ WARN] laudio: Failed to probe ALSA card=0 - No such file or directory [2020-11-04 09:16:19] [ INFO] laudio: Adding ALSA device 'default' with name 'Server' [2020-11-04 09:16:19] [ WARN] ffmpeg: No bit rate set. Defaulting to 96000 bps. [2020-11-04 09:16:19] [ WARN] scan: Cannot open media file '/music/sentinel': Invalid data found when processing input [2020-11-04 09:16:19] [ INFO] stream: Streaming quality: 44100/16/2 @ 192kbps [2020-11-04 09:16:19] [ INFO] mpd: mpd thread init [2020-11-04 09:16:19] [ INFO] main: Registering rendezvous names [2020-11-04 09:16:19] [ INFO] mdns: Re-registering mDNS groups (services and records) [2020-11-04 09:16:19] [ INFO] mdns: Re-registering mDNS groups (services and records) [2020-11-04 09:16:19] [ INFO] mdns: Re-registering mDNS groups (services and records) [2020-11-04 09:16:19] [ INFO] mdns: Re-registering mDNS groups (services and records) [2020-11-04 09:16:19] [ INFO] mdns: Re-registering mDNS groups (services and records) [2020-11-04 09:16:19] [ INFO] mdns: Re-registering mDNS groups (services and records) [2020-11-04 09:16:19] [ INFO] mdns: Re-registering mDNS groups (services and records) [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Shed': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type AirPort Express 1 - 802.11g, address 192.168.1.108:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Shed': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type AirPort Express 1 - 802.11g, address 192.168.1.108:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'LedFX': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type Other, address 192.168.1.15:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'LedFX': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type Other, address 192.168.1.15:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Office': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 7, type AirPort Express 1 - 802.11g, address 192.168.1.100:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Office': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 7, type AirPort Express 1 - 802.11g, address 192.168.1.100:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Kitchen': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type AirPort Express 1 - 802.11g, address 192.168.1.176:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Kitchen': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type AirPort Express 1 - 802.11g, address 192.168.1.176:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Basement': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type Other, address 192.168.1.96:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Basement': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type Other, address 192.168.1.96:5000 [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Kitchen display' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Kitchen display' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Bedroom TV' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Bedroom TV' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Nexus Player' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Nexus Player' [2020-11-04 09:16:19] [ WARN] scan: Cannot open media file '/music/iT 3.tmp': Invalid data found when processing input [2020-11-04 09:16:19] [ INFO] scan: Deferred playlist /music/iTunes Library.xml [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Upstairs Hall' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Upstairs Hall' [2020-11-04 09:16:19] [ LOG] mdns: Avahi state change: Client running [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Upstairs Hall' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Nexus Player' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Bedroom TV' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Kitchen display' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Upstairs Hall' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Nexus Player' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Bedroom TV' [2020-11-04 09:16:19] [ INFO] cast: Adding Chromecast device 'Kitchen display' [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Basement': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type Other, address 192.168.1.96:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Kitchen': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type AirPort Express 1 - 802.11g, address 192.168.1.176:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Office': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 7, type AirPort Express 1 - 802.11g, address 192.168.1.100:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'LedFX': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type Other, address 192.168.1.15:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Shed': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type AirPort Express 1 - 802.11g, address 192.168.1.108:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Basement': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type Other, address 192.168.1.96:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Kitchen': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type AirPort Express 1 - 802.11g, address 192.168.1.176:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Office': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 7, type AirPort Express 1 - 802.11g, address 192.168.1.100:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'LedFX': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type Other, address 192.168.1.15:5000 [2020-11-04 09:16:19] [ INFO] raop: Adding AirPlay device 'Shed': password: 0, verification: 0, encrypt: 1, authsetup: 0, metadata: 0, type AirPort Express 1 - 802.11g, address 192.168.1.108:5000 [2020-11-04 09:16:19] [ WARN] scan: Cannot open media file '/music/iT.tmp': Invalid data found when processing input [2020-11-04 09:16:19] [ WARN] scan: Cannot open media file '/music/iT 2.tmp': Invalid data found when processing input [2020-11-04 09:16:19] [ WARN] scan: Cannot open media file '/music/iT 1.tmp': Invalid data found when processing input [2020-11-04 09:16:20] [ WARN] scan: Cannot open media file '/music/iTunes Library Genius.itdb': Invalid data found when processing input [2020-11-04 09:16:20] [ WARN] scan: Cannot open media file '/music/iTunes Library.itl': Invalid data found when processing input [2020-11-04 09:16:20] [ WARN] scan: Cannot open media file '/music/iT 5.tmp': Invalid data found when processing input [2020-11-04 09:16:20] [ WARN] scan: Cannot open media file '/music/iT 6.tmp': Invalid data found when processing input [2020-11-04 09:16:20] [ WARN] scan: Cannot open media file '/music/iTunes Library Extras.itdb': Invalid data found when processing input [2020-11-04 09:16:20] [ WARN] scan: Ignoring file: /music/itunes.db [2020-11-04 09:16:20] [ WARN] scan: Ignoring file: /music/librespot-java.metadata [2020-11-04 09:16:20] [ WARN] scan: Cannot open media file '/music/iT 4.tmp': Invalid data found when processing input [2020-11-04 09:16:20] [ WARN] scan: Ignoring file: /music/Audiobooks/Richard Feynman/Richard Feynman - The Very Best of the Feynman Lectures/Feynman Lectures.jpg [2020-11-04 09:16:20] [ WARN] scan: Ignoring file: /music/Audiobooks/Neil Gaiman/Neil Gaiman - Stardust/Neil Gaiman - Stardust.jpg [2020-11-04 09:16:20] [ LOG] scan: Scanned 200 files...

whatdoineed2do commented 4 years ago

I just remembered that the [ WARN] laudio: Failed to probe ALSA card=0 - No such file or directory is mine - this is where it tries to dump the details of the card. ie the mixer(s).

Can you change the card to be hw:0


EDIT - actually, scratch that .. the probing here is already trying to use hw:0 but for whatever reason, in the container it doesnt believe theres such a device. in the container, can you paste the output from amixer -c 0

taku0220 commented 4 years ago

I am not very good at English, so I apologize in advance. In my case, I needed to set the permission in the container shell.

chmod 666 /dev/snd/*

I'm adding a script because the permission returns when I restart.

/etc/cont-init.d/50-audio

#!/usr/bin/with-contenv bash

if [ -d /dev/snd ]; then
  chmod 0766 /dev/snd/*
fi

And add the user to the "Audio" group.

usermod -aG audio abc
whatdoineed2do commented 4 years ago

I pulled the latest daapd image and running it via podman on this fedora x64 box and its not working as described but i think this is on the container build side

podman run --rm --device /dev/snd --group-add=audio -d --name=daapd --net=host \
-e PUID=500 -e PGID=100 -e TZ=Europe/London \
-v /tmp/docker:/config -v /tmp/docker/music:/music \
daapd

and I get the same problems as reported. In my instance I'm using hw:1 explicitly to make sure no funny stuff is happen but trying to enable the device via the web interface (of the docker daapd process)

[2020-11-05 11:52:54] [  LOG]   laudio: Failed to attach mixer 'hw:1': No such file or directory
[2020-11-05 11:52:54] [  LOG]   laudio: Could not open mixer 'hw:1' ('Master')
[2020-11-05 11:52:54] [  LOG]      web: JSON api request failed with error code 500 (/api/outputs/0)

Inside the container I am not able to chown or chmod the /dev/snd devices, whcih incidentally are all owned by nobody:nobody. The user, inside the container, is abc but is only member of the user group.

So right now, I'm at a loss for why its not finding the devices

taku0220 commented 4 years ago

Hello @whatdoineed2do, I pulled the latest daapd image,me too.

I checked it with debian9.

docker run --rm --device /dev/snd --group-add=audio -d --name=daapd --net=host \
-e PUID=1000 -e PGID=1000 -e TZ=Asia/Tokyo \
-v /appdata/linuxserver-daapd:/config \
-v /Multimedia/Music:/music \
ghcr.io/linuxserver/daapd

I checked the inside of the container.

taku@debian:~$ docker exec -it daapd /bin/bash

root@debian:/# id abc
uid=1000(abc) gid=1000(users) groups=1000(users),1000(users)

root@debian:/# ls -la /dev/snd
total 0
drwxr-xr-x 2 root root     280 Nov  6 16:21 .
drwxr-xr-x 6 root root     360 Nov  6 16:21 ..
crw-rw---- 1 root   29 116,  7 Nov  6 16:21 controlC0
crw-rw---- 1 root   29 116,  2 Nov  6 16:21 controlC1
crw-rw---- 1 root   29 116, 11 Nov  6 16:21 hwC0D0
crw-rw---- 1 root   29 116,  6 Nov  6 16:21 hwC1D0
crw-rw---- 1 root   29 116,  8 Nov  6 16:21 pcmC0D3p
crw-rw---- 1 root   29 116,  9 Nov  6 16:21 pcmC0D7p
crw-rw---- 1 root   29 116, 10 Nov  6 16:21 pcmC0D8p
crw-rw---- 1 root   29 116,  4 Nov  6 16:21 pcmC1D0c
crw-rw---- 1 root   29 116,  3 Nov  6 16:21 pcmC1D0p
crw-rw---- 1 root   29 116,  5 Nov  6 16:21 pcmC1D1p
crw-rw---- 1 root   29 116,  1 Nov  6 16:21 seq
crw-rw---- 1 root   29 116, 33 Nov  6 16:21 timer

root@debian:/# cat /etc/group | grep audio
audio:x:18:

root@debian:/# ls -la /etc/alsa/conf.d
ls: cannot access '/etc/alsa/conf.d': No such file or directory

root@debian:/# ls -la /etc/asound.conf
ls: cannot access '/etc/asound.conf': No such file or directory

root@debian:/# find / -name .asoundrc
root@debian:/#                 

   From the result of checking, I tried this.

taku@debian:~$ docker exec -it daapd /bin/bash

root@debian:/# mkdir /config/custom-cont-init.d
root@debian:/# vi /config/custom-cont-init.d/50-audio
root@debian:/# vi /config/asound.conf

root@debian:/# exit
taku@debian:~$ docker stop daapd

/config/custom-cont-init.d/50-audio is:

#!/usr/bin/with-contenv bash

groupmod -g 29 audio
usermod -aG audio abc

#symlink conf to /conf
[[ ! -L /etc/asound.conf && -f /etc/asound.conf ]] && \
        rm /etc/asound.conf
[[ ! -L /etc/asound.conf && -f /config/asound.conf ]] && \
        ln -s /config/asound.conf /etc/asound.conf

/etc/asound.conf is:

pcm.!default {
        type hw
        card 1
}

ctl.!default {
        type hw
        card 1
}

retry of 'docker run' was OK.

jptrsn commented 4 years ago

Using @taku0220 suggestions, I can confirm that after entering the container shell and running these two commands, local audio output is working:

chmod 666 /dev/snd/*
whatdoineed2do commented 4 years ago

good stuff - just out curiosity, is your host a cgroup 1 or 2?

My fedora host is using cgroup2 which might have contributed to the issues I had reproducing your problem and hence the need for another solution for cgroup2 aka unified cgroup hierarchy users.

$ grep cgroup /proc/filesystems 
nodev   cgroup
nodev   cgroup2
jptrsn commented 4 years ago

Here's what I get when running that command:

$ grep cgroup /proc/filesystems
nodev   cgroup
nodev   cgroup2

I'm mostly hopeless in Linux, and entirely so in Python. I have no understanding of what a cgroup is or what it does. Is there something specific I should be reading to inform myself, or should I just get started with a google search? Are there other concepts I need to learn to be able to better troubleshoot and understand the help I'm getting? I've just been taking random swipes in the dark trying to solve this, and everyone's help here is really appreciated.

whatdoineed2do commented 4 years ago

Don't worry about cgroups too much - just to know that this is how linux provides a container namespace for your docker containers to run - and linux has original container groups and unified contrainer groups (cgroup2) with the latter solving some issues.

However, the problem that you raise isnt a forked-daapd issue - based on the need to change permissions etc it looks like a bug in the docker image build which is maintained outside of this repo.

FWIW, for me cgroup2 is enabled on the kernel command line and I just recalled this breaks docker

$ cat /proc/cmdline 
BOOT_IMAGE=(hd0,msdos1)/vmlinuz-5.5.10-100.fc30.x86_64 root=/dev/mapper/vg-root ro rd.lvm.lv=vg/root rd.lvm.lv=vg/swap resume=/dev/mapper/vg-swap plymouth.enable=0 systemd.unified_cgroup_hierarchy=1
jptrsn commented 4 years ago

Thank you everyone for helping me figure out a solution. I've submitted an issue to the docker repository, and I'll close this one, as it's clearly got to be fixed in the build process.

Thanks again!