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:
- Get the default sink and save what it was. How? Probably grepping through
pacmd list-sinks
- Set default sink to the snd-aloop sink with
pacmd set-default-sink
. - Record from that sink.
- Launch application
- 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. - Change the default back to what it was with
pacmd set-default-sink
. - 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
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)