Exercise4.md
July 17, 2026 · View on GitHub
Exercise 4 - Full open source DMF
Synopsis
In this exercise, we will compile the latest commit of the MXL SDK including rust bindings and the rust Gstreamer plugins. Then we will build a full stream augmentation workflow supported by various open source project. A full list is found at the end of this document.
flowchart LR
subgraph HostNode [Host / Compute Node]
direction LR
%% --- Stage 1: Sources ---
subgraph Sources [Sources]
direction TB
HLS2MXL[HLS2MXL]
LoopPlayer[File Player]
TestGen[Test Generator]
WebRTC2MXL[WebRTC2MXL]
end
%% --- Stage 2: Processing ---
subgraph Processing [Processing]
direction TB
AudioMix[Audio Mix]
HTML5Keyer[HTML5 Keyer]
SPXGraphics[SPX Graphics]
end
%% --- Stage 3: Output ---
MXL2WebRTC[MXL2WebRTC]
%% =========================================
%% CONNECTIONS
%% =========================================
%% --- Solid Video (blue) Connections (Indices 0 to 4) ---
%% Video Sources to Input selector
HLS2MXL -- IN 1 --> InputSel
LoopPlayer -- IN 2--> InputSel
TestGen -- IN 3 --> InputSel
%% Input Selector to Processing
InputSel --> HTML5Keyer
%% Processing to Output
HTML5Keyer --> MXL2WebRTC
%% --- Solid Audio (green) Connection (Indices 5 to 7) ---
%% Audio Sources to Audio Mixer
WebRTC2MXL -- IN 2 --> AudioMix
HLS2MXL -- IN 1 --> AudioMix
%% Audio Processing to/From MXL
AudioMix --> MXL2WebRTC
end
%% --- Legend (Outside the Compute Node) (Indices 8 to 10) ---
subgraph Legend [Diagram Key]
direction LR
k1[Gstreamer</br>based app] -- MXL Video flow --> kt1[Gstreamer</br>based app]
k2[Gstreamer</br>based app] -- MXL Audio flow --> kt2[Gstreamer</br>based app]
k4[HTML 5 Graphic</br>engine]
k5[Future Apps]
end
%% Positioning the legend below the main node
HostNode ~~~ Legend
%% ===========================================
%% STYLING
%% ===========================================
%% Node Styling
classDef gstreamer fill:#66b3ff,color:black,stroke:#333,stroke-width:2px;
classDef control fill:#007bff,color:#fff,stroke:#333,stroke-width:2px;
classDef other fill:#cce6ff,color:black,stroke:#333,stroke-width:2px;
classDef future fill:#ffcccc,color:black,stroke:#cc0000,stroke-width:2px,stroke-dasharray:5 5
class HLS2MXL,LoopPlayer,TestGen,InputSel,HTML5Keyer,MXL2WebRTC,WebRTC2MXL,k1,kt1,k2,kt2,k3 gstreamer
class AudioMix,k5 future
class NmosRegistry,DummyNmosNode,NmosController,kt3 control
class SPXGraphics,k4 other
%% Link Styling
%% Solid blue for video connections
linkStyle 0,1,2,3,4,8 stroke:blue,stroke-width:2px
%% Solid green for audio connections
linkStyle 5,6,7,9 stroke:green,stroke-width:2px
Steps
-
Navigate to exercise 5 working directory
cd ~/mxl-hands-on/docker/exercise-4 -
If you did NOT do the preparations steps for WLS, make sure you have a /Volumes/mxl mounted in tmpfs.
sudo mount -t tmpfs -o size=512m,uid=1000,gid=1000,mode=0755 tmpfs /Volumes/mxl # on WSL linux sudo mkdir -p /Volumes/mxl/domain_1 sudo chown 1000:1000 /Volumes/mxl/domain_1 -
Making sure we have at least one clip for our clip player application (you can add more of your own, .mp4 or .ts)
cp ~/mxl-hands-on/build-images/sizzle.ts data/Clips -
Start the system with the start script.
./start.sh # For linux based system./start-mac.sh # For mac based system -
Use the application and try to reproduce the workflow above. You have more documentation on application usage here
-
When you are down, do not forget to shutdown your containers.
stop.sh # For linux based system./stop-mac.sh # For mac based system
| App | URL | API Swagger Page |
|---|---|---|
| Test Generator | http://localhost:9600 | http://localhost:9600/docs |
| MXL Info GUI | http://localhost:9699 | http://localhost:9699/docs |
| MXL to WebRTC | http://localhost:9601 | http://localhost:9601/docs |
| File Player | http://localhost:9602 | http://localhost:9602/docs |
| HLS to MXL Gateway | http://localhost:9603 | http://localhost:9603/docs |
| Input Selector | http://localhost:9604 | http://localhost:9604/docs |
| HTML5 Keyer | http://localhost:9605 | http://localhost:9605/docs |
| SPX server | http://localhost:5660 | none |
Reference HLS stream that are 1920x1080p60
https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8
https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8
Open Source Components
| Component | Category | License | Test Gen | Info GUI | MXL2WebRTC | File Player | HLS2MXL | Input Sel | HTML5 Keyer |
|---|---|---|---|---|---|---|---|---|---|
| React | Frontend | MIT | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| React DOM | Frontend | MIT | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Vite | Frontend | MIT | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| @vitejs/plugin-react | Frontend | MIT | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| MXL | MXL | Apache-2.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| FastAPI | Python 3 | MIT | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Uvicorn | Python 3 | BSD-3-Clause | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| aiofiles | Python 3 | Apache-2.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Pydantic | Python 3 | MIT | — | — | ✓ | — | ✓ | ✓ | ✓ |
| python-multipart | Python 3 | Apache-2.0 | ✓ | ✓ | — | ✓ | ✓ | — | — |
| Requests | Python 3 | Apache-2.0 | ✓ | — | — | — | ✓ | — | — |
| PyGObject | GStreamer | LGPL-2.1+ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
| GStreamer | GStreamer | LGPL-2.0+ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
| GStreamer plugins-base | GStreamer | LGPL-2.0+ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
| GStreamer plugins-good | GStreamer | LGPL-2.0+ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
| GStreamer plugins-bad | GStreamer | LGPL-2.0+ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
| GStreamer plugins-ugly | GStreamer | LGPL-2.0+ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
| GStreamer libav | GStreamer | LGPL-2.0+ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
| GStreamer nice (libnice) | GStreamer | LGPL-2.1 | — | — | ✓ | — | — | — | — |
| gstcefsrc | GStreamer | LGPL-2.0+ | — | — | — | — | — | — | ✓ |
| CEF (Chromium Embedded Framework) | Browser Engine | BSD-3-Clause | — | — | — | — | — | — | ✓ |
| MediaMTX | Infrastructure | MIT | — | — | ✓ | — | — | — | — |
| Ubuntu 24.04 | Base Image | Various | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Node.js 18 | Build | MIT | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |