Skip to content

Work with MPEG 2 TS Multicasts

George Stoyanov edited this page Sep 16, 2019 · 2 revisions

Work with MPEG-2 TS Multicasts

Joining Multicast Groups with SMCROUTE

IGMP (Internet Group Management Protocol)

IGMP is a common practice to prevent the flooding of switch's ports with multicast traffic. In this case, in order to receive the multicast traffic, you need to join the multicast group. You can do that using smcroute. You can install it by executing:

sudo apt install smcroute

And this is the command to join the multicast:

sudo smcroutectl join <IFNAME> <MULTICAST-GROUP>

where:
<IFNAME> is the interface name which can receive the multicast traffic.
<MULTICAST-GROUP> is the multicast address without the port.

For example, the following command will join 224.0.0.0 multicast on eno1 interface:

sudo smcroutectl join eno1 224.0.0.0

You can check the joined multicast groups executing:

sudo smcroutectl show groups
GROUP (S,G)                        INBOUND
(*, 224.0.0.0)                     eno1

You can also leave the joined groups by:

sudo smcroutectl leave <IFNAME> <MULTICAST-GROUP>

SSM (Source Specific Multicast)

SSM is another common practice to limit the flooding of the switch's ports. In this case, you need to define the IP address of the multicast source in order to receive the multicast traffic. You can do this as well with smcroute by placing the source IP in front of the <MULTICAST-GROUP>:

sudo smcroutectl join <IFNAME> <SOURCE-IP> <MULTICAST-GROUP>

The leave command is exactly the same as above but in this case, you also need to define the <SOURCE-IP>:

sudo smcroutectl leave <IFNAME> <SOURCE-IP> <MULTICAST-GROUP>

Afterward, you can confirm that you have left this group by executing:

sudo smcroutectl show groups

Multicast Traffic Forwarding

You can use smcroute for forwarding the multicast traffic from one interface to another. This is really easy and similar to the join/add commands but in this case, you need to use:

sudo smcroutectl add <INPUT-IFNAME> <SOURCE-IP> <MULTICAST-GROUP> <OUTPUT-IFNAME-1> <OUTPUT-IFNAME-2> ...

where:
<INPUT-IFNAME> is the network interface receiving the multicast traffic.
<SOURCE-IP> is an optional argument in case you have SSM traffic.
<MULTICAST-GROUP> is the multicast group you want to join.
<OUTPUT-IFNAME-1> is the output network interface on which the input multicast traffic will be forwarded.
<OUTPUT-IFNAME-2> is also an optional argument and should be used only if you want to forward the multicast group to more than one interface.

You can learn more about the usage of smcroute at the official Github page or you can also execute smcroute help.

Checking for Multicast Traffic

You can check for existing multicast traffic on a particular network interface using the tcpdump command.

sudo tcpdump -nn -v -q -i <IFNAME> -c 1000 multicast and udp and greater 1344 | sort | uniq | grep '>'

where:
-nn option is telling tcpdump not to resolve port numbers.
-v - forces the output to be more verbose.
-c 1000 tells tcpdump to capture only 1000 packets.
-i <IFNAME> defines which network interface to be used. This has to be the network interface receiving the multicast traffic.
udp - forces tcpdump to analyze only UDP traffic.
multicast - additionally says to filter only for multicast traffic.
greater 1344 is filtering the results additionally by packet length and only capturing packets with a length greater than 1344 bytes.
| sort is sorting the output.
| uniq is showing only the unique entries.
| grep '>' is suppressing the tcpdump output and showing only the entries having the > sign.

In the above example, we are setting the packet length to be greater than 1344 because this filter by default is filtering by total UDP packet size and not by the UDP payload size. By default, UDP doesn't have a length field, but its header size is always 8, and you can usually assume that the IPv4 header size will always be 20 (IPv4 options are very rare, although they do get used in IGMP). So the total UDP packet length is:

IP.TotalLength = IP.Header[20] + UDP.Header[8] + UDP.Payload[1316] = 1344

More information can be found at this link

For example:

sudo tcpdump -c 1000 -q -nn -v -i eno1 udp and multicast and greater 1346 | sort | uniq | grep '>'
tcpdump: listening on eno1, link-type EN10MB (Ethernet), capture size 262144 bytes
1000 packets captured
1089 packets received by filter
0 packets dropped by kernel
    10.0.0.1.4000 > 224.0.0.1.1234: UDP, length 1316
    10.0.0.2.4000 > 224.0.0.2.1234: UDP, length 1316
    10.0.0.3.4000 > 224.0.0.3.1234: UDP, length 1316

The above command is showing me that there are three multicasts present on my eno1 network interface: 224.0.0.1:1234, 224.0.0.2:1234, 224.0.0.3:1234 and the source IP addresses sending those multicasts in the network are: 10.0.0.1, 10.0.0.2, 10.0.0.3 all using source port 4000.

If you want to suppress the tcpdump statistics output, you can redirect the STDERR to /dev/null and this will leave only information about the present multicasts:

sudo tcpdump -c 1000 -q -nn -v -i eno1 udp and multicast and greater 1346 2>/dev/null | sort | uniq | grep '>'
    10.0.0.1.4000 > 224.0.0.1.1234: UDP, length 1316
    10.0.0.2.4000 > 224.0.0.2.1234: UDP, length 1316
    10.0.0.3.4000 > 224.0.0.3.1234: UDP, length 1316

MPEG-2 TS Multicasts Check

FFPROBE MPEG-2 TS Stream Check

You can use check the live MPEG-2 TS stream using ffprobe, which is part of ffmpeg

ffprobe udp://<MULTICAST-IP>:<PORT> 2>&1 | egrep -e "Program" -e "Stream" -e "service_name" -e "service_provider"

where:
<MULTICAST-IP> is the multicast IP address.
<PORT> is the multicast port.
2>&1 - redirects the STDERR to the STDOUT.
| egrep -e "Program" -e "Stream" -e "service_name" -e "service_provider" - prints only the lines containing Program, Stream, service_name and service_provider to the STDOUT.

TSDuck TS Analysis

You can also use tsduck to analyze the stream but first, you need to install it either by installing the provided binaries or compile it from source. After that you can try to execute the following command:

timeout -s SIGINT 30 tsp -I ip <MULTICAST-IP>:<PORT> -P analyze -O drop

where:
timeout 30 - waits for 30 seconds.
-s SIGINT - sends SIGINT signal at the end of the 30 seconds, which is replicating a pressing of CTRL-C by the user.
tsp is the TSProcessor, one of the main programs contained in the tsduck package.
-I ip - sets the input to IP.
<MULTICAST-IP>:<PORT> is the multicast IP address and port.
-P analyze is setting the used TSProcessor plugin to analyze.
-O drop is telling to the TSProcessor to drop the output and not save or forward it.

The above command will analyze the provided multicast address for 30 seconds and will output information about all services and PIDs in the stream. It will also show you if there are any errors in the stream. If you want to save this information in a file you can just add redirection of the output of the command to a specified file.

timeout -s SIGINT 30 tsp -I ip <MULTICAST-IP>:<PORT> -P analyze -O drop > analysis.txt

This will analyze the multicast stream for 30 seconds and record the output to analysis.txt file in the same directory.

You can also use tsp to display the errors in the stream:

timeout -s SIGINT 30 tsp -I ip <MULTICAST-IP>:<PORT> -P analyze --error-analysis -O drop

As you can see TSDuck is a very powerful tool and I strongly recommend you to check its documentation to get to know its full capabilities.

MPEG-2 TS Recording

You can use different programs to record the MPEG-2 TS streams like: ffmpeg, tsudpreceive, part of the OpenCaster software, tsp, part of TSDuck, socat and multicat.

TSDuck TS Recording

An example using tsp program to make a recording of the MPEG-2 TS:

timeout -s SIGINT 30 tsp -ron --buffer-size-mb 50 -I ip <MULTICAST-IP>:<PORT> -O file recording.ts

where:
-ron forces the recording to be realtime.
-buffer-size-mb sets the buffer to 50Mb.
-O file sets the output to a file and saves the stream in this file (recording.ts).

FFMPEG TS Recording

An example of the ffmpeg recording:

ffmpeg -hide_banner -re -i "udp://<MULTICAST-IP>:<PORT>?overrun_nonfatal=1&fifo_size=50000000" \
-map 0 -ignore_unknown -c copy -t 30 -f mpegts ffmpeg.ts

where:
-hide_banner hides the initial banner which contains information about the ffmpeg's version and its configuration.
-re forces tsp to work real-time.
-i udp://<MULTICAST-IP>:<PORT> - defines the input for ffmpeg.
overrun_nonfatal=1 - tells ffmpeg to recover if it accidentally crashes due to some problem in the input stream.
fifo_size=50000000 defines the FIFO size to 50Mb, by default it is 5Mb.
-map 0 - (optional) use this argument only if you have more than one video and audio streams. It tells ffmpeg to grab all streams present in the input. It is very important to use this option in case you want to record an MPTS (multiple programs transport stream). By default ffmpeg is grabbing the first Video and audio stream. and forwards them to the output.
-ignore_unknown forces ffmpeg to ignore the unknown descriptors and to just copy them to the output.
-c copy - tells ffmpeg to copy everything from the input to the output.
-t 30 - sets the recording duration to 30 seconds.
-f mpegts - forces the output format to be MPEG-2 TS.

The above command will save the input UDP multicast stream to the recording.ts file. Please note that ffmpeg by default is erasing all the null stuffing in the stream and it is also adding service name and service providers in the metadata of the stream so perhaps this is not the best utility to save the stream.

TSUDPRECEIVE TS Recording

Another option is to use tsudpreceive which is part of the OpenCaster software:

timeout 30 tsudpreceive <MULTICAST-IP> <PORT> > recording.ts

Here we use the Linux tool timeout to limit the duration of the recording to 30 seconds since tsudpreceive is a very basic utility and it doesn't have such an option. Please note that in the tsudpreceive syntax you need to separate the and the by space and not by double points.

SOCAT TS Recording

Another option is to use the socat Linux tool:

socat -u UDP4-RECV:<PORT>,ip-add-membership=<MULTICAST-IP>:<IFNAME> CREATE:recording.ts

Here you need to define also the name of the interface in order to make the recording.

Multicat TS Recording

Multicat is another interesting tool, developed by Videolan. You can use it to make a recording on the live TS:

multicat -u -U @<MULTICAST-IP>:<PORT> -d 810000000 recording.ts    

where:
-d 810000000 is defining the duration of the recording to 30 seconds. Multicat by default is accepting the duration in 27MHz units, so 27E+6 * 30 = 81E+7.

References:

  1. TSDuck Official Webpage
  2. TSDuck Github Page
  3. TSDuck Manual
  4. OpenCaster Official Webpage
  5. OpenCaster Manual
  6. SMCRoute Official Webpage
  7. SMCRoute Github Page
  8. Socat Official Webpage
  9. Multicat Project's Official Webpage
  10. TCPDump Official Webpage