~ Sending audio over a network with ffmpeg
» By Joren on Tuesday 30 August 2022This post describes how to send audio over a network using the ffmpeg suite. Ffmpeg is the Swiss army knife for working with audio and video formats. It is a command line tool that supports almost all audio formats known to man and woman. ffmpeg
also supports streaming media over networks.
Here, we want to send audio recorded by a microphone, over a network to a single receiver on the other end. We are not aiming for low latency. Also the audio is going only in a single direction. This can be of interest for, for example, a networked music performance. Note that ffmpeg
needs to be installed on your system.
The receiver – Alice
For the receiver we use ffplay
, which is part of the ffmpeg
tools. The command instructs the receiver to listen to TCP
connections on a randomly chosen port 12345
. The \?listen
is important since this keeps the program waiting for new connections. For streaming media over a network the stateless UDP
protocol is often used. When UDP
packets go missing they are simply dropped. If only a few packets are dropped this does not cause much harm for the audio quality. For TCP
missing packets are resent which can cause delays and stuttering of audio. However, TCP
is much more easy to tunnel and the stuttering can be compensated with a buffer. Using TCP
it is also immediately clear if a connection can be made. With UDP
packets are happily sent straight to the void and you need to resort to wiresniffing to know whether packets actually arrive.
ffplay -nodisp -f mpegts tcp://0.0.0.0:12345\?listen
In this example we use MPEGTS over a plain TCP
socket connection. Alteratively RTMP could be used (which also works over TCP
). RTP , however is usually delivered over UDP
.
The shorthand address 0.0.0.0
is used to bind the port to all available interfaces. Make sure that you are listening to the correct interface if you change the IP address.
The sender – Björn
Björn, aka Bob, sends the audio. First we need to know from which microphone to use. To that end there is a way to list audio devices. In this example the macOS avfoundation
system is used. For other operating systems there are similar provisions.
ffmpeg -f avfoundation -list_devices true -i ""
Once the index of the device is determined the command below sends incoming audio to the receiver (which should already be listening on the other end). The audio format used here is MP3
which can be safely encapsulated into mpegts
.
Note that the IP address 192.168.x.x
needs to be changed to the address of the receiver. Now if both devices are on the same network the incoming audio from Bob should arrive at the side of Alice.
The tunnel
If sender and receiver are not on the same network it might be needed to do Network Addres Translation (NAT) and port forwarding. Alternatively an ssh tunnel can be used to forward local tcp connections to a remote location. So on the sender the following command would send the incoming audio to a local port:
ffmpeg -f avfoundation -i ":1" -acodec libmp3lame -ab 196k -f mpegts tcp://192.168.x.x:12345
The connection to the receiver can be made using a local port forwarding tunnel. With ssh the TCP traffic on port 12345 is forwarded to the remote receiver via an intermediary (remote) host using the following command:
ssh -v -L 12345:192.168.x.x:12345 user@host -N