Dynamic adaptive-streaming delivery from media you already store.
dyndo serves existing CMAF files without repackaging or duplicating their
media bytes. A small JSON descriptor supplies the presentation metadata;
manifests, segment views, subtitles, and thumbnails are produced when requested
while the original media stays untouched.
- Store media once. Segment requests are byte-range reads from the original CMAF objects, not files copied into a second packaging layout.
- Change presentation without rewriting media. Correct metadata, add a subtitle, or choose delivery variants in a small descriptor or request URL.
- Keep URLs stable. Track IDs derive from source paths, not mutable labels.
- Keep sources immutable. The server reads only headers and requested byte ranges, which suits read-only filesystems and object storage.
- Scale with metadata, not file size. dyndo derives its index from bounded header reads instead of scanning complete media objects.
https://matvp91.github.io/dyndo/
curl -fsSL https://matvp91.github.io/dyndo/install.sh | bashInstalls the prebuilt dyndo CLI for macOS or Linux into ~/.dyndo/bin and
puts it on your PATH. Pin a version with bash -s <version>. To build from
source instead, follow the Quickstart below.
# Build both binaries; install the dyndo CLI into ~/.cargo/bin
cargo build
make install
# Index your CMAF sources into a descriptor under ./assets
dyndo index video.mp4 audio.mp4 -o assets/asset.json
# Serve it as DASH + HLS from ./assets on :8080
make runThen point a player at either protocol — the bracketed part names the descriptor
relative to the storage root, without its .json extension:
http://localhost:8080/out/(asset:asset)/index.mpd # DASH
http://localhost:8080/out/(asset:asset)/master.m3u8 # HLS
Prefer not to build at all? dyndo-server is published to Docker Hub as
matvp91/dyndo-server:
docker run --rm -p 8080:8080 -e DYNDO_FS__ROOT=/assets \
-v "$PWD/assets:/assets:ro" matvp91/dyndo-serverdyndo is a Cargo workspace of five crates — three libraries and two binaries —
with a strictly one-way dependency direction. dyndo-core knows nothing about
manifests; the two manifest crates know nothing about each other; neither
library layer knows anything about CLI or HTTP concerns.
binaries dyndo-cli dyndo-server
│ ┌───┴───┐
manifests │ dyndo-dash dyndo-hls
│ └───┬───┘
core └───────────────────── dyndo-core
| Crate | Kind | Responsibility |
|---|---|---|
dyndo-core |
library | CMAF header parsing, track and segment models, byte-range reading, WebVTT packaging, and on-demand thumbnail generation. Reads storage through OpenDAL. |
dyndo-dash |
library | DASH MPD generation: adaptation-set grouping, segment templates and timelines, DASH role signalling. |
dyndo-hls |
library | HLS playlist generation: the multivariant playlist, per-track media playlists, rendition groups and HLS role signalling. |
dyndo-cli |
binary (dyndo) |
Indexes sources into descriptors and extracts video frames as JPEG images. |
dyndo-server |
binary (dyndo-server) |
The dynamic packaging HTTP server, built on Axum. |
dyndo-server combines the protocol builders with the storage and segment model
in dyndo-core. The CLI works directly with dyndo-core; it does not generate
manifests.
Common tasks are wrapped in the Makefile:
| Target | Description |
|---|---|
make build |
Release build of the CLI. |
make build-debug |
Debug build of the CLI. |
make run |
Run dyndo-server. |
make test |
Run the whole workspace test suite. |
make lint |
Clippy across all targets, warnings as errors. |
make fmt |
Format all crates (nightly rustfmt). |
make fmt-check |
Verify formatting without modifying. |
make check |
Fast type-check of the workspace. |
make install |
Install the dyndo CLI into ~/.cargo/bin. |
make doc |
Build the crates' rustdoc. |
make book |
Build the mdBook user guide into docs/book. |
make book-serve |
Serve the mdBook user guide locally with live reload. |
make clean |
Remove build artifacts. |
Building the book needs mdBook — install
the version pinned as MDBOOK_VERSION in
.github/workflows/docs.yml
(cargo install mdbook --version <that version>) so local output matches CI.
The guide sources are in docs/.
Tests run against small, committed header-only CMAF fixtures in the
dyndo-core,
dyndo-dash, and
dyndo-hls crates — just enough of each file
(ftyp + moov + sidx + first moof) to exercise parsing end to end without
shipping gigabytes of media.