Task 418: .MPD File Format
Task 418: .MPD File Format
.MPD File Format Specifications
The .MPD file format refers to the Media Presentation Description (MPD) used in MPEG-DASH (Dynamic Adaptive Streaming over HTTP), an adaptive bitrate streaming standard. It is an XML-based manifest file that describes media content segments, enabling clients to request and stream video/audio over HTTP. The format is defined in the ISO/IEC 23009-1 standard, which outlines its XML schema, elements, and attributes for structuring media presentations (static for on-demand or dynamic for live streaming).
- List of All Properties Intrinsic to the .MPD File Format
The properties are the XML elements and attributes defined in the MPD schema. These are intrinsic to the format as they define the structure, timing, media components, and segment information. Below is a hierarchical list based on the standard, including elements, attributes, cardinality (e.g., M = Mandatory, O = Optional, OD = Optional with Default, CM = Conditionally Mandatory), types, and descriptions.
MPD (Root Element)
- Description: Root of the Media Presentation Description.
- Cardinality: 1..1
- Attributes:
@id
(O, xs:string): Unique identifier.@profiles
(M, xs:string): List of profiles (e.g., "urn:mpeg:dash:profile:isoff-on-demand:2011").@type
(OD="static", PresentationType): "static" or "dynamic".@availabilityStartTime
(CM, xs:dateTime): Start time for dynamic MPDs.@availabilityEndTime
(O, xs:dateTime): End time for availability.@mediaPresentationDuration
(CM, xs:duration): Total duration for static MPDs.@minimumUpdatePeriod
(O, xs:duration): Update interval for dynamic MPDs.@minBufferTime
(M, xs:duration): Minimum buffer time.@timeShiftBufferDepth
(O, xs:duration): Time-shifting buffer depth.@suggestedPresentationDelay
(O, xs:duration): Suggested delay.@maxSegmentDuration
(O, xs:duration): Max segment duration.@maxSubsegmentDuration
(O, xs:duration): Max subsegment duration.- Child Elements:
ProgramInformation
(0..N, ProgramInformationType): Program details.BaseURL
(0..N, BaseURLType): Base URLs for resolution.Location
(0..N, xs:anyURI): MPD locations.Period
(1..N, PeriodType): Media periods.Metrics
(0..N, MetricsType): Metrics reporting.xs:any
(0..N): Extensions from other namespaces.
ProgramInformation
- Cardinality: 0..N (under MPD)
- Attributes:
@lang
(O, xs:language): Language code.@moreInformationURL
(O, xs:anyURI): URL for more info.- Child Elements:
Title
(0..1, xs:string): Presentation title.Source
(0..1, xs:string): Content source.Copyright
(0..1, xs:string): Copyright info.xs:any
(0..N): Extensions.
Period
- Cardinality: 1..N (under MPD)
- Attributes:
@xlink:href
(O, xlink:href): External reference.@xlink:actuate
(OD="onRequest", xlink:actuate): Actuation mode.@id
(O, xs:string): Period ID.@start
(O, xs:duration): Start time.@duration
(O, xs:duration): Duration.@bitstreamSwitching
(OD=false, xs:boolean): Enable bitstream switching.- Child Elements:
BaseURL
(0..N, BaseURLType): Base URLs.SegmentBase
(0..1, SegmentBaseType): Segment base info.SegmentList
(0..1, SegmentListType): Segment list.SegmentTemplate
(0..1, SegmentTemplateType): Segment template.AdaptationSet
(0..N, AdaptationSetType): Adaptation sets (at least one typically required).Subset
(0..N, SubsetType): Subsets of adaptation sets.xs:any
(0..N): Extensions.
AdaptationSet (Inherits from RepresentationBaseType)
- Cardinality: 0..N (under Period)
- Attributes:
@xlink:href
(O, xlink:href): External reference.@xlink:actuate
(OD="onRequest", xlink:actuate): Actuation mode.@id
(O, xs:unsignedInt): ID.@group
(O, xs:unsignedInt): Group ID.@lang
(O, xs:language): Language.@contentType
(O, xs:string): Content type.@par
(O, RatioType): Picture aspect ratio.@minBandwidth
/@maxBandwidth
(O, xs:unsignedInt): Bandwidth range.@minWidth
/@maxWidth
(O, xs:unsignedInt): Width range.@minHeight
/@maxHeight
(O, xs:unsignedInt): Height range.@minFrameRate
/@maxFrameRate
(O, FrameRateType): Frame rate range.@segmentAlignment
(OD=false, ConditionalUintType): Segment alignment.@bitstreamSwitching
(O, xs:boolean): Bitstream switching.@subsegmentAlignment
(O, ConditionalUintType): Subsegment alignment.@subsegmentStartsWithSAP
(O, xs:unsignedByte): Starts with Stream Access Point.- Child Elements:
Accessibility
(0..N, DescriptorType): Accessibility info.Role
(0..N, DescriptorType): Role descriptors.Rating
(0..N, DescriptorType): Ratings.Viewpoint
(0..N, DescriptorType): Viewpoints.ContentComponent
(0..N, ContentComponentType): Media components.BaseURL
(0..N, BaseURLType): Base URLs.SegmentBase
(0..1, SegmentBaseType): Segment base.SegmentList
(0..1, SegmentListType): Segment list.SegmentTemplate
(0..1, SegmentTemplateType): Segment template.Representation
(0..N, RepresentationType): Representations (at least one typically required).xs:any
(0..N): Extensions.
Representation (Inherits from RepresentationBaseType)
- Cardinality: 0..N (under AdaptationSet)
- Attributes:
@id
(M, xs:string): Unique ID within Period.@bandwidth
(M, xs:unsignedInt): Bandwidth requirement.@qualityRanking
(O, xs:unsignedInt): Quality ranking.@dependencyId
(O, xs:string): Dependency on other Representations.@mediaStreamStructureId
(O, xs:string): Media stream structure ID.- Child Elements:
BaseURL
(0..N, BaseURLType): Base URLs.SegmentBase
(0..1, SegmentBaseType): Segment base.SegmentList
(0..1, SegmentListType): Segment list.SegmentTemplate
(0..1, SegmentTemplateType): Segment template.xs:any
(0..N): Extensions.
RepresentationBaseType (Base for AdaptationSet and Representation)
- Attributes:
@profiles
(O, xs:string): Profiles.@width
/@height
(O, xs:unsignedInt): Resolution.@sar
(O, RatioType): Sample aspect ratio.@frameRate
(O, FrameRateType): Frame rate.@audioSamplingRate
(O, xs:string): Audio sampling rate.@mimeType
(O, xs:string): MIME type.@segmentProfiles
(O, xs:string): Segment profiles.@codecs
(O, xs:string): Codecs.@maximumSAPPeriod
(O, xs:double): Max Stream Access Point period.@startWithSAP
(O, xs:unsignedByte): Starts with SAP.@maxPlayoutRate
(O, xs:double): Max playout rate.@codingDependency
(O, xs:boolean): Coding dependency.@scanType
(O, VideoScanType): Video scan type.- Child Elements:
FramePacking
(0..N, DescriptorType): Frame packing.AudioChannelConfiguration
(0..N, DescriptorType): Audio config.ContentProtection
(0..N, DescriptorType): DRM protection.EssentialProperty
(0..N, DescriptorType): Essential properties.SupplementalProperty
(0..N, DescriptorType): Supplemental properties.InbandEventStream
(0..N, DescriptorType): In-band events.xs:any
(0..N): Extensions.
SegmentBaseType
- Cardinality: 0..1 (under Period/AdaptationSet/Representation)
- Attributes:
@timescale
(O, xs:unsignedInt): Timescale for durations.@presentationTimeOffset
(O, xs:unsignedLong): Presentation time offset.@indexRange
(O, xs:string): Byte range for index.@indexRangeExact
(O, xs:boolean): Exact index range.- Child Elements:
Initialization
(0..1, URLType): Initialization segment.RepresentationIndex
(0..1, URLType): Representation index.
SegmentListType (Extends MultipleSegmentBaseType)
- Cardinality: 0..1 (under Period/AdaptationSet/Representation)
- Attributes: Inherits from MultipleSegmentBaseType.
- Child Elements:
SegmentURL
(0..N, SegmentURLType): Segment URLs.
SegmentTemplateType (Extends MultipleSegmentBaseType)
- Cardinality: 0..1 (under Period/AdaptationSet/Representation)
- Attributes:
@media
(O, xs:string): Media template.@index
(O, xs:string): Index template.@initialization
(O, xs:string): Initialization template.@bitstreamSwitching
(O, xs:string): Bitstream switching template.- Child Elements: None specific beyond inheritance.
MultipleSegmentBaseType (Base for SegmentList and SegmentTemplate)
- Attributes:
@duration
(O, xs:unsignedInt): Segment duration.@startNumber
(O, xs:unsignedInt): Start number.- Child Elements:
SegmentTimeline
(0..1, SegmentTimelineType): Timeline.BitstreamSwitching
(0..1, URLType): Bitstream switching segment.
Other Elements (Brief)
Subset
(0..N under Period): Contains@contains
(M, ListOfUnsignedIntType): AdaptationSet IDs.ContentComponent
(0..N under AdaptationSet): Attributes like@id
,@lang
,@contentType
.DescriptorType
(Base for descriptors like Accessibility, Role): Attributes@schemeIdUri
(M, xs:anyURI),@value
(O, xs:string).Metrics
(0..N under MPD): Attributes@metrics
(M, xs:string); ChildReporting
(1..N, DescriptorType),Range
(0..N, RangeType).BaseURLType
: Attributes@serviceLocation
(O, xs:string),@byteRange
(O, xs:string).- Types:
RatioType
(xs:string, e.g., "width:height"),FrameRateType
(xs:string, e.g., "num/denom"), etc.
This list covers the core intrinsic properties; extensions allow additional namespaces.
- Two Direct Download Links for .MPD Files
- https://dash.akamaized.net/envivio/dashprclear/Manifest.mpd (Sample from Envivio DASH test stream).
- https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd (Big Buck Bunny 30fps sample).
- Ghost Blog Embedded HTML JavaScript for Drag and Drop .MPD File Dump
Here is a self-contained HTML page with embedded JavaScript. Drag and drop a .MPD file onto the drop zone, and it will parse the XML and dump all properties (elements and attributes) to the screen in a hierarchical JSON-like format.
- Python Class for .MPD File Handling
import xml.etree.ElementTree as ET
import json
class MPDHandler:
def __init__(self, filepath):
self.filepath = filepath
self.tree = None
self.root = None
def open_and_decode(self):
self.tree = ET.parse(self.filepath)
self.root = self.tree.getroot()
def read_properties(self):
if not self.root:
raise ValueError("File not opened or decoded.")
properties = self._extract_properties(self.root)
return properties
def _extract_properties(self, node):
props = {'tag': node.tag, 'attributes': dict(node.attrib), 'children': []}
for child in node:
props['children'].append(self._extract_properties(child))
return props
def print_properties(self):
properties = self.read_properties()
print(json.dumps(properties, indent=2))
def write(self, new_filepath=None):
if not self.tree:
raise ValueError("No data to write.")
filepath = new_filepath or self.filepath
self.tree.write(filepath, encoding='utf-8', xml_declaration=True)
# Example modification: add or update an attribute
def update_property(self, tag_path, attr_name, attr_value):
# tag_path example: 'MPD/Period' to find first Period under MPD
if not self.root:
raise ValueError("File not opened.")
parts = tag_path.split('/')
current = self.root
for part in parts[1:]:
current = current.find(part)
if current is None:
raise ValueError("Path not found.")
current.set(attr_name, attr_value)
# Usage example:
# handler = MPDHandler('example.mpd')
# handler.open_and_decode()
# handler.print_properties()
# handler.update_property('MPD', 'type', 'dynamic')
# handler.write('modified.mpd')
- Java Class for .MPD File Handling
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.json.JSONObject;
import java.io.File;
public class MPDHandler {
private String filepath;
private Document doc;
public MPDHandler(String filepath) {
this.filepath = filepath;
}
public void openAndDecode() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(new File(filepath));
}
private JSONObject extractProperties(Node node) {
JSONObject props = new JSONObject();
props.put("tag", node.getNodeName());
JSONObject attrs = new JSONObject();
if (node.getAttributes() != null) {
for (int i = 0; i < node.getAttributes().getLength(); i++) {
Node attr = node.getAttributes().item(i);
attrs.put(attr.getNodeName(), attr.getNodeValue());
}
}
props.put("attributes", attrs);
org.json.JSONArray children = new org.json.JSONArray();
NodeList childNodes = node.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node child = childNodes.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
children.put(extractProperties(child));
}
}
props.put("children", children);
return props;
}
public JSONObject readProperties() {
if (doc == null) throw new IllegalStateException("File not opened.");
return extractProperties(doc.getDocumentElement());
}
public void printProperties() {
System.out.println(readProperties().toString(2));
}
public void write(String newFilepath) throws Exception {
if (doc == null) throw new IllegalStateException("No data to write.");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(newFilepath != null ? newFilepath : filepath));
transformer.transform(source, result);
}
// Example modification: update attribute by tag path (simple first-match)
public void updateProperty(String tagPath, String attrName, String attrValue) {
if (doc == null) throw new IllegalStateException("File not opened.");
String[] parts = tagPath.split("/");
Node current = doc.getDocumentElement();
for (int i = 1; i < parts.length; i++) {
boolean found = false;
NodeList children = current.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
if (children.item(j).getNodeName().equals(parts[i])) {
current = children.item(j);
found = true;
break;
}
}
if (!found) throw new IllegalArgumentException("Path not found.");
}
((Element) current).setAttribute(attrName, attrValue);
}
// Usage example in main:
// public static void main(String[] args) throws Exception {
// MPDHandler handler = new MPDHandler("example.mpd");
// handler.openAndDecode();
// handler.printProperties();
// handler.updateProperty("MPD/Period", "id", "newId");
// handler.write("modified.mpd");
// }
}
(Note: This uses org.json for JSON output; include the library or use another for production.)
- JavaScript Class for .MPD File Handling
This is a Node.js class (requires fs
and xml2js
for parsing; install xml2js via npm if needed). It reads, decodes, prints properties, and writes.
const fs = require('fs');
const xml2js = require('xml2js');
class MPDHandler {
constructor(filepath) {
this.filepath = filepath;
this.parsedData = null;
}
openAndDecode(callback) {
fs.readFile(this.filepath, 'utf8', (err, data) => {
if (err) return callback(err);
const parser = new xml2js.Parser();
parser.parseString(data, (err, result) => {
if (err) return callback(err);
this.parsedData = result;
callback(null);
});
});
}
readProperties() {
if (!this.parsedData) throw new Error('File not opened or decoded.');
return this.parsedData; // Returns object with all properties
}
printProperties() {
console.log(JSON.stringify(this.readProperties(), null, 2));
}
write(newFilepath, callback) {
if (!this.parsedData) throw new Error('No data to write.');
const builder = new xml2js.Builder();
const xml = builder.buildObject(this.parsedData);
const path = newFilepath || this.filepath;
fs.writeFile(path, xml, callback);
}
// Example modification: update attribute (e.g., MPD.type = 'dynamic')
updateProperty(pathArr, attrName, attrValue) {
if (!this.parsedData) throw new Error('File not opened.');
let current = this.parsedData;
for (let key of pathArr) {
if (!current[key]) throw new Error('Path not found.');
current = current[key];
}
if (!current.$) current.$ = {};
current.$[attrName] = attrValue;
}
}
// Usage example:
// const handler = new MPDHandler('example.mpd');
// handler.openAndDecode((err) => {
// if (err) console.error(err);
// handler.printProperties();
// handler.updateProperty(['MPD'], 'type', 'dynamic');
// handler.write('modified.mpd', (err) => { if (err) console.error(err); });
// });
- C Class (Using C++ for Class Support)
Since standard C lacks classes and built-in XML parsing, this uses C++ with TinyXML2 (assume included; download from https://github.com/leethomason/tinyxml2 if needed). It opens, decodes, prints properties, and writes.
#include <iostream>
#include <string>
#include <tinyxml2.h> // Assume TinyXML2 library
#include <fstream>
class MPDHandler {
private:
std::string filepath;
tinyxml2::XMLDocument doc;
void extractProperties(const tinyxml2::XMLElement* node, std::string indent = "") {
if (!node) return;
std::cout << indent << "{" << std::endl;
std::cout << indent << " \"tag\": \"" << node->Name() << "\"," << std::endl;
std::cout << indent << " \"attributes\": {" << std::endl;
const tinyxml2::XMLAttribute* attr = node->FirstAttribute();
while (attr) {
std::cout << indent << " \"" << attr->Name() << "\": \"" << attr->Value() << "\"," << std::endl;
attr = attr->Next();
}
std::cout << indent << " }," << std::endl;
std::cout << indent << " \"children\": [" << std::endl;
const tinyxml2::XMLElement* child = node->FirstChildElement();
while (child) {
extractProperties(child, indent + " ");
child = child->NextSiblingElement();
}
std::cout << indent << " ]" << std::endl;
std::cout << indent << "}" << std::endl;
}
public:
MPDHandler(const std::string& fp) : filepath(fp) {}
void openAndDecode() {
doc.LoadFile(filepath.c_str());
if (doc.Error()) {
throw std::runtime_error("Error loading XML.");
}
}
void printProperties() {
const tinyxml2::XMLElement* root = doc.RootElement();
if (!root) throw std::runtime_error("No root element.");
extractProperties(root);
}
void write(const std::string& newFilepath = "") {
const std::string path = newFilepath.empty() ? filepath : newFilepath;
doc.SaveFile(path.c_str());
}
// Example modification: update attribute by tag path (simple first-match)
void updateProperty(const std::string& tagPath, const std::string& attrName, const std::string& attrValue) {
tinyxml2::XMLElement* current = doc.RootElement();
size_t pos = 0, next;
std::string token;
std::string path = tagPath;
if (path.find("MPD/") == 0) path = path.substr(4); // Skip root if starts with MPD/
while ((next = path.find('/', pos)) != std::string::npos) {
token = path.substr(pos, next - pos);
current = current->FirstChildElement(token.c_str());
if (!current) throw std::runtime_error("Path not found.");
pos = next + 1;
}
token = path.substr(pos);
if (!token.empty()) {
current = current->FirstChildElement(token.c_str());
if (!current) throw std::runtime_error("Path not found.");
}
current->SetAttribute(attrName.c_str(), attrValue.c_str());
}
};
// Usage example:
// int main() {
// try {
// MPDHandler handler("example.mpd");
// handler.openAndDecode();
// handler.printProperties();
// handler.updateProperty("Period", "id", "newId");
// handler.write("modified.mpd");
// } catch (const std::exception& e) {
// std::cerr << e.what() << std::endl;
// }
// return 0;
// }