Record a program's output with PulseAudio
Solution 1:
Try something like this:
In a terminal enter
pacmd
(this is the CLI of the PulseAudio-Server) then use
list-sink-inputs
(where you get the indices of the running inputs) Now find the index of your input. Now referred to as $INDEX
the scriptable part is:
pactl load-module module-null-sink sink_name=steam
pactl move-sink-input $INDEX steam
parec -d steam.monitor | oggenc -b 192 -o steam.ogg --raw -
Explanations:
- The first command will add a null-sink as you already knew.
- The second command moves the sink-input from your standard-audio-sink to steam
- The third command records the monitor of the device steam (-d) and puts the output (raw-wave-stream) into oggenc, which encodes this wave-stream to an oga-file. (for mp3 use lame)
Solution 2:
Improving Waschtl answer of this thread so you can BOTH LISTEN AND RECORD the app sound:
First, we look for our default output and put its sink name in $DEFAULT_OUTPUT
:
$ pacmd list-sinks | grep -A1 "* index"
* index: 1
name: <alsa_output.pci-0000_00_1b.0.analog-stereo>
$ DEFAULT_OUTPUT=$(pacmd list-sinks | grep -A1 "* index" | grep -oP "<\K[^ >]+")
$ echo $DEFAULT_OUTPUT
alsa_output.pci-0000_00_1b.0.analog-stereo
Then, we create a combined sink that has only one slave: $DEFAULT_OUTPUT. The sound generated by the app (source) will be forwarded to the slave sink (ie. real output), and we'll also record it. It is different than a null sink where the source sound is not forwarded.
$ pactl load-module module-combine-sink \
sink_name=record-n-play slaves=$DEFAULT_OUTPUT \
sink_properties=device.description="Record-and-Play"
sink_properties
is optional and may bug if you use spaces in the description name.
Then, we could use pactl move-sink-input ...
command of Waschtl answer (with record-n-play instead of steam) but GUI pavucontrol
is more simple (and great for checking/troubleshooting):
$ sudo apt-get install pavucontrol
$ pavucontrol &
Then, we play some sound in the app we want to record. In pavucontrol
Playback tab, we select in the app dropdown list: "Record-and-Play".
Finally, we're good to record and listen at the same time! (lame mp3 example, run in foreground)
$ parec --format=s16le -d record-n-play.monitor | \
lame -r --quiet -q 3 --lowpass 17 --abr 192 - "temp.mp3"
Or we can record in background and stop at any time:
$ parec --format=s16le -d record-n-play.monitor | \
lame -r --quiet -q 3 --lowpass 17 --abr 192 - "temp.mp3" \
> /dev/null &1>/dev/null
$ killall -q parec lame
NB:
- To unmess everything or retry the procedure: Delete or reset the sinks by using this answer.
pulseaudio -k
works great to reset everything to session's defaults. - If we change the default output in the System Sound Settings, the custom app Playback setting will be overwritten and we will have to go back in pavucontrol to set it back to the combined interface.
- To be able to listen to the sound from several "real" interfaces (eg headphones, HDMI output, etc...), we should include all "real" outputs that we may use to listen, as record-n-play slink slaves, like:
pactl load-module module-combine-sink sink_name=record-n-play slaves=real-output-1,real-output-2
.
EDIT: Beware, since Ubuntu 18 (maybe 17 too), the combined sink tends to become the default system output device, instead of the real output device. So when you change the volume using the sound icon in the system tray it impacts your record sound. Workaround: After creating the combined sink, open pavucontrol
in Output tab. Select "View: Virtual Output Devices" and reset the sound volume of the combined sink to 100%. Then select "View: Hardware Output Devices" and press the green icon "Define as alternative" on the real output device.
Solution 3:
@Waschtl's answer is fantastic. @ixtmixilix asked about restoring regular audio after the recording is finished. Here's the easiest way I know of:
Install and run the pavucontrol
GUI. You should see your audio-outputting application and it's volume meter under the Playback tab in there. There will be a button next to it showing that it's playing on Null Output. Click on that and change it to your ordinary audio output, Built-in Audio Analog Stereo in my case.
Here's a screenshot of what you're looking for:
You can also use this approach to set up your recording in the future, after you've run the load-module
command in @Waschtl's answer to create the sink.