Examples to demonstrate how to stream videos using MPEG DASH in NeST

This directory contains the following example to understand how videos can be streamed using MPEG DASH in NeST. MpegDashApplication API is used in these examples to configure stream video between a pair of nodes.

IMPORTANT It is strongly recommended that you run these MPEG-DASH examples on systems with Ubuntu version 22.04 or above. All the examples listed below require GPAC MP4 Client to be pre-installed in your machine.

GPAC MP4 Client can be installed as follows:

$ sudo apt -yqq update
$ sudo apt install -y --no-install-recommends \
fakeroot dpkg-dev devscripts debhelper ccache \
zlib1g-dev libfreetype6-dev libjpeg62-dev \
libpng-dev libmad0-dev libfaad-dev libogg-dev \
libvorbis-dev libtheora-dev liba52-0.7.4-dev \
libavcodec-dev libavformat-dev libavutil-dev \
libswscale-dev libavdevice-dev libnghttp2-dev \
libopenjp2-7-dev libcaca-dev libxv-dev \
x11proto-video-dev libgl1-mesa-dev libglu1-mesa-dev \
x11proto-gl-dev libxvidcore-dev libssl-dev \
libjack-jackd2-dev libasound2-dev libpulse-dev \
libsdl2-dev dvb-apps mesa-utils

$ git clone https://github.com/gpac/gpac.git
$ cd gpac/
$ ./configure
$ sudo make
$ sudo make install

Ensure that the installed gpac version is 2.2 or above by typing gpac in the terminal.

In case you want to dive into the details of GPAC installation, feel free to read their documentation at https://github.com/gpac/gpac/wiki/GPAC-Build-Guide-for-Linux

The installation command for VLC Media Player is as follows:

$ sudo apt install vlc

In case you use GPAC MP4 Client for playback then NeST will generate plots of the video streaming statistics and also generate a JSON file of the same.

In case you use VLC Media Player, then while the video is playing you will have to navigate to Tools > Media Information > 'Statistics' Tab (or use keyboard shortcut CTRL+I) in order to view the video statistics.

To set the media player as GPAC MP4 Client or VLC Media Player in the MPEG-DASH examples, set the player argument of MpegDashApplication to ‘gpac’ or ‘vlc’ respectively.

In all the examples below, NeST will require a video file which will be utilised for streaming. The user is advised to perform any one of the following tasks: i. Either copy a video file in the same directory as these examples and rename it as ‘video.mp4’, or ii. Set the ‘VIDEO_PATH’ variable in the example to the path of the video file of the user’s choice.

If the path specified by ‘VIDEO_PATH’ is invalid, then the API will automatically resort to downloading a sample 15-second video from the Internet as a fallback mechanism. The sample video will be downloaded from https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4 .

The encoded chunks will be generated and dumped in a folder named mpeg-dash-encoded-chunks in the same directory as the example program.

1. mpeg-dash-point-to-point-1.py

This program emulates a point to point network between two hosts h1 and h2. Here, h2 acts as the MPEG-DASH streaming server and h1 acts as the MPEG-DASH client. The results of this MPEG-DASH video streaming experiment will be documented in the examples/mpeg-dash/mpeg-dash-point-to-point-1(date-timestamp)_dump folder. It contains a README which provides details about the sub-directories and files within this directory.

Additionally, Socket statistics (ss) will be gathered and stored in the same folder mentioned above. However, it’s important to note that these socket statistics are collected as a formality and might not offer significant or useful information.

Source code

  1# SPDX-License-Identifier: GPL-2.0-only
  2# Copyright (c) 2019-2023 NITK Surathkal
  3
  4########################
  5# SHOULD BE RUN AS ROOT
  6########################
  7import os
  8from pathlib import Path
  9import sys
 10from nest.topology import *
 11from nest.experiment import *
 12from nest.topology.network import Network
 13from nest.topology.address_helper import AddressHelper
 14from nest.mpeg_dash_encoder import MpegDashEncoder
 15from nest import config
 16
 17# IMPORTANT: It is strongly recommended that you run MPEG-DASH examples on systems
 18# with Ubuntu version `22.04 or above`.
 19
 20#################################
 21#       Network Topology        #
 22#                               #
 23#          5mbit, 5ms -->       #
 24#   h1 ------------------- h2   #
 25#       <-- 10mbit, 100ms       #
 26#                               #
 27#################################
 28
 29# In the following lines below, NeST will require a video file which will be utilised for streaming.
 30# The user is advised to perform any one of the following tasks:
 31# i. Either copy a video file in the same directory as these examples and rename it as 'video.mp4', or
 32# ii. Set the 'VIDEO_PATH' variable in the example to the path of the video file of the user's choice.
 33# If the path specified by 'VIDEO_PATH' is invalid, then the API will automatically resort to
 34# downloading a sample 15-second video from the Internet as a fallback mechanism. The sample video
 35# will be downloaded from https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4 .
 36
 37# The encoded chunks will be generated and dumped in a folder named
 38# `mpeg-dash-encoded-chunks` in the same directory as this program.
 39
 40CURRENT_DIR = Path(os.path.abspath(__file__)).parent
 41VIDEO_PATH = CURRENT_DIR / "video.mp4"
 42OUTPUT_PATH = CURRENT_DIR / "mpeg-dash-encoded-chunks"
 43
 44# Encoding the video into MPEG-DASH chunks
 45mpeg_dash_encoder = MpegDashEncoder()
 46ENCODER_RESPONSE = mpeg_dash_encoder.encode_video(
 47    VIDEO_PATH, OUTPUT_PATH, overwrite=False
 48)
 49if ENCODER_RESPONSE != 0:
 50    sys.exit(0)
 51
 52# The following line ensures that NeST does not delete encoded video chunks
 53# during the termination of this experiment.
 54config.set_value("mpeg_dash_delete_encoded_chunks_on_termination", False)
 55
 56# Create two hosts `h1` and `h2`.
 57h1 = Node("h1")
 58h2 = Node("h2")
 59
 60# Set the IPv4 address for the network, and not the interfaces.
 61# We will use the `AddressHelper` later to assign addresses to the interfaces.
 62n1 = Network("192.168.1.0/24")
 63
 64# Connect the above two hosts using a veth pair. Note that `connect` API in
 65# this program takes `network` as an additional parameter. The following line
 66# implies that `eth1` and `eth2` interfaces on `h1` and `h2`, respectively are
 67# in the same network `n1`.
 68(eth1, eth2) = connect(h1, h2, network=n1)
 69
 70# Assign IPv4 addresses to all the interfaces in the network.
 71AddressHelper.assign_addresses()
 72
 73# Set the link attributes: `h1` --> `h2` and `h2` --> `h1`
 74eth1.set_attributes("5mbit", "5ms")
 75eth2.set_attributes("10mbit", "100ms")
 76
 77# Set a packet error rate of 0.5% with 0.1% correlation rate between two packets
 78# on the links from `h1` to `h2` and `h2` to `h1`.
 79eth1.set_packet_corruption("0.5%", "0.1%")
 80eth2.set_packet_corruption("0.5%", "0.1%")
 81
 82# Set the random packet loss rate on the links from `h1` to `h2` and `h2` to `h1`.
 83eth1.set_packet_loss("0.2%")
 84eth2.set_packet_loss("0.2%")
 85
 86exp = Experiment("mpeg-dash-point-to-point-1")
 87
 88# In case you use GPAC MP4 Client for playback then NeST will
 89# generate plots of the video streaming statistics and also
 90# generate a JSON file of the same.
 91
 92# In case you use VLC Media Player, then NeST won't generate video
 93# streaming statistics. In order to view video statistics, while
 94# the video is playing you will have to navigate to `Tools >
 95# Media Information > 'Statistics' Tab` (or use keyboard shortcut
 96# `CTRL+I`).
 97
 98# To set the media player as GPAC MP4 Client or VLC Media Player in this example,
 99# set the `player` argument of `MpegDashApplication` to 'gpac' or 'vlc' respectively.
100
101# Create an MPEG-DASH application with a client node `h1` and a server node `h2`
102# using their respective network interfaces (`eth1` and `eth2`). The server is
103# listening on port 8000. The path specified by `OUTPUT_PATH` contains the encoded
104# video chunks. The experiment duration is set to 100 seconds (It is recommended
105# to set the experiment duration less or equal to the video duration).
106# The media player to be used is set to 'gpac'. The audio playback, which is disabled
107# by default, can be enabled by setting `enable_audio_playback` to `True`.
108
109app = MpegDashApplication(
110    h1,
111    h2,
112    eth1.get_address(),
113    eth2.get_address(),
114    8000,
115    OUTPUT_PATH,
116    100,
117    player="gpac",
118    enable_audio_playback=False,
119)
120
121exp.add_mpeg_dash_application(app)
122exp.run()

2. mpeg-dash-two-lans-connected-via-router.py

This program emulates two Local Area Network (LANs) connected via a router. LAN-1 consists three hosts h1 to h3 connected to switch s1, and LAN-2 consists three hosts h4 to h6 connected to switch s2. Switches s1 and s2 are connected to each other via a router r1. Here, h4 acts as the MPEG-DASH streaming server and h1 acts as the MPEG-DASH client. The results of this MPEG-DASH video streaming experiment will be documented in the examples/mpeg-dash/mpeg-dash-two-lans-connected-via-router(date-timestamp)_dump folder. It contains a README which provides details about the sub-directories and files within this directory.

Additionally, Socket statistics (ss) will be gathered and stored in the same folder mentioned above. However, it’s important to note that these socket statistics are collected as a formality and might not offer significant or useful information.

Source code

  1# SPDX-License-Identifier: GPL-2.0-only
  2# Copyright (c) 2019-2024 NITK Surathkal
  3
  4########################
  5# SHOULD BE RUN AS ROOT
  6########################
  7import os
  8from pathlib import Path
  9import sys
 10from nest.topology import *
 11from nest.experiment import *
 12from nest.topology.network import Network
 13from nest.topology.address_helper import AddressHelper
 14from nest.mpeg_dash_encoder import MpegDashEncoder
 15from nest import config
 16
 17# IMPORTANT: It is strongly recommended that you run MPEG-DASH examples on systems
 18# with Ubuntu version `22.04 or above`.
 19
 20# This program emulates two Local Area Networks (LANs) connected via a router.
 21# LAN-1 consists three hosts `h1` to `h3` connected to switch `s1`, and
 22# LAN-2 consists three hosts `h4` to `h6` connected to switch `s2`. Switches
 23# `s1` and `s2` are connected to each other via a router `r1`.
 24# An MPEG-DASH application has been configured to stream between `h1` (client)
 25# and `h4` (server).
 26
 27##################################################################
 28#                       Network Topology                         #
 29#           LAN-1                           LAN-2                #
 30#   h1 ---------------                      --------------- h4   #
 31#                     \                    /                     #
 32#   h2 --------------- s1 ----- r1 ----- s2 --------------- h5   #
 33#                     /                    \                     #
 34#   h3 ---------------                      --------------- h6   #
 35#   <- 100mbit, 1ms ->  <- 10mbit, 10ms ->  <- 100mbit, 1ms ->   #
 36#                                                                #
 37##################################################################
 38
 39# In the following lines below, NeST will require a video file which will be utilised for streaming.
 40# The user is advised to perform any one of the following tasks:
 41# i. Either copy a video file in the same directory as these examples and rename it as 'video.mp4', or
 42# ii. Set the 'VIDEO_PATH' variable in the example to the path of the video file of the user's choice.
 43# If the path specified by 'VIDEO_PATH' is invalid, then the API will automatically resort to
 44# downloading a sample 15-second video from the Internet as a fallback mechanism. The sample video
 45# will be downloaded from https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4 .
 46
 47# The encoded chunks will be generated and dumped in a folder named
 48# `mpeg-dash-encoded-chunks` in the same directory as this program.
 49
 50CURRENT_DIR = Path(os.path.abspath(__file__)).parent
 51VIDEO_PATH = CURRENT_DIR / "video.mp4"
 52OUTPUT_PATH = CURRENT_DIR / "mpeg-dash-encoded-chunks"
 53
 54# Encoding the video into MPEG-DASH chunks
 55mpeg_dash_encoder = MpegDashEncoder()
 56ENCODER_RESPONSE = mpeg_dash_encoder.encode_video(
 57    VIDEO_PATH, OUTPUT_PATH, overwrite=False
 58)
 59if ENCODER_RESPONSE != 0:
 60    sys.exit(0)
 61
 62# The following line ensures that NeST does not delete encoded video chunks
 63# during the termination of this experiment.
 64config.set_value("mpeg_dash_delete_encoded_chunks_on_termination", False)
 65
 66# Create six hosts 'h1' to 'h6'
 67h1 = Node("h1")
 68h2 = Node("h2")
 69h3 = Node("h3")
 70h4 = Node("h4")
 71h5 = Node("h5")
 72h6 = Node("h6")
 73
 74# Create two switches 's1' and 's2'
 75s1 = Switch("s1")
 76s2 = Switch("s2")
 77
 78# Create a router 'r1'
 79r1 = Router("r1")
 80
 81# Create two networks
 82n1 = Network("192.168.1.0/24")  # network on the left of `r1`
 83n2 = Network("192.168.2.0/24")  # network on the right of `r1`
 84
 85# Create LAN-1: Connect hosts `h1`, `h2` and `h3` to switch `s1`
 86(eth1, ets1a) = connect(h1, s1, network=n1)
 87(eth2, ets1b) = connect(h2, s1, network=n1)
 88(eth3, ets1c) = connect(h3, s1, network=n1)
 89
 90# Create LAN-2: Connect hosts `h4`, `h5` and `h6` to switch `s2`
 91(eth4, ets2a) = connect(h4, s2, network=n2)
 92(eth5, ets2b) = connect(h5, s2, network=n2)
 93(eth6, ets2c) = connect(h6, s2, network=n2)
 94
 95# Connect switches `s1` and `s2` to router `r1`
 96(ets1d, etr1a) = connect(s1, r1, network=n1)
 97(ets2d, etr1b) = connect(s2, r1, network=n2)
 98
 99# Assign IPv4 addresses to all the interfaces and switches in the network.
100AddressHelper.assign_addresses()
101
102# Set the attributes of the links between hosts and switches
103eth1.set_attributes("100mbit", "1ms")
104eth2.set_attributes("100mbit", "1ms")
105eth3.set_attributes("100mbit", "1ms")
106eth4.set_attributes("100mbit", "1ms")
107eth5.set_attributes("100mbit", "1ms")
108eth6.set_attributes("100mbit", "1ms")
109
110# Set the attributes of the links between `r1` and switches
111etr1a.set_attributes("10mbit", "10ms")
112etr1b.set_attributes("10mbit", "10ms")
113
114# Set the packet error rates on the links.
115etr1a.set_packet_corruption("0.5%", "0.1%")
116etr1b.set_packet_corruption("0.5%", "0.1%")
117
118# Set the random packet loss rate on the links.
119etr1a.set_packet_loss("0.2%")
120etr1b.set_packet_loss("0.2%")
121
122# Set the default routes for hosts `h1`, `h2` and `h3` via `etr1a`
123h1.add_route("DEFAULT", eth1, etr1a.address)
124h2.add_route("DEFAULT", eth2, etr1a.address)
125h3.add_route("DEFAULT", eth3, etr1a.address)
126
127# Set the default routes for hosts `h4`, `h5` and `h6` via `etr1b`
128h4.add_route("DEFAULT", eth4, etr1b.address)
129h5.add_route("DEFAULT", eth5, etr1b.address)
130h6.add_route("DEFAULT", eth6, etr1b.address)
131
132exp = Experiment("mpeg-dash-two-lans-connected-via-router")
133
134# In case you use GPAC MP4 Client for playback then NeST will
135# generate plots of the video streaming statistics and also
136# generate a JSON file of the same.
137
138# In case you use VLC Media Player, then NeST won't generate video
139# streaming statistics. In order to view video statistics, while
140# the video is playing you will have to navigate to `Tools >
141# Media Information > 'Statistics' Tab` (or use keyboard shortcut
142# `CTRL+I`).
143
144# To set the media player as GPAC MP4 Client or VLC Media Player in this example,
145# set the `player` argument of `MpegDashApplication` to 'gpac' or 'vlc' respectively.
146
147# Create an MPEG-DASH application `app` with a client node `h1` and a server node `h4`
148# using their respective network interfaces (`eth1` and `eth4`). The server is
149# listening on port 9000. The path specified by `OUTPUT_PATH` contains the encoded
150# video chunks. The experiment duration is set to 100 seconds (It is recommended
151# to set the experiment duration less or equal to the video duration).
152# The media player to be used is set to 'gpac'. The audio playback, which is disabled
153# by default, can be enabled by setting `enable_audio_playback` to `True`.
154
155app = MpegDashApplication(
156    h1,
157    h4,
158    eth1.get_address(),
159    eth4.get_address(),
160    9000,
161    OUTPUT_PATH,
162    100,
163    player="gpac",
164    enable_audio_playback=False,
165)
166
167exp.add_mpeg_dash_application(app)
168exp.run()