Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Streaming audio output from Linux (Pulseaudio) to Windows
# Windows (receiver) side:
.\ffplay.exe -nodisp -ac 2 -acodec pcm_u8 -ar 48000 -analyzeduration 0 -probesize 32 -f u8 -i udp://0.0.0.0:18181?listen=1
# Linux (transmitter) side:
pactl load-module module-null-sink sink_name=remote
ffmpeg -f pulse -i "remote.monitor" -ac 2 -acodec pcm_u8 -ar 48000 -f u8 "udp://RECEIVER:18181"
pavucontrol # Change the default output to the Null sink or move single applications to this "output" device.
@PatienceAllergy
Copy link

PatienceAllergy commented Sep 6, 2019

This works brilliantly!

But I want to know why it works so I can modify it. I'm finding the ffmpeg syntax confusing. For instance:

  • You have -f u8 but the documentation seems to indicate -sample_fmt u8, yet when tried it doesn't work.
  • Why does -f u16 not work for 16 bit sound?
  • How are there 2 -f options on the same line?
  • Where did you learn about -analyzeduration 0 and -probesize 32 ? I can't find them documented.

EDIT:

I think I've answered my own questions...

-f is used twice because the first is for input, the second for output.

-analyzeduration 0 and -probesize 32 are apparently from some older version of ffmpeg's documentation.

u16 is not a valid sample format, so that will never work. However, this works:

16bit uncompressed stream

Windows (receiver) side:

.\ffplay -nodisp -ac 2 -acodec pcm_s16le -ar 48000 -analyzeduration 0 -probesize 32 -f s16le -i udp://0.0.0.0:18181?listen=1

Linux (transmitter) side:

pactl load-module module-null-sink sink_name=remote
ffmpeg -f pulse -i "remote.monitor" -ac 2 -acodec pcm_s16le -ar 48000 -f s16le "udp://<RECEIVER'S IP ADDRESS>:18181"

MP3 compressed stream, more latency (at least for me)

Windows (receiver) side:

.\ffplay -nodisp rtp://0.0.0.0:18181

Linux (transmitter) side:

pactl load-module module-null-sink sink_name=remote
ffmpeg -f pulse -i "remote.monitor" -ac 2 -acodec libmp3lame -ar 44100 -ab 128000 -f rtp rtp://<RECEIVER'S IP ADDRESS>:18181

@Myrkie
Copy link

Myrkie commented Jan 20, 2020

worked like a charm thanks
also ive met you before on pypy/VRCX what a coincidence

@Myrkie
Copy link

Myrkie commented Jan 20, 2020

Do you know if theres anyway to change the output (playback) device ffplay uses on windows side? I use voice meeter as a audio mixer to separate music from a recording I want to route ffplay to a virtual audio cable

@Fusl
Copy link
Author

Fusl commented Jan 21, 2020

@Murkur The world definitely is a small place, heh. Check out Chevolume, it should allow you to re-route ffplay through another device once it's running but I don't think there's a way to directly tell ffplay to use a different output device, at least not on Windows.

@Myrkie
Copy link

Myrkie commented Jan 21, 2020

I just ended up using a free github project called audio rerouter its no automatic solution but it works audiorouterdev

@mwroffo
Copy link

mwroffo commented Nov 5, 2020

Thanks for this helpful script! Has anybody managed to record audio from windows10 to a linux box via pulseaudio over SSH?

@anticore
Copy link

anticore commented Nov 26, 2020

@PatienceAllergy thank you for the breakdown, curiously the MP3 compressed stream has much less latency for me.

@davidystephenson
Copy link

davidystephenson commented Dec 6, 2020

What IP Address should I put for the receiver? How can I discover it?

@bombela
Copy link

bombela commented Mar 5, 2021

What IP Address should I put for the receiver? How can I discover it?

The MS Windows receiver is listening on all interfaces (I believe on ipv4 only, but I haven't looked further). On windows you can find out the IP addresses by typing ipconfig within the windows terminal.

The Linux client is the one that sends to the address of the MS Windows computer.

@theaddies
Copy link

theaddies commented Mar 8, 2021

I am trying to get this to work sending sound from a raspberry pi to Windows 10. I have it such that There was popping on the windows machine but no intelligable sound. Is there something I need to do with the sound input on the pi or output on windows 10? Below are the commands I used except that for windows I ran the program in the folder with ffplay so did not use './'

Windows (receiver) side:

.\ffplay -nodisp -ac 2 -acodec pcm_s16le -ar 48000 -analyzeduration 0 -probesize 32 -f s16le -i udp://0.0.0.0:18181?listen=1

Linux (transmitter) side:

pactl load-module module-null-sink sink_name=remote
ffmpeg -f pulse -i "remote.monitor" -ac 2 -acodec pcm_s16le -ar 48000 -f s16le "udp://<RECEIVER'S IP ADDRESS>:18181"

@Mistergino
Copy link

Mistergino commented Oct 28, 2021

i have a massive lag with this, and the 2 computers are connected per cable, what can i do to make it better?

@cha0s
Copy link

cha0s commented Mar 19, 2022

If you have plenty of bandwidth (in other words if you can spare 3mB/s), replacing all the u8's with u32les really improves the sound quality

There are probably more efficient ways to encode it but I'm not an expert

@vdud
Copy link

vdud commented Jun 8, 2022

This works for me perfectly on Lan, with 0 latency i believe.
I'm uploading the code here so i won't lost this code.. if this works well for anyone else, its a good news!

Linux (transmitter) side:
pactl load-module module-null-sink sink_name=remote
ffmpeg -f pulse -i "remote.monitor" -ac 2 -acodec pcm_s16le -ar 48000 -f s16le "udp://<RECEIVER'S IP ADDRESS>:18181"

Windows (receiver) side:
.\ffplay -nodisp -fflags nobuffer -flags low_delay -strict experimental -fflags discardcorrupt -ac 2 -acodec pcm_s16le -ar 48000 -analyzeduration 0 -probesize 32 -f s16le -i udp://0.0.0.0:18181?listen=1

(try running windows command later)

@gmeks
Copy link

gmeks commented Jun 22, 2022

This works for me perfectly on Lan, with 0 latency i believe. I'm uploading the code here so i won't lost this code.. if this works well for anyone else, its a good news!

Linux (transmitter) side: pactl load-module module-null-sink sink_name=remote ffmpeg -f pulse -i "remote.monitor" -ac 2 -acodec pcm_s16le -ar 48000 -f s16le "udp://<RECEIVER'S IP ADDRESS>:18181"

Windows (receiver) side: .\ffplay -nodisp -fflags nobuffer -flags low_delay -strict experimental -fflags discardcorrupt -ac 2 -acodec pcm_s16le -ar 48000 -analyzeduration 0 -probesize 32 -f s16le -i udp://0.0.0.0:18181?listen=1

(try running windows command later)

Im getting 3 second on this one. Are you using a spesial version of something? ( Im on ubuntu to windows)

@Fusl
Copy link
Author

Fusl commented Jun 22, 2022

You can try adding -flush_packets 1, -fflags discardcorrupt, -fflags nobuffer, -flags low_delay, -muxdelay 0.01 on the output section of the transmitter side, that might cut down on some latency too but I haven't tried any of the options to see if they're compatible with the stuff I posted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment