Я решил эту проблему следующим образом:
Сначала загрузите модуль snd-aloop
:
sudo modprobe snd-aloop
Это создаст новое устройство под названием Loopback
:
± % cat /proc/asound/cards !10017
0 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0xc1814000 irq 60
1 [HDMI ]: HDA-Intel - HDA Intel HDMI
HDA Intel HDMI at 0xc1810000 irq 61
2 [Loopback ]: Loopback - Loopback
Loopback 1
Из информации, показанной выше, мы должны создать два hw
устройства:
hw: 0,0
(PCH - мой основной звук карта). hw: 2,1
(виртуальное устройство Loopback
). Обычно hw
устройства имеют вид: hw: X, Y
. Для наших целей кажется, что Y
для основной карты всегда 0
, тогда как для Loopback
мы имеем Y
равняется 1
.
Теперь, чтобы все это работало, нам нужен ~ /.asoundrc
со следующим:
pcm.!default {
type asym
playback.pcm "LoopAndReal"
#capture.pcm "looprec"
capture.pcm "hw:X1,Y1"
}
pcm.looprec {
type hw
card "Loopback"
device 1
subdevice 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:X1,Y1"
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
}
}
Измените hw: X1, Y1
значениями для вашей основной карты (в моем случае hw: 0,0
).
Вы можете проверить, что эта конфигурация работает, проиграв что-нибудь на своем компьютере. Если вы это слышите, значит, ничего страшного. Теперь давайте воспроизведем что-нибудь на компьютере и запишем это с этого виртуального устройства с помощью ffmpeg
:
ffmpeg -f alsa -i hw:X2,Y2 -c:a libmp3lame -b:a 256k -vn capture.mp3
Где hw: X2, Y2
нужно заменить на Loopback
устройство, в данном случае
hw: 2,1
.
Я полагаю, что использование arecord
тоже должно работать.
В bash
вы можете запустить:
cmd1 | cmd2 | (trap '' INT; cmd3)
А Control -C убьет только cmd1
и cmd2
, но не cmd3
.
Пример:
$ while sleep.1; do echo -n 1; done | (trap '' INT; tr 1 2)
^C222222222
$ while sleep.1; do echo -n 1; done | tr 1 2
^C
При этом используется тот факт, что расположение сигнала «игнорировать» наследуется подпроцессами --, trap '' INT
также повлияет на команду tr
. Но, конечно, некоторые команды устанавливают свои собственные обработчики SIGINT
, которые нарушают это предположение.
К сожалению, это не работает в ksh93
из-за глупой ошибки. Обходной путь может быть:
ksh93$ while sleep.1; do echo -n 1; done | sh -c 'trap "" INT; exec tr 1 2'
^C222222222ksh93$
Протестировано с помощью приведенной ниже команды, все работает нормально
tail -f /var/log/kern.log & read -t 10 ;kill $!
Приведенная выше команда будет работать только 10 секунд, а затем будет завершена.