{"id":13586939,"url":"https://github.com/emarsden/dash-mpd-cli","last_synced_at":"2025-10-21T04:48:46.845Z","repository":{"id":41325213,"uuid":"451507822","full_name":"emarsden/dash-mpd-cli","owner":"emarsden","description":"Download media content from a DASH-MPEG or DASH-WebM MPD manifest","archived":false,"fork":false,"pushed_at":"2024-10-29T12:08:19.000Z","size":407,"stargazers_count":315,"open_issues_count":10,"forks_count":32,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-10-29T14:37:17.934Z","etag":null,"topics":["dash","downloader","mpeg","mpeg-dash","rust","streaming","video"],"latest_commit_sha":null,"homepage":"https://emarsden.github.io/dash-mpd-cli/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emarsden.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-MIT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-24T14:56:12.000Z","updated_at":"2024-10-29T14:21:35.000Z","dependencies_parsed_at":"2023-02-16T11:40:27.891Z","dependency_job_id":"7608a113-87ee-4a4d-ac30-14957c8698c6","html_url":"https://github.com/emarsden/dash-mpd-cli","commit_stats":{"total_commits":366,"total_committers":4,"mean_commits":91.5,"dds":0.09562841530054644,"last_synced_commit":"47bf6ebd8f21ef93d75118259a63733c02771908"},"previous_names":[],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emarsden%2Fdash-mpd-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emarsden%2Fdash-mpd-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emarsden%2Fdash-mpd-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emarsden%2Fdash-mpd-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emarsden","download_url":"https://codeload.github.com/emarsden/dash-mpd-cli/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247707850,"owners_count":20982862,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dash","downloader","mpeg","mpeg-dash","rust","streaming","video"],"created_at":"2024-08-01T15:05:55.386Z","updated_at":"2025-10-21T04:48:46.823Z","avatar_url":"https://github.com/emarsden.png","language":"Rust","funding_links":[],"categories":["Rust","HarmonyOS","video","Protocols \u0026 Transport"],"sub_categories":["Windows Manager","DASH Tools"],"readme":"# dash-mpd-cli\n\nA commandline application for downloading media content from a DASH MPD file, as used for on-demand\nreplay of TV content and video streaming services.\n\n[![Crates.io](https://img.shields.io/crates/v/dash-mpd-cli)](https://crates.io/crates/dash-mpd-cli)\n[![CI](https://github.com/emarsden/dash-mpd-cli/workflows/build/badge.svg)](https://github.com/emarsden/dash-mpd-cli/actions/)\n[![Container size](https://ghcr-badge-hwb3.onrender.com/emarsden/dash-mpd-cli/size?label=Container%20image)](https://github.com/users/emarsden/packages/container/package/dash-mpd-cli)\n[![Dependency status](https://deps.rs/repo/github/emarsden/dash-mpd-cli/status.svg)](https://deps.rs/repo/github/emarsden/dash-mpd-cli)\n[![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE-MIT)\n[![Github downloads](https://img.shields.io/github/downloads/emarsden/dash-mpd-cli/total)]()\n\n![Terminal capture](https://risk-engineering.org/emarsden/dash-mpd-cli/terminal-capture.svg)\n\n\n[DASH](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP) (dynamic adaptive\nstreaming over HTTP), also called MPEG-DASH, is a technology used for media streaming over the web,\ncommonly used for video on demand (VOD) and “replay/catch-up TV” services. The Media Presentation\nDescription (MPD) is an XML document that lists the resources (manifest or “playlist”) forming a\nstreaming service. A DASH client uses the manifest to determine which assets to request in order to\nperform adaptive streaming of the content. DASH MPD manifests can be used with content using\ndifferent codecs (including H264, HEVC, AV1, AAC, VP9, MP4A, MP3) and containers (MP4, WebM,\nMatroska, AVI). There is a good explanation of adaptive bitrate video streaming at\n[howvideo.works](https://howvideo.works/#dash).\n\nThis commandline application allows you to **download streaming video** or audio to your local\ndevice. This involves selecting the alternative with the most appropriate encoding (in terms of\nbitrate, codec, etc.), fetching segments of the content using HTTP or HTTPS requests and muxing\naudio and video segments together. There is also support for downloading subtitles (mostly WebVTT,\nTTML, SRT, tx3g and SMIL formats, with some support for wvtt format).\n\nThis application builds on the [dash-mpd](https://crates.io/crates/dash-mpd) crate. It works for\nstreaming that uses DASH adaptive streaming (MPD manifests), and doesn’t currently have support for\nHLS streaming (m3u8 manifests).\n\n📖 You may be interested in the [user manual](https://emarsden.github.io/dash-mpd-cli/).\n\n\n## Features\n\nThe following features are supported:\n\n- **Multi-period** content. The media in the different streams will be saved in a single media container\n  if the formats are compatible (same resolution, codecs, bitrate and so on) and the\n  `--no-period-concatenation` commandline option is not provided, and otherwise in separate media\n  containers.\n\n- The application can download content available over HTTP, HTTPS and HTTP/2. Network bandwidth can\n  be throttled (see the `--limit-rate` commandline argument).\n\n- Support for SOCKS and HTTP **proxies**, via the `--proxy` commandline argument. The following\n  environment variables can also be used to specify the proxy at a system level: `HTTP_PROXY` or\n  `http_proxy` for HTTP connections, `HTTPS_PROXY` or `https_proxy` for HTTPS connections, and\n  `ALL_PROXY` or `all_proxy` for all connection types. The system proxy can be disabled using the\n  `--no-proxy` commandline argument.\n\n- Support for HTTP Basic **authentication** (see the `--auth-username` and `--auth-password` commandline\n  arguments) and for Bearer authentation (see the `--auth-bearer` commandline argument). This\n  authentication information is sent both to the server which hosts the DASH manifest, and to the\n  server that hosts the media segments (the latter often being a CDN).\n\n- **Subtitles**: download support for WebVTT, TTML, SRT, tx3g and SMIL streams, as well as some support\n  for the wvtt format. We support both subtitles published as a complete file and segmented\n  subtitles made available in media fragments.\n\n- The application can read **cookies** from the Firefox, Chromium, Chrome, ChromeBeta, Safari and\n  Edge browsers on Linux, Windows and MacOS, thanks to the\n  [bench_scraper](https://crates.io/crates/bench_scraper) crate. See the `--cookies-from-browser`\n  commandline argument. Browsers that support multiple profiles will have all their profiles scraped\n  for cookies.\n\n- Support for **decrypting** media streams that use ContentProtection (DRM 🗝️). This requires either the\n  `mp4decrypt` or `shaka-packager` commandline application to be installed. mp4decrypt is available\n  from the [Bento4 suite](https://github.com/axiomatic-systems/Bento4/) ([binaries are\n  available](https://www.bento4.com/downloads/) for common platforms), and [shaka-packager\n  binaries](https://github.com/shaka-project/shaka-packager) are available from Google for common\n  platforms (see the Releases section on their GitHub page). See the `--key` commandline argument to\n  specify a decryption key (can be used several times if different keys are used for different media\n  streams). See the `--decryption-application` commandline argument to specify which decryption\n  application to use. Shaka packager is able to decrypt more types of media streams (including in\n  particular WebM containers and more encryption formats), whereas mp4decrypt mostly works with MPEG\n  Common Encryption.\n\n- Support for selecting the streams to download based on audio language, quality, horizontal and\n  vertical resolution of the video stream, and role annotation (e.g. `main` instead of `alternate`\n  role).\n\n- Support for **[rewriting the MPD\n  manifest](https://emarsden.github.io/dash-mpd-cli/rewriting.html)** before downloading, for\n  example to replace the URL of certain segments by other URLs, or to drop certain Periods based on\n  different criteria (such as the CDN or DAI server they originate from, the content language). The\n  rewriting instructions are specified by a user-supplied XSLT stylesheet, which is applied to the\n  XML of the MPD manifest (see the `--xslt-stylesheet` commandline argument). A convenience form for\n  dropping elements based on an XPath specification is also provided (see the `--drop-elements`\n  commandline argument). This functionality depends on the xsltproc commandline tool.\n\n- XLink elements (only with actuate=onLoad semantics), including resolve-to-zero.\n\n- All forms of segment index info: SegmentBase@indexRange, SegmentTimeline,\n  SegmentTemplate@duration, SegmentTemplate@index, SegmentList.\n\n- Media containers of types supported by mkvmerge, ffmpeg, VLC or MP4Box (this includes ISO-BMFF /\n  CMAF / MP4, Matroska, WebM, MPEG-2 TS, AVI), and all the codecs supported by these applications.\n\n- Any video resolution available on the streaming server, including 1080p and 4K content.\n\n- In practice, all features used by real streaming services and on-demand TV. Our test suite\n  includes test streams published by industry groups such as HbbTV and the DASH Industry Forum, and\n  comprises a wide variety of DASH streams using different publishing software, including GPAC (used\n  by Netflix and other services), Amazon MediaTailor, Google’s Shaka packager, Microsoft’s Azure\n  Media Services, and Unified Streaming. Test content is served by different CDNs including Akamai\n  and various telecom providers.\n\nThe following are not currently supported:\n\n- **Live streams** (dynamic MPD manifests), that are used for live streaming/OTT TV are not really\n  supported. This is because we don’t implement the clock-related throttling that is needed to only\n  download media segments when they become available. However, some media sources publish\n  “pseudo-live” streams where all media segments are in fact available; they simply don’t update the\n  manifest once the live is complete. We are able to download these streams using the\n  `--enable-live-streams` commandline argument. You might also have some success with a live stream\n  in combination with the `--sleep-requests` commandline argument. The VLC application is a better\n  choice for watching live streams.\n\n- XLink elements with actuate=onRequest semantics.\n\n- HLS streaming (m3u8 manifests).\n\n- Microsoft Smooth Streaming\n\n\n\n## Run safely in a Docker container\n\nThe application, alongside the external helper applications that it uses for muxing media streams,\nfor extracting/converting subtitle streams, and for decrypting content infected with DRM, are\navailable as a prebuilt container, which is probably the easiest and safest way to run it. The\ncontainer is packaged with a minimal Alpine Linux installation and can be run on any host that can\nrun Linux containers (using [Podman](https://podman.io/) or [Docker](https://www.docker.com/) on\nLinux, Microsoft Windows and MacOS). It’s available in the GitHub Container Registry `ghcr.io`.\n\n\u003e [!TIP]\n\u003e What are the **advantages of running in a container**, instead of natively on your machine?\n\u003e\n\u003e - Much safer, because the container isn't able to modify your host machine, except for writing\n\u003e   downloaded media to the directory you specify. This is a very good idea when running random\n\u003e   software you downloaded from the internet!\n\u003e\n\u003e - No need to install the various helper applications (ffmpeg, mkvmerge, mp4decrypt,\n\u003e   shaka-packager, MP4Box, xsltproc), which are already present in the container.\n\u003e\n\u003e - Automatically run the latest version of dash-mpd-cli and the various helper applications (the\n\u003e   container runtime will pull the latest version for you automatically).\n\u003e\n\u003e - Podman and Docker also allow you to set various limits on the resources allocated to the\n\u003e   container (number of CPUs, memory); see their respective documentation.\n\nUnlike running software in a virtual machine, there is only a negligeable performance penalty to\nrunning in a container. That’s not quite true: if you’re running the container on an aarch64 (“Apple\nSilicon”) Mac, Podman will set up a virtual machine for you. On Windows, Podman will set up a\nlow-overhead WSL2 virtual machine for you.\n\nI recommend installing [Podman](https://podman.io/) because it’s fully free software, whereas Docker\nis partly commercial. Podman is also able to run containers “rootless”, without special privileges,\nwhich is good for security.\n\nTo **run the container** with podman:\n\n    podman machine start (optional step, only required on Windows and MacOS)\n    podman run --rm -v .:/content ghcr.io/emarsden/dash-mpd-cli -v \u003cMPD-URL\u003e -o foo.mp4\n\nOn the first run, this will fetch the container image (around 220 MB) from the GitHub Container\nRegistry ghcr.io, and will save it on your local disk for later uses. You can later delete the image\nif you no longer need it using `podman image rm` and the image id shown by `podman images` (see the\n[user manual](https://emarsden.github.io/dash-mpd-cli/container.html) for details).\n\n📁 Your current working directory (`.`) will be mounted in the container as `/content`, which will be\nthe working directory in the container. This means that an output file specified without a root\ndirectory, such as `foo.mp4`, will be saved to your current working directory on the host machine.\n\nOn Linux/AMD64, it’s also possible to run the container using the [gVisor](https://gvisor.dev/)\ncontainer runtime runsc, which uses a sandbox to further improve security (strong isolation, protection\nagainst privilege escalation). This requires installation of runsc and running as root (runsc\ndoesn’t currently support rootless operation).\n\n    sudo apt install runsc\n    sudo podman --runtime=runsc run --rm -v .:/content ghcr.io/emarsden/dash-mpd-cli -v \u003cMPD-URL\u003e -o foo.mp4\n\nThe container image is a **multiarch** manifest, currently built for the following platforms:\n\n- linux/amd64\n- linux/arm64\n- linux/armv7 (should run on a Raspberry Pi)\n- linux/riscv64\n- linux/ppc64le\n\n\n## Installation\n\nIf you prefer to install the software and its dependencies on your computer in the traditional way,\nyou can download a prebuilt binary or build from source yourself.\n\n**Binary releases** are [available on GitHub](https://github.com/emarsden/dash-mpd-cli/releases) for\nGNU/Linux on AMD64 (statically linked against Musl Libc to avoid glibc versioning problems),\nMicrosoft Windows on AMD64 and MacOS on aarch64 (“Apple Silicon”). These are built\nautomatically on the GitHub continuous integration infrastructure.\n\nOn macOS and Linux, you can install the software using [Homebrew](https://brew.sh/):\n\n```shell\nbrew install dash-mpd-cli\n```\n\nYou can also **build from source** using an [installed Rust development\nenvironment](https://www.rust-lang.org/tools/install):\n\n```shell\ncargo install dash-mpd-cli\n```\n\nThis installs the binary to your installation root’s `bin` directory, which is typically\n`$HOME/.cargo/bin`.\n\nYou should also install the following **dependencies**:\n\n- the mkvmerge commandline utility from the [MkvToolnix](https://mkvtoolnix.download/) suite, if you\n  download to the Matroska container format (`.mkv` filename extension). mkvmerge is used as a\n  subprocess for muxing (combining) audio and video streams. See the `--mkvmerge-location`\n  commandline argument if it’s not installed in a standard location (not on your PATH).\n\n- [ffmpeg](https://ffmpeg.org/) or [vlc](https://www.videolan.org/vlc/) to download to the MP4\n  container format, also for muxing audio and video streams (see the `--ffmpeg-location` and\n  `--vlc-location` commandline arguments if these are installed in non-standard locations). See the\n  `--muxer-preference` commandline argument to specify which muxing application to prefer for\n  different container types.\n\n- the MP4Box commandline utility from the [GPAC](https://gpac.wp.imt.fr/) project, if you want to\n  test the preliminary support for retrieving subtitles in wvtt format. If it's installed, MP4Box\n  will be used to convert the wvtt stream to the more widely recognized SRT format. MP4Box can also\n  be used for muxing audio and video streams to an MP4 container, as a fallback if ffmpeg and vlc\n  are not available. See the `--mp4box-location` commandline argument if this is installed in a\n  non-standard location.\n\n- the mp4decrypt commandline application from the [Bento4\n  suite](https://github.com/axiomatic-systems/Bento4/), if you need to fetch encrypted content.\n  [Binaries are available](https://www.bento4.com/downloads/) for common platforms. See the\n  `--mp4decrypt-location` commandline argument if this is installed in a non-standard location.\n\n- for some types of streams that the mp4decrypt application is not able to decrypt (for example\n  content in WebM containers), you should install the [Shaka packager\n  application](https://github.com/shaka-project/shaka-packager) developed by Google. See the\n  `--decryption-application` commandline option to specify the choice of decryption application, and\n  the `--shaka-packager-location` commandline argument if it is installed in a non-standard location.\n\n- the xsltproc commandline utility packaged with libxslt, which is used for the MPD rewriting\n  functionality (the `--drop-elements` and `--xslt-stylesheet` commandline options).\n\nThis crate is tested on the following **platforms**:\n\n- Our prebuilt container images are tested using Podman on Linux and Windows\n\n- Linux on AMD64 (x86-64) and Aarch64 architectures\n\n- MacOS on AMD64 and Aarch64 (“Apple Silicon”) architectures\n\n- Microsoft Windows 10 and Windows 11 on AMD64\n\n- Android 12 on Aarch64 via [termux](https://termux.dev/) (you’ll need to install the rust, binutils\n  and ffmpeg packages, and optionally the mkvtoolnix, vlc and gpac packages). You’ll need to disable\n  the `cookies` feature by building with `--no-default-features`.\n\n- FreeBSD/AMD64 and OpenBSD/AMD64. You’ll need to disable the `cookies` feature. Some of the\n  external applications we depend on (e.g. mp4decrypt, Shaka packager) are poorly supported on OpenBSD.\n\n\n\n## Usage\n\nSee the 📖 [user manual](https://emarsden.github.io/dash-mpd-cli/usage.html).\n\n\n\n## Muxing\n\nThe underlying library `dash-mpd-rs` has two methods for muxing audio and video streams together. If\nthe library feature `libav` is enabled (which is not the default configuration), muxing support is\nprovided by ffmpeg’s libav library, via the `ac_ffmpeg` crate. Otherwise, muxing is implemented by\ncalling an external muxer, mkvmerge (from the [MkvToolnix](https://mkvtoolnix.download/) suite),\n[ffmpeg](https://ffmpeg.org/), [vlc](https://www.videolan.org/vlc/) or\n[MP4Box](https://github.com/gpac/gpac/wiki/MP4Box) as a subprocess. Note that these commandline\napplications implement a number of checks and workarounds to fix invalid input streams that tend to\nexist in the wild. Some of these workarounds are implemented here when using libav as a library, but\nnot all of them, so download support tends to be more robust with the default configuration (using\nan external application as a subprocess). The `libav` feature currently only works on Linux.\n\nThe choice of external muxer depends on the filename extension of the path supplied to `--output`\nor `-o` (which will be `.mp4` if you don't specify the output path explicitly):\n\n- `.mkv`: call mkvmerge first, then if that fails call ffmpeg, then try MP4Box\n- `.mp4`: call ffmpeg first, then if that fails call vlc, then try MP4Box\n- `.webm`: call vlc, then if that fails ffmpeg\n- other: try ffmpeg, which supports many container formats, then try MP4Box\n\nYou can specify a different order of preference for muxing applications using the\n`--muxer-preference` commandline option. For example, `--muxer-preference avi:vlc,ffmpeg` means that\nfor an AVI media container the external muxer vlc will be tried first, then ffmpeg in case of\nfailure. This commandline option can be used multiple times to specify options for different\ncontainer types.\n\n\n\n## Similar tools\n\nSimilar commandline tools that are able to download content from a DASH manifest:\n\n- `yt-dlp \u003cMPD-URL\u003e`\n\n- `N_m3u8DL-RE \u003cMPD-URL\u003e`\n\n- `streamlink -o /tmp/output.mp4 \u003cMPD-URL\u003e worst`\n\n- `ffmpeg -i \u003cMPD-URL\u003e -vcodec copy /tmp/output.mp4`\n\n- `vlc \u003cMPD-URL\u003e`\n\n- `gst-launch-1.0 playbin uri=\u003cMPD-URL\u003e`\n\nHowever, dash-mpd-cli (this application) is able to download content from certain streams that do\nnot work with other applications:\n\n- streams using xHE-AAC codecs are currently unsupported by ffmpeg, streamlink, VLC, and gstreamer\n- streams in multi-period manifests\n- streams using XLink elements\n\n\n## Building\n\n```\n$ sudo apt install protobuf-compiler\n$ git clone https://github.com/emarsden/dash-mpd-cli\n$ cd dash-mpd-cli\n$ cargo build --release\n$ target/release/dash-mpd-cli --help\n```\n\nThe application can also be built statically with the musl-libc target on Linux. First install the\n[MUSL C standard library](https://musl.libc.org/) on your system. Add linux-musl as a target to your\nRust toolchain, then rebuild for the relevant target:\n\n```\n$ sudo apt install musl-dev\n$ rustup target add x86_64-unknown-linux-musl\n$ cargo build --release --target x86_64-unknown-linux-musl\n```\n\nStatic musl-libc builds don’t work with OpenSSL, which is why we disable default features on the\ndash-mpd crate and build it with [rustls](https://github.com/rustls/rustls) support (a Rust TLS\nstack). You may encounter some situations where rustls fails to connect (handshake errors, for\nexample) but other applications on your system can connect. These differences in behaviour are\ntypically due to different configurations for the set of root certificates. If you prefer to use\nyour machine’s native TLS stack, replace both instances of `rustls-tls` by `native-tls` in\n`Cargo.toml` and rebuild.\n\n\n## Why?\n\nThe [dash-mpd-rs](https://github.com/emarsden/dash-mpd-rs) library at the core of this application\nwas developed to allow the author to watch a news programme produced by a public media broadcaster\nwhilst at the gym. The programme is published as a DASH stream on the broadcaster’s “replay”\nservice, but network service at the gym is sometimes poor. First world problems!\n\n\u003e [!WARNING]\n\u003e The author is not the morality police nor a lawyer, but please note that redistributing media\n\u003e content that you have not produced may, depending on the publication licence, be a breach of\n\u003e intellectual property laws. Also, circumventing DRM may be prohibited in some countries.\n\n\n## License\n\nThis project is licensed under the MIT license. For more information, see the `LICENSE-MIT` file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femarsden%2Fdash-mpd-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femarsden%2Fdash-mpd-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femarsden%2Fdash-mpd-cli/lists"}