There are two possibilities I know of, to play sound from a Linux environment on Android device:
- Play through native ALSA libraries
- Stream through PulseAudio
- Forward to X Server (on UNIX or TCP socket)
- Stream over IP (TCP or UDP) e.g. when using VNC
First method works natively through ALSA kernel module/drivers while second and third work through PulseAudio
libraries i.e. different modules and protocols (pulseaudio
package should be installed on Termux / Linux distro).
Mostly Android OEMs base their sound architecture on ALSA, though not necessary:
"You can use Advanced Linux Sound Architecture (ALSA), Open Sound System (OSS), or a custom driver"
In case of ALSA kernel lists devices in /dev/snd/
which can be manipulated to direct sound towards sound card. Complete tutorial can be found here. It works, but not for all sound formats. It's because ALSA drivers loaded on Android devices can't be controlled (at least I could not) through standard Linux userspace tools in straightforward manner because they aren't compatible (refer to changes/additions in Linux kernel by Google/OEMs, the closed source proprietary HALs in userspace, and differences in ALSA vs. TinyALSA). Also access to /proc/asound/
is not possible without root, see details in this answer. ALSA project is here.
Also there are more customized solutions that work with ALSA and PulseAudio both such as Music Player Daemon.
When using X Server:
XSDL Server
is the only well developed X server Android app I know of, no more developed unfortunately. It has a built-in PulseAudio server with module-cli-protocol-tcp
already loaded, listening on standard port 4712
by default. Once the X Session is started on Linux, we can direct sound from Linux PulseAudio client libraries to XDSL PulseAudio server by setting the following environment variable on Linux:
$ export PULSE_SERVER=tcp:127.0.0.1:4712
* 127.0.0.1 indicates that Linux and XDSL are running on same device
Or to set permanently, edit file:
# /etc/pulse/client.conf or ~/.config/pulse/client.conf
default-server = tcp:127.0.0.1:4712
Now any media player running in this environment that makes use of PulseAudio client libraries, will stream its audio to XDSL app. You can forward X session display and sound to X server running on a PC as well but that needs a more complicated setup.
When using VNC:
VNC protocol by default doesn't support sound. However, PulseAudio server can stream over TCP/UDP using different protocols. There are apps available for Android that can play simple protocol
(e.g. Simple Protocol Player) and real-time transport protocol
(e.g. VLC). For this we need to load the related PulseAudio module.
To setup local PulseAudio daemon, first of all comment out following lines:
# /etc/pulse/default.pa
#ifexists module-console-kit.so
#load-module module-console-kit
#.endif
Otherwise daemon will fail to start if /usr/lib/pulse*/modules/module-console-kit.so
exists but consolekit
package isn't installed (which is deprecated, replaced by systemd-login
and no more present on many Linux repos).
Ensure that autospawn
is set to yes
so that we don't need to start daemon manually and it is auto started by Desktop Environment. Not necessary if we start daemon manually.
# /etc/pulse/client.conf
# Autospawn a PulseAudio server/daemon when needed
autospawn = yes
Now start pulseaudio daemon and note the value of source, for me it's auto_null.monitor
:
$ pulseaudio --start && pactl list | grep -A2 -i RUNNING
$ DISPLAY=:0 pulseaudio --start
Load simple-protocol module:
$ DISPLAY=:0 pactl load-module module-simple-protocol-tcp rate=48000 format=s16le channels=2 source=auto_null.monitor record=true port=8000 listen=127.0.0.1
Or to set permanently, edit file:
$ echo 'load-module module-simple-protocol-tcp rate=48000 format=s16le channels=2 source=auto_null.monitor record=true port=8000 listen=127.0.0.1' >> /etc/pulse/default.pa
Following should be enabled in DE startup settings, necessary because some programs such as emixer
on Enlightenment
Desktop Environment works only if PulseAudio server in local X server is published:
$ DISPLAY=:0 start-pulseaudio-x11
Start Simple Player app and match bitrate
and port
set in above command i.e. 48000
and 8000
in my case. Don't use listen=127.0.0.1
if you want to listen on PC too.
I have tested both of PulseAudio based solutions on ArchLinuxARM
and Ubuntu
, and they work without root access. However SELinux
may restrict access to certain resources if running in non-root context. Also, in order to get network access and create sockets, you have to be member of inet (3003) group necessarily. All apps with android.permission.INTERNET granted are member of this group.