9

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.

4
  • This could help: swview.org/node/213 He is temporarily changing ~/.asoundrc. Maybe you can avoid this somehow.
    – rudimeier
    Nov 13, 2016 at 17:19
  • @rudimeier That is globally setting the default output device. No matter whether from ~/.asoundrc or in an other way, it will always mess the rest of the audio system up.
    – Nobody
    Nov 13, 2016 at 20:47
  • No idea, but I think you're on the right track. The output of pacmd list shows what sources and sinks are attached to particular programs, so there may be a way to change them. Try asking on the pulseaudio list at lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss The maintainers/developers are there and are quite helpful.
    – Joe
    Nov 19, 2016 at 4:29
  • @Joe Reassigning sinks is possible with pacmd, yes, but because they are only allocated when audio actually starts playing (at least for some programs; Firefox), that means I would need to search for them in a tight loop and would possibly miss the first 0.5s or so of the audio. Thanks for the tip about the mailing list. :-)
    – Nobody
    Nov 19, 2016 at 22:50

1 Answer 1

3

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
3
  • Now I feel stupid. Thanks. ^^ Eventually I'll learn to read the documentation first.
    – Nobody
    Nov 25, 2016 at 9:43
  • So how do I use this script? Put it in a file (call it redirect-wrapper.sh) and run redirect-wrapper.sh file.wav my-program? @Nobody
    – 842Mono
    Feb 17, 2021 at 4:33
  • @MinaMichael You would need to understand it to use it an adapt it to your needs. For starters, line 3 needs to have $sink_name.monitor instead of steam.monitor. The output file is hardcoded to /tmp/steam.ogg in line 3.
    – Nobody
    Feb 17, 2021 at 10:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .