Debian – Programmatically Redirect Audio Output to File

audiocommand linedebianrecording

I would like to redirect the audio output of a program to file, on the command line, like in

$ redirect-wrapper file.wav my-program

so that

  • I don't hear the output of the program, i.e. the output should only go to the file
  • I don't record anything besides the program, i.e. only this specific program is redirected to the file
  • the rest of the audio system is left completely undisturbed, no configuration options changed back and forth or something like that

Is there a way to do this? This related question does not help, I need a command line solution, no "click there, then there". This is probably also related, but also relies on the graphical application pavucontrol. I found a terminal alternative to pavucontrol, pacmd.

But this still only makes the following compromise possible:

  1. Get the default sink and save what it was. How? Probably grepping through pacmd list-sinks
  2. Set default sink to the snd-aloop sink with pacmd set-default-sink.
  3. Record from that sink.
  4. Launch application
  5. Wait until the application opened its sink input: pacmd list-sink-inputs | grep name-of-my-program if this finds something, the input is open.
  6. Change the default back to what it was with pacmd set-default-sink .
  7. Stop recording once the application closes.

But this still changes the default sink for a timespan of up to a couple of minutes (the sink input isn't usually opened until the program is actually playing sounds which doesn't need to be right after launch). I implemented this compromise; Github.

Still searching for non-compromising answers.

Best Answer

Umm so looking at the pulseaudio documentation.

man pulseaudio

We have the following environment variables

   $PULSE_SERVER: the server string specifying the server to connect to when a client asks for a sound server connection  and  doesn't  explicitly  ask  for  a  specific
   server.  The server string is a list of server addresses separated by whitespace which are tried in turn. A server address consists of an optional address type speciā€
   fier (unix:, tcp:, tcp4:, tcp6:), followed by a path or host address. A host address may include an optional port number. A server address may be prefixed by a string
   enclosed in {}. In this case the following server address is ignored unless the prefix string equals the local hostname or the machine id (/etc/machine-id).

   $PULSE_SINK: the symbolic name of the sink to connect to when a client creates a playback stream and doesn't explicitly ask for a specific sink.

This should hopefully allow you to complete replace the pulseaudio sink, and if this isn't enough run our own single use pulseaudio server.

Referring to this page (https://askubuntu.com/questions/60837/record-a-programs-output-with-pulseaudio), we find out about the parec/pacat command (they are aliases) which can record from and write to sinks and streams.

Putting this together we have the following wrapper (which I haven't actually run - though I've successful got this method to work on an ad-hoc basis)

sink_name="sink-$(date +%s)"
pacat $sink_name.monitor 
parec -d steam.monitor | oggenc -b 192 -o /tmp/steam.ogg --raw - &
pid=$!
PULSE_SINK=$sink_name "$@"
kill $pid
Related Question