You will first need to setup ALSA correctly by loading the snd_aloop module and using its named device in an mdev plugin. You will simultaneously output an application's audio through the loop back device and another device of your choice.
# ~/.asoundrc
pcm.!default {
type plug
slave.pcm mdev
route_policy duplicate
}
pcm.mdev {
type multi
slaves.a.pcm "hw:Loopback,0,0"
slaves.a.channels 2
slaves.b.pcm "hw:0,0"
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.loopback {
type hw
card Loopback
device 1
subdevice 0
}
pcm.mic {
type hw
card 1
device 0
}
FFMPEG can merge multiple audio streams using the amerge filter. You will provide it with the loop back source and you may provide additional inputs. This example includes a microphone. This script is setup for streaming to TwitchTV.
#!/bin/bash
FPS="30"
QUAL="faster"
GOP="60"
GOPMIN="30"
CBR="1500k"
ABR="96k"
SIZE="960x540"
OUTPUT=""rtmp://live-jfk.twitch.tv/app/${STREAM_KEY}"
function GetWindowPos() {
echo $(xwininfo | grep 'Absolute' | awk '{ORS=" "; print $4;}' | awk '{print ":0.0+"$1","$2"+draw_mouse=0";}')
}
function GetWindowSize() {
echo $(xwininfo | grep 'Width\|Height' | awk '{ORS=" "; print $2;}' | awk '{print $1"x"$2;}')
}
ffmpeg \
-f alsa -i mic \
-f alsa -i loopback \
-f x11grab -s $(GetWindowSize) -i $(GetWindowPos) \
-acodec aac -ab "$ABR" -strict -2 \
-vcodec libx264 -preset "$QUAL" \
-g "$GOP" -keyint_min "$GOPMIN" \
-b:v "$CBR" -minrate "$CBR" -maxrate "$CBR" -bufsize "$CBR" \
-filter_complex "[2:0]format=pix_fmts=yuv420p[vstream];[0:0][1:0]amerge=inputs=2[astream]" \
-flags:v +global_header -flags:a +global_header \
-r "$FPS" -s "$SIZE" \
-map "[vstream]" -map "[astream]" \
-f flv "$OUTPUT"
This would be an order of magnitude easier to use PulseAudio, but I often experience latency using the monitor sources, which is terrible for live streaming. If you are latency free on PulseAudio you could simply switch out the ALSA devices for two pulse inputs.
-f alsa -i mic \
-f alsa -i loopback \
These would change to:
-f alsa -i pulse \
-f alsa -i pulse \
Then you would set the inputs in pavucontrol.