How can I use PulseAudio virtual audio streams to play music over Skype?

After many hours of tinkering I finally achieved it!

I created two Null Outputs and created two loopbacks for the first and one loopback for the second.

pactl load-module module-null-sink sink_name=Virtual1
pactl load-module module-null-sink sink_name=Virtual2
pactl load-module module-loopback sink=Virtual1
pactl load-module module-loopback sink=Virtual1
pactl load-module module-loopback sink=Virtual2

Next I opened PulseAudio Volume Control (pavucontrol)

These are my settings. I typed them in the order they appear. Numbers go from up to down.

  • Recording tab:

    • Applications:
      • All applications should input from your headset/microphone.
      • Except the application(s) you want to send the audio to should be set to one of the following. If you ONLY want to send the audio: Monitor of Null Output 1. It will be the first "Null Output" in the list. If you want to send both the audio and your voice: Monitor of Null Output 2. It will be the second "Null Output" in the list.
    • Virtual Streams:
      • Loopback to Null Output (1): Your headset/microphone
      • Loopback to your headset/microphone: Null Output 1. It will be the first "Null Output" in the list.
      • Loopback to Null Output: Null Output 1. It will be the first "Null Output" in the list.
  • Playback tab:

    • Applications:
      • All applications should output to your headset/speaker.
      • Except the application(s) you want to record/send through Skype/stream should be set to Null Output 1. It will be the first "Null Output" in the list.
    • Virtual streams:
      • Loopback of your headset: Null Output 2. It will be the second "Null Output" in the list.
      • Loopback of Monitor of Null Output (1): Your headset.
      • Loopback of Monitor of Null Output (2): Null Output 2. It will be the second "Null Output" in the list.

just to not get confused with the "null Output", just specify the names like this:

pactl load-module module-null-sink sink_name=Virtual1 sink_properties=device.description="NAME HERE (mic+music)"
pactl load-module module-null-sink sink_name=Virtual2 sink_properties=device.description="NAME HERE (only music)"
pactl load-module module-loopback sink=Virtual1
pactl load-module module-loopback sink=Virtual1
pactl load-module module-loopback sink=Virtual2

It is possible to go even further than the improvement proposed by @MikWind, and configure the sources of the loopback devices at creation time.

I finally got a bash script to setup everything that is constant :

#!/bin/bash

MICROPHONE="alsa_input.pci-0000_00_1b.0.analog-stereo"
SPEAKERS="alsa_output.pci-0000_00_1b.0.analog-stereo"

# Create the null sinks
# virtual1 gets your audio source (mplayer ...) only
# virtual2 gets virtual1 + micro
pactl load-module module-null-sink sink_name=virtual1 sink_properties=device.description="virtual1"
pactl load-module module-null-sink sink_name=virtual2 sink_properties=device.description="virtual2"

# Now create the loopback devices, all arguments are optional and can be configured with pavucontrol
pactl load-module module-loopback source=virtual1.monitor sink=$SPEAKERS
pactl load-module module-loopback source=virtual1.monitor sink=virtual2
pactl load-module module-loopback source=$MICROPHONE sink=virtual2

Having myself struggled several hours before understanding enough to make it work, I compiled my research result (script, documentation links, explanations) in a git repo.

I'm not sure if it is clear enough to be useful to anyone else than me, but I wish I found this kind of documentation when I did my own research, so I'd recommend anyone trying to do the same kind of stuff to have a look.