What Is UDP Streaming

UDP (User Datagram Protocol) is a way of sending data over a network. Unlike TCP, it doesn’t set up a connection before sending. It skips the handshake and never resends lost data, so it adds little overhead and video arrives with low delay. FFmpeg sends and receives UDP directly with udp:// URLs.

The downside is that UDP can’t recover lost packets. Unlike SRT and RTMP (which runs over TCP), it doesn’t resend them, so if the network drops packets, the video breaks up.

Where UDP works well and where it doesn’t:

Well suited for Not suited for
Transport within a managed LAN Distribution across the internet
Low-loss environments such as direct switch connections Lossy paths such as wireless or mobile
Sites that require ultra-low latency (relay, monitoring) Distribution that demands loss tolerance and reliability

For the container (the format that wraps the video and audio), use MPEG-TS (MPEG Transport Stream), which is made for streaming. In FFmpeg you choose it with -f mpegts. MPEG-TS is made of fixed 188-byte packets, and a receiver can join partway through and still read it (it is self-synchronizing). That makes it a good fit for live transport.

Unicast Send and Receive

Unicast sends from one sender to one receiver. You give the receiver’s IP address and port.

Sending (No Re-Encoding)

If the input already uses codecs suited to streaming (H.264 + AAC), sending it as is, without re-encoding, is the lightest option.

ffmpeg -re -i input.mp4 -c copy -f mpegts "udp://192.168.1.50:1234"
  • -re: reads the file at its normal playback speed (its frame rate). Without it, FFmpeg sends the file as fast as it can, which doesn’t work as a live stream. You need it for real-time streaming.
  • -c copy: copies the streams without re-encoding. It uses little CPU and doesn’t lower the quality.
  • -f mpegts: uses MPEG-TS as the container.
  • udp://192.168.1.50:1234: the receiver’s IP address and port.

Receiving and Saving

On the receiving side, listen on 0.0.0.0 and save what arrives to a file.

ffmpeg -i "udp://0.0.0.0:1234" -c copy received.mp4

0.0.0.0 means: receive on this port on every network interface of this machine. With -c copy, the stream is written to received.mp4 without re-encoding.

Receiving and Playing (ffplay)

To watch the stream instead of saving it, play it with ffplay.

ffplay "udp://0.0.0.0:1234"

Start the sender and the receiver on separate machines (or in separate terminals on one machine) to try low-latency streaming over your LAN.

Multicast Distribution

With multicast, one send reaches many receivers at the same time. The sender puts one stream on the network, and switches and routers that support multicast copy it only to the receivers that want it. Adding receivers doesn’t increase the sender’s bandwidth.

Multicast uses its own range of IP addresses. The usual choice is 239.0.0.0/8, the administratively scoped range reserved for use inside an organization. It doesn’t clash with internet addresses, so it is safe to use on a LAN.

Multicast Sending

ffmpeg -re -i input.mp4 -c copy -f mpegts "udp://239.0.0.1:1234?pkt_size=1316"

The difference from unicast is the destination, a multicast address (239.0.0.1). pkt_size=1316 sets the packet size (explained below). You can change the port number (1234) as you like.

Multicast Receiving

The receiver uses the same multicast address as the sender.

ffplay "udp://239.0.0.1:1234"

Every receiver that uses the same address gets the same stream, however many there are. This is useful when the same video has to reach many devices, such as digital signage or every screen in a classroom.

Whether multicast gets through depends on your routers and switches (IGMP support and so on). Home routers and some switches block or filter multicast. If the stream doesn’t reach the receiver, check the settings of your network equipment.

Key Parameters (pkt_size, fifo_size, overrun_nonfatal)

UDP settings go at the end of the URL, as ?key=value&.... These three help keep the stream stable.

pkt_size

pkt_size is the size in bytes of each UDP packet. MPEG-TS packets are always 188 bytes, so the usual practice is to use a whole multiple of 188.

188 bytes × 7 = 1316 bytes

pkt_size=1316 is exactly seven MPEG-TS packets. It also fits in a typical Ethernet MTU (the largest packet the network carries in one piece, 1500 bytes), so packets are not split up on the way (IP fragmentation). It is the recommended value for MPEG-TS over UDP.

ffmpeg -re -i input.mp4 -c copy -f mpegts "udp://192.168.1.50:1234?pkt_size=1316"

fifo_size and overrun_nonfatal

The receiver first stores arriving packets in an internal FIFO buffer (a ring buffer), then processes them. If data arrives fast, or the receiver falls behind for a moment, this buffer can overflow.

  • fifo_size: the size of the receive buffer. A bigger buffer absorbs short bursts of incoming data. The unit is packets, and setting it above the default makes dropouts less likely.
  • overrun_nonfatal=1: when the buffer overflows (an overrun), FFmpeg keeps receiving instead of stopping with an error. Use it when you’d rather lose some data than stop.

A receive command with both:

ffmpeg -i "udp://0.0.0.0:1234?overrun_nonfatal=1&fifo_size=1000000" -c copy received.mp4

fifo_size=1000000 gives a larger buffer, and overrun_nonfatal=1 keeps FFmpeg from stopping when it overflows. If reception stops with Circular buffer overrun, these two options keep it going.

Re-Encoding While Sending

If the input’s bitrate is too high or its codec isn’t supported, re-encode while sending. These settings keep the delay low and aim for a video bitrate of about 2 Mbps:

ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2000k -maxrate 2000k -bufsize 4000k -pix_fmt yuv420p -g 60 -c:a aac -b:a 128k -f mpegts "udp://192.168.1.50:1234?pkt_size=1316"

What each option does:

Option Meaning
-c:v libx264 Encode the video to H.264
-preset veryfast Prioritize encoding speed (keeps live latency low)
-b:v 2000k Target video bitrate of 2 Mbps
-maxrate 2000k / -bufsize 4000k Keeps the rate from staying above 2 Mbps for long. It can go above for a moment (at a keyframe, for example), and simple scenes use less
-pix_fmt yuv420p A highly compatible pixel format
-g 60 Keyframes at most 60 frames apart (increase receive entry points)
-c:a aac -b:a 128k Encode the audio to AAC at 128 kbps
-f mpegts Send in an MPEG-TS container

-maxrate and -bufsize keep the video from staying above 2 Mbps for long, but they do not smooth out the packets: FFmpeg sends each frame as soon as it is encoded, so a keyframe goes out as a burst far above 2 Mbps. The audio and the MPEG-TS overhead also come on top. Leave spare bandwidth on the network. Regular keyframes from -g 60 let a receiver that joins partway through show video quickly.

Choosing Between UDP, RTMP, and SRT

Pick the protocol by what you need:

Protocol Transport Loss Recovery Main Use
UDP UDP None Ultra-low-latency transport and monitoring within a LAN
SRT UDP + retransmission Yes (ARQ) Low-latency distribution over unstable links or the internet
RTMP TCP Yes (TCP) Ingest to distribution platforms (YouTube/Twitch, etc.)

How to choose:

  • UDP: on a closed LAN you manage, when the lowest latency matters most. It needs a network that rarely drops packets, such as machines on the same switch. It is not suited to the internet or to lossy links.
  • SRT: when you want low latency across the internet. It runs over UDP but resends lost packets itself (ARQ).
  • RTMP: when you send video to a streaming service. Many services accept it, and because it runs over TCP, the data arrives reliably.

Common Errors and Fixes

Cannot Receive

Check these in order:

  • Port number: do the sender and receiver use the same port (for example 1234)?
  • Firewall: is the receiver’s firewall blocking that UDP port? Open the port in the Windows firewall or on Linux (ufw/firewalld).
  • Multicast: if a router or switch is set not to forward multicast (IGMP), the stream won’t arrive. To narrow it down, test with both machines on the same switch and check the multicast settings of your network equipment.

Video Is Garbled

Blocky video or audio dropouts usually mean packets are being lost. UDP can’t recover lost packets, so the fix is on the network side.

  • Leave spare bandwidth: lower -maxrate to reduce the bitrate, or use a wired connection.
  • Clear up congestion along the path.
  • If the path keeps losing packets, switch to SRT, which recovers lost packets.

Circular buffer overrun

This error means the receiver’s buffer overflowed. It appears when the receiver can’t keep up with the incoming data. Without overrun_nonfatal=1, reception stops at that point.

ffmpeg -i "udp://0.0.0.0:1234?overrun_nonfatal=1&fifo_size=1000000" -c copy received.mp4

A larger fifo_size gives the buffer more room, and overrun_nonfatal=1 keeps reception going when it overflows.

Latency Is High

fifo_size is only the most the buffer can hold, so raising it doesn’t add latency by itself. Latency grows when the receiver falls behind and data piles up in the buffer. If low latency matters most, use a faster -preset when re-encoding and make sure the receiver doesn’t fall behind.

FAQ

Should I use UDP or SRT?

On a managed LAN that rarely loses packets, use UDP: it is light and its latency is very low. Where packets will be lost, such as over the internet or wireless, SRT is the better choice because it recovers lost packets (ARQ). UDP can’t recover dropped packets, so it is a poor fit where reliability matters.

Why is pkt_size 1316?

MPEG-TS packets are always 188 bytes, and seven of them (188×7=1316) is the most that fits in an Ethernet MTU (1500 bytes). FFmpeg’s default of 1472 bytes also fits the MTU, but it isn’t a multiple of 188, so some TS packets get split across two UDP packets. 1316 is the standard value for MPEG-TS over UDP.

Which multicast address range should I use?

On a LAN, 239.0.0.0/8 (the administratively scoped range) is safe. It is reserved for use inside an organization and doesn’t clash with internet addresses. When the receivers use the same address and port as the sender, several devices can receive the same stream at once.

What happens if I forget to add -re?

FFmpeg sends the file as fast as it can, and the receiver can’t process it in real time, so playback breaks. When you stream a file as if it were live, always add -re so the file is read at normal speed.