GithubHelp home page GithubHelp logo

emarsden / dash-mpd-cli Goto Github PK

View Code? Open in Web Editor NEW
223.0 6.0 26.0 374 KB

Download media content from a DASH-MPEG or DASH-WebM MPD manifest

Home Page: https://emarsden.github.io/dash-mpd-cli/

License: MIT License

Rust 87.21% Shell 1.33% Dockerfile 11.46%
downloader mpeg-dash rust streaming video dash mpeg

dash-mpd-cli's Introduction

dash-mpd-cli

A commandline application for downloading media content from a DASH MPD file, as used for on-demand replay of TV content and video streaming services.

Crates.io CI Dependency status LICENSE

Terminal capture

DASH (dynamic adaptive streaming over HTTP), also called MPEG-DASH, is a technology used for media streaming over the web, commonly used for video on demand (VOD) and “replay/catch-up TV” services. The Media Presentation Description (MPD) is an XML document that lists the resources (manifest or “playlist”) forming a streaming service. A DASH client uses the manifest to determine which assets to request in order to perform adaptive streaming of the content. DASH MPD manifests can be used with content using different codecs (including H264, HEVC, AV1, AAC, VP9, MP4A, MP3) and containers (MP4, WebM, Matroska, AVI). There is a good explanation of adaptive bitrate video streaming at howvideo.works.

This commandline application allows you to download streaming video or audio to your local device. This involves selecting the alternative with the most appropriate encoding (in terms of bitrate, codec, etc.), fetching segments of the content using HTTP or HTTPS requests and muxing audio and video segments together. There is also support for downloading subtitles (mostly WebVTT, TTML, SRT, tx3g and SMIL formats, with some support for wvtt format).

This application builds on the dash-mpd crate. It works for streaming that uses DASH adaptive streaming (MPD manifests), and doesn’t currently have support for HLS streaming (m3u8 manifests).

📖 You may be interested in the user manual.

Features

The following features are supported:

  • Multi-period content. The media in the different streams will be saved in a single media container if the formats are compatible (same resolution, codecs, bitrate and so on) and the --no-period-concatenation commandline option is not provided, and otherwise in separate media containers.

  • The application can download content available over HTTP, HTTPS and HTTP/2. Network bandwidth can be throttled (see the --limit-rate commandline argument).

  • Support for SOCKS and HTTP proxies, via the --proxy commandline argument. The following environment variables can also be used to specify the proxy at a system level: HTTP_PROXY or http_proxy for HTTP connections, HTTPS_PROXY or https_proxy for HTTPS connections, and ALL_PROXY or all_proxy for all connection types. The system proxy can be disabled using the --no-proxy commandline argument.

  • Support for HTTP Basic authentication (see the --auth-username and --auth-password commandline arguments) and for Bearer authentation (see the --auth-bearer commandline argument). This authentication information is sent both to the server which hosts the DASH manifest, and to the server that hosts the media segments (the latter often being a CDN).

  • Subtitles: download support for WebVTT, TTML, SRT, tx3g and SMIL streams, as well as some support for the wvtt format. We support both subtitles published as a complete file and segmented subtitles made available in media fragments.

  • The application can read cookies from the Firefox, Chromium, Chrome, ChromeBeta, Safari and Edge browsers on Linux, Windows and MacOS, thanks to the bench_scraper crate. See the --cookies-from-browser commandline argument. Browsers that support multiple profiles will have all their profiles scraped for cookies.

  • Support for decrypting media streams that use ContentProtection (DRM 🗝️). This requires either the mp4decrypt or shaka-packager commandline application to be installed. mp4decrypt is available from the Bento4 suite (binaries are available for common platforms), and shaka-packager binaries are available from Google for common platforms (see the Releases section on their GitHub page). See the --key commandline argument to specify a decryption key (can be used several times if different keys are used for different media streams). See the --decryption-application commandline argument to specify which decryption application to use. Shaka packager is able to decrypt more types of media streams (including in particular WebM containers and more encryption formats), whereas mp4decrypt mostly works with MPEG Common Encryption.

  • XLink elements (only with actuate=onLoad semantics), including resolve-to-zero.

  • All forms of segment index info: SegmentBase@indexRange, SegmentTimeline, SegmentTemplate@duration, SegmentTemplate@index, SegmentList.

  • Media containers of types supported by mkvmerge, ffmpeg, VLC or MP4Box (this includes ISO-BMFF / CMAF / MP4, Matroska, WebM, MPEG-2 TS, AVI), and all the codecs supported by these applications.

  • Any video resolution available on the streaming server, including 1080p and 4K content.

  • In practice, all features used by real streaming services and on-demand TV. Our test suite includes test streams published by industry groups such as HbbTV and the DASH Industry Forum, and comprises a wide variety of DASH streams using different publishing software, including GPAC (used by Netflix and other services), Amazon MediaTailor, Google’s Shaka packager, Microsoft’s Azure Media Services, and Unified Streaming. Test content is served by different CDNs including Akamai and various telecom providers.

The following are not currently supported:

  • Live streams (dynamic MPD manifests), that are used for live streaming/OTT TV are not really supported. This is because we don’t implement the clock-related throttling that is needed to only download media segments when they become available. However, some media sources publish “pseudo-live” streams where all media segments are in fact available; they simply don’t update the manifest once the live is complete. We are able to download these streams using the --enable-live-streams commandline argument. You might also have some success with a live stream in combination with the --sleep-requests commandline argument. The VLC application is a better choice for watching live streams.

  • XLink elements with actuate=onRequest semantics.

  • HLS streaming (m3u8 manifests).

Run safely in a Docker container

The application, alongside the external helper applications that it uses for muxing media streams, for extracting/converting subtitle streams, and for decrypting content infected with DRM, are available as a prebuilt container, which is probably the easiest and safest way to run it. The container is packaged with a minimal Alpine Linux installation and can be run on any host that can run Linux containers (using Podman or Docker on Linux, Microsoft Windows and MacOS). It’s available in the GitHub Container Registry ghcr.io.

Tip

What are the advantages of running in a container, instead of natively on your machine?

  • Much safer, because the container isn't able to modify your host machine, except for writing downloaded media to the directory you specify. This is a very good idea when running random software you downloaded from the internet!

  • No need to install the various helper applications (ffmpeg, mkvmerge, mp4decrypt, shaka-packager, MP4Box, xsltproc), which are already present in the container.

  • Automatically run the latest version of dash-mpd-cli and the various helper applications (the container runtime will pull the latest version for you automatically).

  • Podman and Docker also allow you to set various limits on the resources allocated to the container (number of CPUs, memory); see their respective documentation.

Unlike running software in a virtual machine, there is only a negligeable performance penalty to running in a container. That’s not quite true: if you’re running the container on an aarch64 (“Apple Silicon”) Mac, Podman will set up a virtual machine for you. On Windows, Podman will set up a low-overhead WSL2 virtual machine for you.

I recommend installing Podman because it’s fully free software, whereas Docker is partly commercial. Podman is also able to run containers “rootless”, without special privileges, which is good for security.

To run the container with podman:

podman machine start (optional step, only required on Windows and MacOS)
podman run --rm -v .:/content ghcr.io/emarsden/dash-mpd-cli -v <MPD-URL> -o foo.mp4

On the first run, this will fetch the container image (around 220 MB) from the GitHub Container Registry ghcr.io, and will save it on your local disk for later uses. You can later delete the image if you no longer need it using podman image rm and the image id shown by podman images (see the user manual for details).

📁 Your current working directory (.) will be mounted in the container as /content, which will be the working directory in the container. This means that an output file specified without a root directory, such as foo.mp4, will be saved to your current working directory on the host machine.

On Linux/AMD64, it’s also possible to run the container using the gVisor container runtime runsc, which uses a sandbox to further improve security (strong isolation, protection against privilege escalation). This requires installation of runsc and running as root (runsc doesn’t currently support rootless operation).

sudo apt install runsc
sudo podman --runtime=runsc run --rm -v .:/content ghcr.io/emarsden/dash-mpd-cli -v <MPD-URL> -o foo.mp4

The container image is a multiarch manifest, currently built for the following platforms:

  • linux/amd64
  • linux/arm64
  • linux/armv7 (should run on a Raspberry Pi)
  • linux/riscv64
  • linux/ppc64le

Installation

If you prefer to install the software and its dependencies on your computer in the traditional way, you can download a prebuilt binary or build from source yourself.

Binary releases are available on GitHub for GNU/Linux on AMD64 (statically linked against Musl Libc to avoid glibc versioning problems), Microsoft Windows on AMD64 and MacOS on aarch64 (“Apple Silicon”). These are built automatically on the GitHub continuous integration infrastructure.

You can also build from source using an installed Rust development environment:

cargo install dash-mpd-cli

This installs the binary to your installation root’s bin directory, which is typically $HOME/.cargo/bin.

You should also install the following dependencies:

  • the mkvmerge commandline utility from the MkvToolnix suite, if you download to the Matroska container format (.mkv filename extension). mkvmerge is used as a subprocess for muxing (combining) audio and video streams. See the --mkvmerge-location commandline argument if it’s not installed in a standard location (not on your PATH).

  • ffmpeg or vlc to download to the MP4 container format, also for muxing audio and video streams (see the --ffmpeg-location and --vlc-location commandline arguments if these are installed in non-standard locations). See the --muxer-preference commandline argument to specify which muxing application to prefer for different container types.

  • the MP4Box commandline utility from the GPAC project, if you want to test the preliminary support for retrieving subtitles in wvtt format. If it's installed, MP4Box will be used to convert the wvtt stream to the more widely recognized SRT format. MP4Box can also be used for muxing audio and video streams to an MP4 container, as a fallback if ffmpeg and vlc are not available. See the --mp4box-location commandline argument if this is installed in a non-standard location.

  • the mp4decrypt commandline application from the Bento4 suite, if you need to fetch encrypted content. Binaries are available for common platforms. See the --mp4decrypt-location commandline argument if this is installed in a non-standard location.

  • for some types of streams that the mp4decrypt application is not able to decrypt (for example content in WebM containers), you should install the Shaka packager application developed by Google. See the --decryption-application commandline option to specify the choice of decryption application, and the --shaka-packager-location commandline argument if it is installed in a non-standard location.

  • the xsltproc commandline utility packaged with libxslt, which is used for the MPD rewriting functionality (the --drop-elements and --xslt-stylesheet commandline options).

This crate is tested on the following platforms:

  • Our prebuilt container images are tested using Podman on Linux and Windows

  • Linux on AMD64 (x86-64) and Aarch64 architectures

  • MacOS on AMD64 and Aarch64 (“Apple Silicon”) architectures

  • Microsoft Windows 10 and Windows 11 on AMD64

  • Android 12 on Aarch64 via termux (you’ll need to install the rust, binutils and ffmpeg packages, and optionally the mkvtoolnix, vlc and gpac packages). You’ll need to disable the cookies feature by building with --no-default-features.

  • FreeBSD/AMD64 and OpenBSD/AMD64. You’ll need to disable the cookies feature. Some of the external applications we depend on (e.g. mp4decrypt, Shaka packager) are poorly supported on OpenBSD.

Usage

See the 📖 user manual.

Muxing

The underlying library dash-mpd-rs has two methods for muxing audio and video streams together. If the library feature libav is enabled (which is not the default configuration), muxing support is provided by ffmpeg’s libav library, via the ac_ffmpeg crate. Otherwise, muxing is implemented by calling an external muxer, mkvmerge (from the MkvToolnix suite), ffmpeg, vlc or MP4Box as a subprocess. Note that these commandline applications implement a number of checks and workarounds to fix invalid input streams that tend to exist in the wild. Some of these workarounds are implemented here when using libav as a library, but not all of them, so download support tends to be more robust with the default configuration (using an external application as a subprocess). The libav feature currently only works on Linux.

The choice of external muxer depends on the filename extension of the path supplied to --output or -o (which will be .mp4 if you don't specify the output path explicitly):

  • .mkv: call mkvmerge first, then if that fails call ffmpeg, then try MP4Box
  • .mp4: call ffmpeg first, then if that fails call vlc, then try MP4Box
  • .webm: call vlc, then if that fails ffmpeg
  • other: try ffmpeg, which supports many container formats, then try MP4Box

You can specify a different order of preference for muxing applications using the --muxer-preference commandline option. For example, --muxer-preference avi:vlc,ffmpeg means that for an AVI media container the external muxer vlc will be tried first, then ffmpeg in case of failure. This commandline option can be used multiple times to specify options for different container types.

Similar tools

Similar commandline tools that are able to download content from a DASH manifest:

  • yt-dlp <MPD-URL>

  • N_m3u8DL-RE <MPD-URL>

  • streamlink -o /tmp/output.mp4 <MPD-URL> worst

  • ffmpeg -i <MPD-URL> -vcodec copy /tmp/output.mp4

  • vlc <MPD-URL>

  • gst-launch-1.0 playbin uri=<MPD-URL>

However, dash-mpd-cli (this application) is able to download content from certain streams that do not work with other applications:

  • streams using xHE-AAC codecs are currently unsupported by ffmpeg, streamlink, VLC, and gstreamer
  • streams in multi-period manifests
  • streams using XLink elements

Building

$ sudo apt install protobuf-compiler
$ git clone https://github.com/emarsden/dash-mpd-cli
$ cd dash-mpd-cli
$ cargo build --release
$ target/release/dash-mpd-cli --help

The application can also be built statically with the musl-libc target on Linux. First install the MUSL C standard library on your system. Add linux-musl as a target to your Rust toolchain, then rebuild for the relevant target:

$ sudo apt install musl-dev
$ rustup target add x86_64-unknown-linux-musl
$ cargo build --release --target x86_64-unknown-linux-musl

Static musl-libc builds don’t work with OpenSSL, which is why we disable default features on the dash-mpd crate and build it with rustls support (a Rust TLS stack). You may encounter some situations where rustls fails to connect (handshake errors, for example) but other applications on your system can connect. These differences in behaviour are typically due to different configurations for the set of root certificates. If you prefer to use your machine’s native TLS stack, replace both instances of rustls-tls by native-tls in Cargo.toml and rebuild.

Why?

The dash-mpd-rs library at the core of this application was developed to allow the author to watch a news programme produced by a public media broadcaster whilst at the gym. The programme is published as a DASH stream on the broadcaster’s “replay” service, but network service at the gym is sometimes poor. First world problems!

Warning

The author is not the morality police nor a lawyer, but please note that redistributing media content that you have not produced may, depending on the publication licence, be a breach of intellectual property laws. Also, circumventing DRM may be prohibited in some countries.

License

This project is licensed under the MIT license. For more information, see the LICENSE-MIT file.

dash-mpd-cli's People

Contributors

dependabot[bot] avatar emarsden avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

dash-mpd-cli's Issues

Ability to handle http errors: retrying, logging response

Hello!

Thank you for your work. I'm downloading video course for my non-programmer-friend :) And your app is helping me a lot.

But I'm facing a smal problem with HTTP request error with some audio or video fragments. I'm not entirely sure what causes them.
And I'm afraid fragments are missed because of them. So, the video and audio are out of sync.

I have encreased max-error-count a lot, so video can loaded, but it's not best workaround.

So my questions are:

  1. Are video-audio are desynced after HTTP errors?
  2. Is it possible to retry an HTTP request in case of an error?
  3. How can I see details of errored response?

My logs:

>dash-mpd-cli-windows.exe -v -v -v -o s01_06.mp4 --quality intermediate --muxer-preference mp4:vlc --max-error-count 1000 https://.../master.mpd
[0s] [>-------------------------------------------------] Fetching DASH manifest      
23:30:12  INFO Fetching the DASH manifest
23:30:13  INFO DASH manifest has 1 period
23:30:13  INFO Streams in period #1, duration 3612.067s:
23:30:13  INFO   audio mp4a.40.2         |   127 Kbps |    lang=? label=Unknown
23:30:13  INFO   video avc1.4D401F       |  2194 Kbps |  1280x720
23:30:13  INFO   video avc1.640028       |  3113 Kbps | 1920x1080
23:30:13  INFO   video avc1.4D401E       |   803 Kbps |   640x360
23:30:13  INFO   video avc1.4D401F       |  1227 Kbps |   852x480
23:30:13  INFO Preparing download for period #1
23:30:13  INFO   Using Representation>SegmentList addressing mode for audio representation
23:30:13  INFO   Using Representation>SegmentList addressing mode for video representation
23:30:13  INFO   Audio stream selected: bw=127 Kbps lang=? codec=mp4a.40.2
23:30:13  INFO   Video stream selected: bw=2194 Kbps resolution=1280x720 codec=avc1.4D401F
23:30:14  INFO Period #1: fetching 905 audio, 905 video and 0 subtitle segments

...

23:42:13 ERROR error sending request for url (https://...) fetching video segment https://...

...

23:43:30  INFO   Wrote 287.3MB to DASH video file (0.6 MB/s)
[13m] [#################################################>] Muxing audio and video    
23:43:30  INFO   Muxing audio and video streams
23:43:30  INFO   Muxer preference for mp4 is ["vlc"]
23:43:30  INFO   Trying muxer vlc
23:43:35  INFO   Muxing with vlc subprocess succeeded
23:43:35  INFO   Wrote 55.1MB to media file
[13m] [##################################################] Done

Throws parse error for DASH with SCTE35

Could this promising looking tool support downloading manifests that define SCTE35?

When trying to download DASH with manifests such as: https://docs.aws.amazon.com/mediatailor/latest/ug/dash-ad-markers.html

I.e. with:

<scte35:Signal>
    <scte35:Binary>/DAhAAAAAAAAAP/wEAUAAAHAf+9/fgAg9YDAAAAAAAA25aoh</Binary>
</scte35:Signal>

Then I get:

Download error: parse error parsing DASH XML: Parsing(
    "Unexpected `Event::Start(\"scte35:Signal\")`",
)

There wouldn't be any handling needed, just ignoring those SCTE35 events would be fine, since they are not needed to download the audio/video sources.

Just downloading without merging

Hi, first of all great tool - works like a charm ;-).

Is it possible to download all Segments of a DASH-Stream including manifest tranparently without merging them?

Subtitle files remain on the Temp folder

Hey Eric,
Just realized that on the "\AppData\Local\Temp" folder, the original subtitle files downloaded by the tool don't get deleted after they are converted to .srt. The audio and video files are deleted normally after getting merged, but the subtitles remain there.

image

Thanks!

native decryption

running a command like this:

dash-mpd-cli --key 21b82dc2ebb24d5aa9f8631f04726650:602a9289bfb9b1995b75ac63f123fc86 `
http://example.com/v1/dash/196861183/manifest.mpd

I get this result:

Download failed: I/O error spawning mp4decrypt

I think it would be helpful if the tool here could just do the decryption itself. have you searched for any decryption crates?

Selecting the video quality

Hello!

First of all, thank you. Your program helped me a lot!

So I have some problems to selecting the best video quality in some cases.

The manifest is like this:

Streams in period #1, duration 8940.932s:
audio mp4a.40.2         |    93 Kbps |  lang=por
audio mp4a.40.2         |    93 Kbps |  lang=org
video avc1.640029       |   512 Kbps |   480x270
video avc1.640029       |  1126 Kbps |   768x432
video avc1.640029       |  1843 Kbps |  1024x576
video avc1.640029       |  4091 Kbps |  1280x720
video avc1.640029       |  6348 Kbps |  1280x720
video avc1.640029       |   512 Kbps |   480x270 role=alternate
video avc1.640029       |  1126 Kbps |   768x432 role=alternate
video avc1.640029       |  1843 Kbps |  1024x576 role=alternate
video avc1.640029       |  4091 Kbps |  1280x720 role=alternate
video avc1.640029       |  6348 Kbps |  1280x720 role=alternate

When i use just --quality best the program download one of two 1280x720@6348 Kbps (@ 59,94 fps), but i dont know what, if the main option or the alternate

When i add --prefer-video-width 1280 the program download one of two 1280x720@4091 Kbps (@ 29,97 fps) , but again i dont know what, if the main option or the alternate

In this case, there are two options of each quality because the service provide main streams as expected and the other option is something like a sequence of screenshots and isnt the normal videostream (i really dont know why)

I got the information that yt-dlp provide to try explain this case

ID                EXT RESOLUTION FPS │   TBR PROTO │ VCODEC        VBR ACODEC     ABR ASR MORE INFO
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
dyHiAZ8.          m4a audio only     │   96k dash  │ audio only        mp4a.40.2  96k 24k [por] DRM, DASH audio, m4a_dash
dyHjAZ8.          m4a audio only     │   96k dash  │ audio only        mp4a.40.2  96k 24k [org] DRM, DASH audio, m4a_dash
dzEAAAif          mp4 480x270        │  524k dash  │ avc1.640029  524k video only         DRM, DASH video, mp4_dash
trickmodedzEAAAif mp4 480x270      1 │  524k dash  │ avc1.640029  524k video only         DRM, DASH video, mp4_dash
dzGZmRGf          mp4 768x432        │ 1153k dash  │ avc1.640029 1153k video only         DRM, DASH video, mp4_dash
trickmodedzGZmRGf mp4 768x432      1 │ 1153k dash  │ avc1.640029 1153k video only         DRM, DASH video, mp4_dash
dzHMzByf          mp4 1024x576       │ 1887k dash  │ avc1.640029 1887k video only         DRM, DASH video, mp4_dash
trickmodedzHMzByf mp4 1024x576     1 │ 1887k dash  │ avc1.640029 1887k video only         DRM, DASH video, mp4_dash
dzEw7z-f          mp4 1280x720       │ 4190k dash  │ avc1.640029 4190k video only         DRM, DASH video, mp4_dash
dzEzM2Of          mp4 1280x720       │ 6501k dash  │ avc1.640029 6501k video only         DRM, DASH video, mp4_dash
trickmodedzEw7z-f mp4 1280x720     1 │ 4190k dash  │ avc1.640029 4190k video only         DRM, DASH video, mp4_dash
trickmodedzEzM2Of mp4 1280x720     1 │ 6501k dash  │ avc1.640029 6501k video only         DRM, DASH video, mp4_dash

So, is there any way that I can select the exact option I want to download?

PS: adding the raw MPD

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--Created with VSPP Streamer version 9.2.0.0 build  Commit_id: d537ec715e771249b4933ee5f30b36c6710cc258 Commit_time: 1681376738 context FHCIAPIAHHLNKNFG-ICPIKBAAHHLNKNFG-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:cenc="urn:mpeg:cenc:2013"
     xmlns:mspr="urn:microsoft:playready"
     profiles="urn:mpeg:dash:profile:isoff-live:2011"
     type="static"
     mediaPresentationDuration="PT2H29M0.932S"
     maxSegmentDuration="PT6.017S"
     minBufferTime="PT6.017S">
    <Period>
        <AdaptationSet id="1"
                        group="1"
                        bitstreamSwitching="true"
                        segmentAlignment="true"
                        contentType="video"
                        mimeType="video/mp4"
                        maxWidth="1280"
                        maxHeight="720"
                        par="16:9"
                        maxFrameRate="30000/1001"
                        startWithSAP="1">
            <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
                                value="Widevine">
                <cenc:pssh>XXXXX</cenc:pssh>
            </ContentProtection>
            <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"
                                value="MSPR 2.0">
                <mspr:pro>XXXXX</mspr:pro>
            </ContentProtection>
            <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011"
                                value="cenc"/>
            <SegmentTemplate timescale="10000000"
                             media="S!dxIHQxhXtctE8Jy1yzbhSbdnEkdWUC1EQVNILURSTV9CUi1QTngg6gMVAQoLrw__/QualityLevels($Bandwidth$)/Fragments(video=$Time$)"
                             initialization="S!dxIHQxhXtctE8Jy1yzbhSbdnEkdWUC1EQVNILURSTV9CUi1QTngg6gMVAQoLrw__/QualityLevels($Bandwidth$)/Fragments(video=Init)"
                             presentationTimeOffset="17088295804034560">
                <SegmentTimeline>
                    <S t="17088295804034560"
                       d="60060000"
                       r="1487"/>
                    <S d="40040000"/>
                </SegmentTimeline>
            </SegmentTemplate>
            <Representation id="dzEAAAif"
                            bandwidth="524288"
                            codecs="avc1.640029"
                            width="480"
                            height="270"
                            frameRate="30000/1001"
                            sar="1:1"/>
            <Representation id="dzGZmRGf"
                            bandwidth="1153433"
                            codecs="avc1.640029"
                            width="768"
                            height="432"
                            frameRate="30000/1001"
                            sar="1:1"/>
            <Representation id="dzHMzByf"
                            bandwidth="1887436"
                            codecs="avc1.640029"
                            width="1024"
                            height="576"
                            frameRate="30000/1001"
                            sar="1:1"/>
            <Representation id="dzEw7z-f"
                            bandwidth="4190000"
                            codecs="avc1.640029"
                            width="1280"
                            height="720"
                            frameRate="30000/1001"
                            sar="1:1"/>
            <Representation id="dzEzM2Of"
                            bandwidth="6501171"
                            codecs="avc1.640029"
                            width="1280"
                            height="720"
                            frameRate="30000/1001"
                            sar="1:1"/>
        </AdaptationSet>
        <AdaptationSet id="2"
                        group="32"
                        bitstreamSwitching="true"
                        segmentAlignment="true"
                        contentType="video"
                        mimeType="video/mp4"
                        maxWidth="1280"
                        maxHeight="720"
                        par="16:9"
                        maxFrameRate="30000/1001"
                        startWithSAP="1"
                        codingDependency="false">
            <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
                                value="Widevine">
                <cenc:pssh>XXXXX</cenc:pssh>
            </ContentProtection>
            <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"
                                value="MSPR 2.0">
                <mspr:pro>XXXXX</mspr:pro>
            </ContentProtection>
            <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011"
                                value="cenc"/>
            <EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode"
                               value="1"/>
            <Role schemeIdUri="urn:mpeg:dash:role:2011"
                  value="alternate"/>
            <SegmentTemplate timescale="10000000"
                             media="S!dxIHQxhXtctE8Jy1yzbhSbdnEkdWUC1EQVNILURSTV9CUi1QTngg6gMVAQoLrw__/QualityLevels($Bandwidth$)/Fragments(trickmode=$Time$)"
                             initialization="S!dxIHQxhXtctE8Jy1yzbhSbdnEkdWUC1EQVNILURSTV9CUi1QTngg6gMVAQoLrw__/QualityLevels($Bandwidth$)/Fragments(trickmode=Init)"
                             presentationTimeOffset="17088295804034560">
                <SegmentTimeline>
                    <S t="17088295804034560"
                       d="60060000"
                       r="1487"/>
                    <S d="40040000"/>
                </SegmentTimeline>
            </SegmentTemplate>
            <Representation id="trickmodedzEAAAif"
                            bandwidth="524288"
                            codecs="avc1.640029"
                            width="480"
                            height="270"
                            frameRate="1"
                            sar="1:1"
                            maxPlayoutRate="29.97"/>
            <Representation id="trickmodedzGZmRGf"
                            bandwidth="1153433"
                            codecs="avc1.640029"
                            width="768"
                            height="432"
                            frameRate="1"
                            sar="1:1"
                            maxPlayoutRate="29.97"/>
            <Representation id="trickmodedzHMzByf"
                            bandwidth="1887436"
                            codecs="avc1.640029"
                            width="1024"
                            height="576"
                            frameRate="1"
                            sar="1:1"
                            maxPlayoutRate="29.97"/>
            <Representation id="trickmodedzEw7z-f"
                            bandwidth="4190000"
                            codecs="avc1.640029"
                            width="1280"
                            height="720"
                            frameRate="1"
                            sar="1:1"
                            maxPlayoutRate="29.97"/>
            <Representation id="trickmodedzEzM2Of"
                            bandwidth="6501171"
                            codecs="avc1.640029"
                            width="1280"
                            height="720"
                            frameRate="1"
                            sar="1:1"
                            maxPlayoutRate="29.97"/>
        </AdaptationSet>
        <AdaptationSet id="3"
                        group="2"
                        bitstreamSwitching="true"
                        segmentAlignment="true"
                        contentType="audio"
                        mimeType="audio/mp4"
                        lang="por">
            <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011"
                                       value="2"/>
            <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
                                value="Widevine">
                <cenc:pssh>XXXXX</cenc:pssh>
            </ContentProtection>
            <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"
                                value="MSPR 2.0">
                <mspr:pro>XXXXX</mspr:pro>
            </ContentProtection>
            <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011"
                                value="cenc"/>
        </AdaptationSet>
    </Period>
</MPD>...

PS 2: I downloaded the version 0.2.8 ans worked as I wanted, saving my target version (id=dzEzM2Of).

does not work with this manifest

manifest:

https://cmesk-ott-vod-prep-prot.ssl.cdn.cra.cz/0199/3211/cze-dash-s-axinom-sd1-sd2-sd3-sd4-hd1-hd2-P1BCeo6o.ism/.mpd

i'm on windows 10
this is how i am running it:

dash-mpd-cli.exe https://cmesk-ott-vod-prep-prot.ssl.cdn.cra.cz/0199/3211/cze-dash-s-axinom-sd1-sd2-sd3-sd4-hd1-hd2-P1BCeo6o.ism/.mpd --cookies-from-browser Firefox --quality best --ffmpeg-location "D:\coding\yt-dlp\ffmpeg-master-latest-win64-gpl-shared\bin\ffmpeg.exe" --mp4decrypt-location "D:\coding\yt-dlp\Bento4-SDK-1-6-0-640.x86_64-microsoft-win32\bin\mp4decrypt.exe" --mkvmerge-location "D:\coding\yt-dlp\mkvtoolnix\mkvmerge.exe" -o test.mkv

versions:

ffmpeg version N-111859-g3c397a1d46-20230830
mkvtoolnix version 80.0 Roundabout
mp4decrypt version in file path

it produces an uplayable mkv file, i cannot play it on VLC with error "VLC could not decode the format " " (No description for this codec)" and the mp4 encoding fails after a while and is corrupted:
image

this is the info about the mkv file:
image
i am also attaching the manifest file:

manifest.mpd.txt
let me know if you need additonal info, thanks.

Add commandline argument --ignore-codec

It would be useful to have a commandline argument --ignore-codec that influences the selection of media stream. Some manifests are available with audio encoded in m4a as well as ec-3, and certain playback devices do not support all audio and video codecs. This would allow streams that can't be played to be ignored.

Download failing due to "Subtitle representation is missing SegmentTemplate@duration"

Hi Eric,
Not sure where the issue is on the MPD below. There is 1 period, 2 audio and 5 video streams + subtitles. Even though I'm forcing to download video only, it is still failing due to an error associated with the subtitles. Any idea?
Thanks!

dash-mpd-cli --verbose --video-only --keep-video ".\video\video.mp4" --cookies-from-browser Chrome "https://vod-as-09-14.video.globo.com/j/eyJhbGciOiJSUzUxMiIsImtpZCI6IjEiLCJ0eXAiOiJKV1QifQ.eyJjb3VudHJ5X2NvZGUiOiJCUiIsImRvbWFpbiI6InZvZC1hcy0wOS0xNC52aWRlby5nbG9iby5jb20iLCJleHAiOjE2OTE5MDEwNzUsImlhdCI6MTY5MTg5MzA0MiwiaXNzIjoicGxheWJhY2stYXBpLXByb2QtZ2NwIiwib3duZXIiOiI4MjYzN2Q1ZS00MWI1LTRlZDAtODUwYi1mNzg3YjJmNzAzYjgiLCJwYXRoIjoiL3IyNDBfNzIwL3Y0NS9kYi82Mi9jYS83MDU2NzIzX2NhMDJiNDU3OWI2NjQwODIxMDE2MjI4OTk4YWIzYTdiMDNmNzIxODcvNzA1NjcyMy1XTjByNVEtbWFuaWZlc3QuaXNtLzcwNTY3MjMubXBkIn0.id5Os60-NfkEKZR5Qmxfo3r0SadZiHauXqS5-2M1vgDq5COWK-hAIQ6bTvmm8Gb9GytjCdYJ7hoA-sSABEt7nw61YJB1P_V-acTTeSqrHtCOlrFuzTy4EaGzNCgE1E-bjd0vpeZRbDieCgTBI-dPTT7WY63n3b4MRvby-IlwPuybhHhvUP-DGKvXth0uT3E147qQZUoqqf1hjnnz7j0OvikSbOVvnBhY8xPFkz0s48pfTh6mbRV9-zy8CLkL4HKF_3P3qYV0Zogpp4Qh1_6th4mTyClN1PR4YTEybad3SX4y2KfZTcGdvBH41IDAteFuJKeL08z-BB6TpuPFsl8gag/r240_720/v45/db/62/ca/7056723_ca02b4579b6640821016228998ab3a7b03f72187/7056723-WN0r5Q-manifest.ism/7056723.mpd"
[0s] [>-------------------------------------------------] Fetching DASH manifest Fetching the DASH manifest
DASH manifest has 1 period
Streams in period 1 (#1), duration 2677.556s:
audio mp4a.40.2 | 125 Kbps | lang=en
audio mp4a.40.2 | 125 Kbps | lang=pt
video avc1.64001E | 351 Kbps | 640x360
video avc1.64001E | 614 Kbps | 640x360
video avc1.64001F | 1067 Kbps | 854x480
video avc1.64001F | 1915 Kbps | 1280x720
video avc1.640028 | 2965 Kbps | 1280x720
subs Wvtt/wvtt | pt |
subs Vtt | pt |
Handling period 1 (# 1)
Using SegmentTemplate addressing mode for stpp subtitles
Download failed: invalid media stream: Subtitle representation is missing SegmentTemplate@duration

Downloading off brightcove (wetv) error

C:\Users\DeezNuts>dash-mpd-cli [mpd-url]
[2m] [#################################################>] Muxing audio and video
[2022-08-19T17:28:48Z INFO dash_mpd::ffmpeg] ffmpeg stderr: [aac @ 0000021d5d8a6d00] Number of bands (17) exceeds limit (13).
[h264 @ 0000021d5e0a1080] left block unavailable for requested intra4x4 mode -1
[h264 @ 0000021d5e0a1080] error while decoding MB 0 3, bytestream 3160

[2022-08-19T17:28:48Z WARN dash_mpd::ffmpeg] Muxing with ffmpeg subprocess failed: creating output file
[2022-08-19T17:28:48Z INFO dash_mpd::ffmpeg] Retrying mux with vlc subprocess
[2022-08-19T17:28:48Z WARN dash_mpd::ffmpeg] Muxing with vlc subprocess failed: spawning VLC subprocess
Error: muxing audio and video streams

Caused by:
0: spawning VLC subprocess
1: program not found
'rule' is not recognized as an internal or external command,
operable program or batch file.

any ideas where to go from here?

Transient error - InvalidData, error: AlertReceived(HandshakeFailure)

First of all, thanks for this great piece of SW.

Any idea what's behind this?

dash-mpd-cli.exe --ignore-content-type --quality best --cookies-from-browser Firefox --ffmpeg-location c:\app\downloader\ffmpeg.exe https://cdn01st01-2.o2tv.cz/aa/bbe7e0795a6e0a7a81bee134b904f73d/1685908116923/a3dc40e18fb2a82c9e5a0eb9d47fea778/dna-8-tv-pc-20230604T054900-20230604T102500/mpd

I am able to download mpd file manually (via curl), but I get this error/warn in a cycle

[2023-06-04T20:14:31Z WARN  dash_mpd::fetch] Transient error after 5s: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("cdn01st01-2.o2tv.cz")), port: None, path: "/aa/bbe7e0795a6e0a7a81bee134b904f73d/1685908116923/a3dc40e18fb2a82c9e5a0eb9d47fea778/dna-8-tv-pc-20230604T054900-20230604T102500/mpd", query: None, fragment: None }, source: hyper::Error(Connect, Custom { kind: Other, error: Custom { kind: InvalidData, error: AlertReceived(HandshakeFailure) } }) }

Feature request: Custom variables

Hi,

Can you add an option to provide formats which are not present in the original mpd?

For example:

If for example, from I want to download "$RepresentationID$" called VIDEO1 and from I want to download "$RepresentationID$" called AUDIO1 which are not present in the MPD, would it be possible to override the variables in the mpd?

For example the MPD might offer a lower quality version of video and audio, but the server still has a higher quality version available which is hidden (due to geo locks) but still accessible.

I'm thinking of such an option:

dash-mpd-cli --override "AdaptationSet=1 RepresentationID=VIDEO1" --override "AdaptationSet=2 RepresentationID=AUDIO1" [url]

Option to manually select the video stream?

Hello Eric,
Hope all is well :-)

Not really sure where to post this question/issue/request, so please apologize and feel free to close this issue if it shouldn't be here.

Apparently, the tool does not allow you to manually select which video stream you want to download from multiple options in the MPD. Please see the example below:

DASH manifest has 1 period
Streams in period 1 (# 1), duration 2673.085s:
audio mp4a.40.2 | 125 Kbps | lang=en
audio mp4a.40.2 | 125 Kbps | lang=pt
video avc1.64001E | 351 Kbps | 640x360
video avc1.64001E | 614 Kbps | 640x360
video avc1.64001F | 1068 Kbps | 854x480
video avc1.64001F | 1915 Kbps | 1280x720
video avc1.640028 | 2965 Kbps | 1280x720
subs Wvtt/wvtt | pt |
subs Vtt | pt |

--quality best = downloads the stream "video avc1.640028 | 2965 Kbps | 1280x720"
--quality worst = downloads the stream "video avc1.64001E | 351 Kbps | 640x360"

But what if I wanted to download this stream: "video avc1.64001F | 1915 Kbps | 1280x720"? Is there a way to force which stream to be selected; something similar to the argument "--prefer-language"?

Thanks in advance!

Append token to request URL

I am trying to download .mpd streams which request a token passed as a GET parameter in the HTTP request. As it doesnt seem like this is passing the the GET parameters from the URL I provide the program, any attempts to obtain the .m4s files results in HTTP 401 errors. Is there any way to do this with dash-mpd-cli?

PS C:\Users\Administrator\desktop> .\dash-mpd-cli.exe "https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/manifest.mpd?access_token=1!7vlgwMYEkBcGaHd6UuKkHMNkxD-wE2-pfN7mLltjz6bolOH7WH65BFJdm1Vnsz7ZTvbcy0BcZbzMT79sqSH9jQvvHe_S1UzQGJGbtvq-D_o-veaWmDEv-L0e_sYdffhuL6-Xk8uHy1DEcV9syYLVj02t612SGZtrYp6c052TfTOOk3g4FHLuj-cgkE5GcVa_C7Z5zZ8e8j5Kg8MuwiJbq2czfnqzzd6UQCg7m08YrGgO-JLRatYBUhyrW1-IXc0gyy5YgCR7jldbKD5Pzr9luZ09sX-YDzthtcdymDl8cx4cw400XhraY9JSjcV3cYt_jhrWyvVrCEO-sj9SaEWjhhv1Wb4cFlUkeP46KlBD7rNWNFjPdPioF8UBA2WGRU3pHgkZt2oyKYTOmzqrIK72Fr5wwF11rNV2xadgZDJ4FJ90z7oMXAVYuKUvom0TXk3LEpovz9bRkDdyS04UvrJDqQ7puo8zly5kRlHbEvGl_Smth1Bt9OIFgV9Yh8t0inG9U9joSzHkqIMlTqZcNCX0IJlpQQu622Nxk6ncA9EfzrwI2ZbfUk5IxTNgakMywm_-hWOJWOJjlB0kqjnC0Xh_wch_30R9IgK8t6BTAUAdDNLtIxRdAlyyXbnREaPZRnzoeqUIco3Vkl_vjIJzxTqAEpunWBkmov59mvaiz2FZX6Ckzatc3bXt_oUaNZhLfvbvMnxfO3874jaZXS66ZfiPiQgRhM2e-qHZotM7aXRav_g4UlwjBfvy80r-yw.." -v
[0s] [>-------------------------------------------------] Fetching DASH manifest                    Fetching the DASH manifest
DASH manifest has 1 period
Streams in period #1, duration 603.900s:
  video avc1.640028       |  7812 Kbps | 1920x1080
  video avc1.42c028       |  1953 Kbps |   854x480
Preparing download for period #1
  Video stream selected: bw=1953 Kbps resolution=854x480 codec=avc1.42c028
Period #1: fetching 0 audio, 121 video and 0 subtitle segments
[1s] [>-------------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/init.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/init.m4s
[1s] [#>------------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/1.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/1.m4s
[2s] [#>------------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/2.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/2.m4s
[2s] [##>-----------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/3.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/3.m4s
[2s] [##>-----------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/4.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/4.m4s
[2s] [##>-----------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/5.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/5.m4s
[3s] [###>----------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/6.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/6.m4s
[3s] [###>----------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/7.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/7.m4s
[3s] [####>---------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/8.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/8.m4s
[3s] [####>---------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/9.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/9.m4s
[4s] [#####>--------------------------------------------] Fetching video segments                   HTTP status client error (401 Unauthorized) for url (https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/10.m4s) fetching video segment https://public.boxcloud.com/api/2.0/internal_files/1300373106323/versions/1422096702323/representations/dash/content/video/480/10.m4s
Download failed: network error more than max_error_count network errors

error when downloading

[3m] [#################################################>] Muxing audio and video
[2023-04-01T16:50:37Z INFO  dash_mpd::ffmpeg] Muxer preference for mp4 is ["ffmpeg", "vlc"]
[2023-04-01T16:50:37Z INFO  dash_mpd::ffmpeg] Trying muxer ffmpeg
[2023-04-01T16:50:38Z INFO  dash_mpd::ffmpeg] ffmpeg stderr: Unrecognized option 'hide_banner'.
    Error splitting the argument list: Option not found

[2023-04-01T16:50:38Z WARN  dash_mpd::ffmpeg] Muxing with ffmpeg subprocess failed: muxing error running ffmpeg
[2023-04-01T16:50:38Z INFO  dash_mpd::ffmpeg] Trying muxer vlc
[2023-04-01T16:50:38Z WARN  dash_mpd::ffmpeg] Muxing with vlc subprocess failed: I/O error spawning VLC subprocess
[2023-04-01T16:50:38Z WARN  dash_mpd::ffmpeg] All available muxers failed
Download error: muxing error all available muxers failed```

fail downloading

doesnt support ContentProtection

many MPD now include this element, so it should either be supported, or it should be clearly documented that it is not supported

Add commandline arguments --skip-period-id, --skip-period-duration

It would be useful to have commandline arguments that allow the user to request that certain Periods in a multi-Period manifest are not downloaded. For example, --skip-period-id could allow a Period with a specific @id attribute (which is printed when fetching with "-v" and "--simulate") to be ignored, and --skip-period-duration could skip all periods whose duration is less than the specified argument.

This functionality could be useful for fetching content which has been enriched with server-side ad insertion (SSAI) or dynamic ad insertion (DAI).

won't work on youtube dash manifest

I took a link to the dash from a youtube stream initialPlayer.StreamingData.DashManifestUrl

dash-mpd-cli --quality=worst https://manifest.googlevideo.com/api/manifest/dash/expire/1670387314/ei/EsKPY7W1BIGAsfIPhdW4oAs/ip/154.13.53.175/id/W1oorPTCw4A.1/source/yt_live_broadcast/requiressl/yes/as/fmp4_audio_clear,webm_audio_clear,webm2_audio_clear,fmp4_sd_hd_clear,webm2_sd_hd_clear/vprv/1/pacing/0/keepalive/yes/fexp/24001373,24007246/itag/0/playlist_type/DVR/sparams/expire,ei,ip,id,source,requiressl,as,vprv,itag,playlist_type/sig/AOq0QJ8wRgIhAJZKg8Xq1kHqjRQysrv_StcyZSThQpBfxEN5kf8Mn89rAiEA1r9oTDr0TQVc-_XLj8DyTg9_aM2vJZuKwXCHzd9BeJs=

i got this error:
Download error: parse error parsing DASH XML: parse error premature end of input

link to file: manifest dl

download speed

is an option available to show the current download speed? all I see currently is the elapsed time and a progress bar.

Doesn't work for this URL, have tested on different machines

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.