Record system audio output with ALSA
Table of Contents
This was written & tested on an Archlinux system, but I believe it applies to most Linux/ALSA systems.
ALSA loopback device ∆
We assume a single run-of-the-mill Intel sound card, mapped as card 0
. We will create a virtual loopback card 1
.
#> modprobe snd-aloop
aplay -l
The loopback device works, but we won't be able to hear anything because sound goes only there, and not to the main output anymore.
Duplicate master output to loopback device ∆
It is possible to duplicate the main output to the loopback device.
Unfortunately my nerd-fu starts to run thin here and I simply scoured the web until I found an ~/.asoundrc
that works for my setup (source):
pcm.!default {
type asym
playback.pcm "LoopAndReal"
capture.pcm "hw:0,0"
}
pcm.LoopAndReal {
type plug
slave.pcm mdev
route_policy "duplicate"
}
pcm.mdev {
type multi
slaves.a.pcm pcm.MixReale
slaves.a.channels 2
slaves.b.pcm pcm.MixLoopback
slaves.b.channels 2
bindings.0.slave a
bindings.0.channel 0
bindings.1.slave a
bindings.1.channel 1
bindings.2.slave b
bindings.2.channel 0
bindings.3.slave b
bindings.3.channel 1
}
pcm.MixReale {
type dmix
ipc_key 1024
slave {
pcm "hw:0,0"
rate 48000
#rate 44100
periods 128
period_time 0
period_size 1024 # must be power of 2
buffer_size 8192
}
}
pcm.MixLoopback {
type dmix
ipc_key 1025
slave {
pcm "hw:Loopback,0,0"
rate 48000
#rate 44100
periods 128
period_time 0
period_size 1024 # must be power of 2
buffer_size 8192
}
}
Just restart your audio playback, there's no thing like restarting ALSA. Archlinux uses dmix by default "for soundcards which do not support hardware mixing", and it continues to work as expected after these changes.
Record something ∆
The rest is easy.
ffmpeg ∆
ffmpeg -f alsa -i hw:1,1 -c:a flac output.flac
So why hw:1,1
?
snd-aloop
created a virtual sound card, which is "card 1" (after the default "card 0").- This card has two devices:
1
and0
. - We told ALSA to send the master output to card
1
, device0
. - The loopback device loops this sound back to card
1
, device1
, from where we can grab it.
Only one application can record at a time.
Make it permanent ∆
I had to create two files:
$> cat /etc/modules-load.d/alsa-aloop.conf
snd_aloop
This just loads the module.
$> cat /etc/modprobe.d/alsa.conf
options snd_hda_intel index=0
options snd-aloop index=1 enable=1
This makes sure the two "devices" stay in order: first the sound card, then the loopback.