ivories.org | pulseaudio

On PulseAudio Network "streaming"

There are many ways to use PulseAudio across a network environment. I personally wanted to do two different things and after much trial and error, got both of those things working. I've documented here a relatively easy way to do so.

  • Audio from a physical source on SOURCE machine -> speakers of OUTPUT machine
  • Audio from a running application on SOURCE machine -> speakers of OUTPUT machine

  • Some preliminary notes

  • We won't use the terms SERVER and CLIENT here, as these get vague with PulseAudio. Instead, we'll refer to SOURCE (the machine playing sound from an application or a microphone), and OUTPUT (the machine connected to speakers out of which you wish to hear stuff).
  • If you don't wish to use auth-anonymous=1, then you can use auth cookies as discussed here.
  • Watch out for iptables blocking port 4713 which is used for PulseAudio tunnels.

  • Physical source on SOURCE machine -> Speakers on OUTPUT machine

  • On both SOURCE and OUTPUT machines in /etc/pulse/default.pa, add
    	load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16 auth-anonymous=1
          
    Then cycle PulseAudio on both machines:
    	pulseaudio -k
    	pulseaudio --start
          
  • Use pavucontrol on the machine PLAYING audio source (the one the mic or line-in is connected to) Check that under the heading Input Devices, the correct Port: is selected (if we want to pass through microphone, select Front Microphone from the Port: drop-down. If we want to pass through line-in, select Line-In from the Port: drop-down)
  • On the OUTPUT machine:
    	pacmd load-module module-tunnel-source server=NAME_OR_IP_OF_PLAYING_MACHINE
    	pacmd load-module module-loopback source=tunnel-source.NAME_OR_IP_OF_PLAYING_MACHINE sink=NAME_OF_LOCAL_SINK
          
  • If you don't know the names of the right source or sink, use
    	pacmd list-sources
    	pacmd list-sinks
          
  • You'll need to load the module-tunnel-source module BEFORE pacmd list-sources will show the source name you're looking for.
  • If things don't seem to be going, check volumes (in pavucontrol) on both sides (and the physical receiver volume, if you're doing something like playing a phonograph connected to line-in on the SOURCE machine.)

  • Application on SOURCE machine -> Speakers on OUTPUT machine

    1. On both SOURCE and OUTPUT machines in /etc/pulse/default.pa, add
      	  load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16 auth-anonymous=1
      	
      Then cycle PulseAudio on both machines:
      	  pulseaudio -k
      	  pulseaudio --start
      	
    2. On the SOURCE machine, run
      	  pacmd load-module module-tunnel-sink server=NAME_OR_IP_OF_SPEAKER_MACHINE
      	
    3. On the SOURCE machine, start the application that will output audio. (Make sure it's not set to go directly to alsa. This would happen if, for instance, you have a custom .mpv/config or the like for a given application.)
    4. On the SOURCE machine, use pacmd list-sink-inputs to get the "index:" number for SOURCE in step 6. This will correspond to the application running on the SOURCE machine that is outputting sound.
    5. One the SOURCE machine, use pacmd list-sinks to get the "name:" value for SINK in step 6. This will correspond to the output device on the OUTPUT machine.
    6. (If using zsh, tab-completion will work nicely for both source and sink this part.) On the SOURCE machine, run
      	  pacmd move-sink-input [SOURCE: (index number from step 4)] [SINK: (sink name from step 5)]
      	
      You can also use pavucontrol's Playback tab for this: There's a dropdown by the running application to change the sink for that application.

    One bonus note on bluetooth with PulseAudio

    This has nothing directly to do with network oriented PulseAudio, but I want this note somewhere that I will find it when I next forget how to make bluetooth behave properly with PulseAudio.

    Once you have properly paired and connected to a bluetooth headset, it will tend to be in HSP/HSF profile. If you switch this on the Configuration tab in pavucontrol to a2dp_sink, it my not report any issue, but will still sound like crap.

    Watch the log (probably syslog) output for errors when you make this switch. If you're receiving an error like

          a2dp-sink profile connect failed for [bluetooth MAC]: Protocol not available
        
    Try adding a the line
          Enable=Socket
        
    to the file /etc/pulse/audio.conf. If the file doesn't exist, create it. Then cycle PulseAudio
          pulseaudio -k
          pulseaudio --start
        
    And while watching the log tail output, change the Profile: in the Configuration tab in pavucontrol for the bluetooth headset to A2DP_sink. This should make the Protocol not available error disappear.