8

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.

  • This could help: swview.org/node/213 He is temporarily changing ~/.asoundrc. Maybe you can avoid this somehow. – rudimeier Nov 13 '16 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 '16 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 '16 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 '16 at 22:50
2

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
  • Now I feel stupid. Thanks. ^^ Eventually I'll learn to read the documentation first. – Nobody Nov 25 '16 at 9:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.