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.
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.
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()