MCPcopy Index your code
hub / github.com/Eyevinn/dash-mpd

github.com/Eyevinn/dash-mpd @v0.16.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.16.0 ↗ · + Follow
719 symbols 1,766 edges 29 files 345 documented · 48%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Test golangci-lint GoDoc Go Report Card license

DASH-MPD - A complete MPEG-DASH MPD parser/writer

This MPEG-DASH MPD implementation is meant to include all elements from the MPEG DASH specification (ISO/IEC 23009-1 6'th edition) by starting from the MPD XML schema and auto-generating all data structures. It should also handle namespaces and schemaLocation properly.

It has been enhanced with extra structures from the Common Encryption specification ISO/IEC 23001-7 and proprietary structures and name spaces for some DRM systems.

XML Schemas

The XML Schema for MPEG DASH MPD being used is the 6'th edition fetched from the DASHSchema repo 6th-Ed branch at commit a855144.

It was fed to a forked modified version of xgen. The fork modified xgen so that it could deal with DOCTYPE, and also removed the suffix Attr from all attribute names. The fork can be found at tobbee xgen.

The process of generating this start MPD structures is done in the Github repo tobbee/mpdgen. The output provided the starting point for the MPD type of this project.

Adjustments of the MPD structures

Mapping of the full MPD Schema to Go structures provides a good start, but it has some limitations and issues. Therefore, all structures have been scrutinized, and modified where needed. The main modifications made were:

  • Change of top-level MPD type
  • Add xlink name space
  • Change some attributes to remove omitempty or become pointers. An example is availabilityTimeComplete. It is boolean, but it should either have the value false or be absent
  • Add type comments and document enum values for certain types
  • Change names to plural for all subelement slices, e.g. Periods instead of Period
  • Add ContentProtection elements and corresponding name spaces

SCTE-35

DASH events carrying SCTE-35 splice information sections are supported with types defined in mpd/scte35.go, mapped from scte_35_20230713.xsd (ANSI/SCTE 35 2023r2). The <Signal> wrapper element specified by SCTE 214-1 is exposed as EventType.Signal and the alternative direct form (SCTE-35 SpliceInfoSection placed straight under Event, as emitted by AWS MediaTailor and others) is exposed as EventType.SpliceInfoSection. Use the (*EventType).SpliceInfo helper to read either form uniformly.

Two SCTE-35 namespace URIs are seen in the wild for the same schema:

  • http://www.scte.org/schemas/35 — the canonical URI, declared as targetNamespace by every XSD since 2020 (constant mpd.SCTE35Namespace).
  • http://www.scte.org/schemas/35/2016 — a legacy URI still produced by a large fraction of packagers (constant mpd.SCTE35Namespace2016).

Each SCTE-35 type embeds an unnamed XMLName xml.Name field. On unmarshal the namespace URI is captured from the input document; on marshal it is replayed verbatim. An unmarshal/marshal round trip therefore preserves whichever URI the source manifest used — including the legacy 2016 variant. This is a deliberate exception to the "output names are fixed, and may differ from the input names" limitation listed below: SCTE-35 namespaces are passed through.

A fresh value should be built via the New* constructors (mpd.NewSignal, mpd.NewSpliceInfoSection, mpd.NewTimeSignal, …) so that XMLName is set to the canonical URI by default. Bypassing them with a struct literal is legal but the resulting element will fall back to the Go type name when marshaled.

sig := mpd.NewSignal()
sis := mpd.NewSpliceInfoSection()
tier := uint16(4095)
sis.Tier = &tier
sis.TimeSignal = mpd.NewTimeSignal()
ptsTime := uint64(7835775000)
sis.TimeSignal.SpliceTime = mpd.NewSpliceTime()
sis.TimeSignal.SpliceTime.PtsTime = &ptsTime
sig.SpliceInfoSection = sis
event.Signal = sig

A representative set of round-trip fixtures lives in mpd/testdata/scte35/.

XML handling

The handling of XML name spaces in the Go standard library encoding/xml is incomplete, and has a number of quirks and limitations which makes it impossible to generate namespaces and namespace prefixes in the standard way used in many places including XML schemas and DASH MPDs.

There are a number of pull requests to improve the situation, and in particular PR #48641 - encoding/xml: support xmlns prefixes includes an extension to the XML struct tags that make it possible to specify name space prefixes.

Since this functionality has not yet made its way into the standard library, after more than four years, the full patched version of the encoding/xml package is included here in the xml directory. The vendored copy tracks the current head of PR #48641 rebased on Go master, and therefore includes stdlib fixes made since Go 1.17 (notably CVE-2022-30633 and several panic fixes). See xml/README.md for the exact commit. Therefore, the github.com/Eyevinn/dash-mpd/xml package should be used together with the XML structure in the package, rather than the standard library version. The package functions mpd.ReadFromFile(), mpd.ReadFromString(), and mpd.Write() do use that XML library.

Limitations to MPD manipulations

Since the MPD is mapped to Go structures, there are some limitations to what can be processed and how the output looks:

  1. Only elements and attributes specified in the data structures are kept. Unknown elements and attributes are silently discarded.
  2. All XML comments are removed
  3. The output order of XML attributes is given by the order in the structure, which is in turn comes from the XML schema. The order is therefore often different from the input document.
  4. Mapping to float numbers may not preserve the exact value of the input.
  5. Addition of extra name spaces, such as specific DRM systems must be done explicitly.
  6. In the output, the name-spaces are added to the level where they are used and not at the top MPD level. The output names are also fixed, and may differ from the input names.
  7. Durations are mapped to nanoseconds and back. This may change the duration slightly. All trailing zeros are also removed, as are the minutes and seconds counts if they are zero and a bigger unit is present.

Tests

The MPD marshaling/unmarshaling is tested by by using many MPDs in the testdata/schema-mpds, testdata/go-dash-fixtures, and testdata/livesim directories. See the README.md files in these directories for their origins and the small tweaks needed to make durations and some other values consistent after a unmarshaling/marshaling process.

Performance

Including all elements, including rarely used ones, has some performance penalty. One such contribution comes from matching attributes which is done in a linear fashion. Some benchmark tests are included in the mpd/mpd_test.go file.

Commits, ChangeLog

This project aims to follow Semantic Versioning and Conventional Commits. There is a manual ChangeLog that should be updated with each commit.

With making a local git commit, this project uses pre-commit hooks. You therefore need Python3 installed and run make prepare to create a Python virtual envinvorment at .venv and then run source .venv/bin/activate in your shell in order to activate that virtual environment to get the pre-commit` mechanism to work.

License

MIT, see LICENSE.

Support

Join our community on Slack where you can post any questions regarding any of our open source projects. Eyevinn's consulting business can also offer you:

  • Further development of this component
  • Customization and integration of this component into your platform
  • Support and maintenance agreement

Contact sales@eyevinn.se if you are interested.

About Eyevinn Technology

Eyevinn Technology is an independent consultant firm specialized in video and streaming. Independent in a way that we are not commercially tied to any platform or technology vendor. As our way to innovate and push the industry forward we develop proof-of-concepts and tools. The things we learn and the code we write we share with the industry in blogs and by open sourcing the code we have written.

Want to know more about Eyevinn and how it is to work here. Contact us at work@eyevinn.se!

Extension points exported contracts — how you extend this code

TokenReader (Interface)
A TokenReader is anything that can decode a stream of XML tokens, including a [Decoder]. When Token encounters an error [5 …
xml/xml.go
UnmarshalerAttr (Interface)
UnmarshalerAttr is the interface implemented by objects that can unmarshal an XML attribute description of themselves. [3 …
xml/read.go
Marshaler (Interface)
Marshaler is the interface implemented by objects that can marshal themselves into valid XML elements. MarshalXML encod [1 …
xml/marshal.go
Unmarshaler (Interface)
Unmarshaler is the interface implemented by objects that can unmarshal an XML element description of themselves. Unmars [2 …
xml/read.go
MarshalerAttr (Interface)
MarshalerAttr is the interface implemented by objects that can marshal themselves into valid XML attributes. MarshalXML [1 …
xml/marshal.go

Core symbols most depended-on inside this repo

Unmarshal
called by 45
xml/read.go
Marshal
called by 41
xml/marshal.go
WriteByte
called by 36
xml/marshal.go
NewDecoder
called by 33
xml/xml.go
WriteString
called by 32
xml/marshal.go
Token
called by 31
xml/xml.go
String
called by 31
mpd/period.go
Error
called by 30
xml/xml.go

Shape

Struct 293
Function 235
Method 151
TypeAlias 35
Interface 5

Languages

Go100%

Modules by API surface

mpd/mpd.go137 symbols
xml/marshal_test.go127 symbols
xml/xml_test.go102 symbols
xml/xml.go61 symbols
xml/read_test.go61 symbols
xml/marshal.go47 symbols
mpd/scte35.go44 symbols
xml/read.go17 symbols
mpd/io.go14 symbols
xml/typeinfo.go13 symbols
mpd/mpd_test.go11 symbols
mpd/duration.go11 symbols

For agents

$ claude mcp add dash-mpd \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page