representation;
+ @XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
+ protected String href;
+ @XmlAttribute(name = "actuate", namespace = "http://www.w3.org/1999/xlink")
+ protected ActuateType actuate;
+ @XmlAttribute(name = "id")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long id;
+ @XmlAttribute(name = "group")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long group;
+ @XmlAttribute(name = "lang")
+ @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+ @XmlSchemaType(name = "language")
+ protected String lang;
+ @XmlAttribute(name = "contentType")
+ protected String contentType;
+ @XmlAttribute(name = "par")
+ protected String par;
+ @XmlAttribute(name = "minBandwidth")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long minBandwidth;
+ @XmlAttribute(name = "maxBandwidth")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long maxBandwidth;
+ @XmlAttribute(name = "minWidth")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long minWidth;
+ @XmlAttribute(name = "maxWidth")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long maxWidth;
+ @XmlAttribute(name = "minHeight")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long minHeight;
+ @XmlAttribute(name = "maxHeight")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long maxHeight;
+ @XmlAttribute(name = "minFrameRate")
+ protected String minFrameRate;
+ @XmlAttribute(name = "maxFrameRate")
+ protected String maxFrameRate;
+ @XmlAttribute(name = "segmentAlignment")
+ protected String segmentAlignment;
+ @XmlAttribute(name = "subsegmentAlignment")
+ protected String subsegmentAlignment;
+ @XmlAttribute(name = "subsegmentStartsWithSAP")
+ protected Long subsegmentStartsWithSAP;
+ @XmlAttribute(name = "bitstreamSwitching")
+ protected Boolean bitstreamSwitching;
+
+ /**
+ * Gets the value of the accessibility property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the accessibility property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAccessibility().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getAccessibility() {
+ if (accessibility == null) {
+ accessibility = new ArrayList();
+ }
+ return this.accessibility;
+ }
+
+ /**
+ * Gets the value of the role property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the role property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getRole().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getRole() {
+ if (role == null) {
+ role = new ArrayList();
+ }
+ return this.role;
+ }
+
+ /**
+ * Gets the value of the rating property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the rating property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getRating().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getRating() {
+ if (rating == null) {
+ rating = new ArrayList();
+ }
+ return this.rating;
+ }
+
+ /**
+ * Gets the value of the viewpoint property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the viewpoint property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getViewpoint().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getViewpoint() {
+ if (viewpoint == null) {
+ viewpoint = new ArrayList();
+ }
+ return this.viewpoint;
+ }
+
+ /**
+ * Gets the value of the contentComponent property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the contentComponent property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getContentComponent().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link ContentComponentType }
+ *
+ *
+ */
+ public List getContentComponent() {
+ if (contentComponent == null) {
+ contentComponent = new ArrayList();
+ }
+ return this.contentComponent;
+ }
+
+ /**
+ * Gets the value of the baseURL property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the baseURL property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getBaseURL().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link BaseURLType }
+ *
+ *
+ */
+ public List getBaseURL() {
+ if (baseURL == null) {
+ baseURL = new ArrayList();
+ }
+ return this.baseURL;
+ }
+
+ /**
+ * Gets the value of the segmentBase property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentBaseType }
+ *
+ */
+ public SegmentBaseType getSegmentBase() {
+ return segmentBase;
+ }
+
+ /**
+ * Sets the value of the segmentBase property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentBaseType }
+ *
+ */
+ public void setSegmentBase(SegmentBaseType value) {
+ this.segmentBase = value;
+ }
+
+ /**
+ * Gets the value of the segmentList property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentListType }
+ *
+ */
+ public SegmentListType getSegmentList() {
+ return segmentList;
+ }
+
+ /**
+ * Sets the value of the segmentList property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentListType }
+ *
+ */
+ public void setSegmentList(SegmentListType value) {
+ this.segmentList = value;
+ }
+
+ /**
+ * Gets the value of the segmentTemplate property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentTemplateType }
+ *
+ */
+ public SegmentTemplateType getSegmentTemplate() {
+ return segmentTemplate;
+ }
+
+ /**
+ * Sets the value of the segmentTemplate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentTemplateType }
+ *
+ */
+ public void setSegmentTemplate(SegmentTemplateType value) {
+ this.segmentTemplate = value;
+ }
+
+ /**
+ * Gets the value of the representation property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the representation property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getRepresentation().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link RepresentationType }
+ *
+ *
+ */
+ public List getRepresentation() {
+ if (representation == null) {
+ representation = new ArrayList();
+ }
+ return this.representation;
+ }
+
+ /**
+ * Gets the value of the href property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getHref() {
+ return href;
+ }
+
+ /**
+ * Sets the value of the href property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setHref(String value) {
+ this.href = value;
+ }
+
+ /**
+ * Gets the value of the actuate property.
+ *
+ * @return
+ * possible object is
+ * {@link ActuateType }
+ *
+ */
+ public ActuateType getActuate() {
+ if (actuate == null) {
+ return ActuateType.ON_REQUEST;
+ } else {
+ return actuate;
+ }
+ }
+
+ /**
+ * Sets the value of the actuate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link ActuateType }
+ *
+ */
+ public void setActuate(ActuateType value) {
+ this.actuate = value;
+ }
+
+ /**
+ * Gets the value of the id property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * Sets the value of the id property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setId(Long value) {
+ this.id = value;
+ }
+
+ /**
+ * Gets the value of the group property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getGroup() {
+ return group;
+ }
+
+ /**
+ * Sets the value of the group property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setGroup(Long value) {
+ this.group = value;
+ }
+
+ /**
+ * Gets the value of the lang property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getLang() {
+ return lang;
+ }
+
+ /**
+ * Sets the value of the lang property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setLang(String value) {
+ this.lang = value;
+ }
+
+ /**
+ * Gets the value of the contentType property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+ /**
+ * Sets the value of the contentType property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setContentType(String value) {
+ this.contentType = value;
+ }
+
+ /**
+ * Gets the value of the par property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getPar() {
+ return par;
+ }
+
+ /**
+ * Sets the value of the par property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setPar(String value) {
+ this.par = value;
+ }
+
+ /**
+ * Gets the value of the minBandwidth property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getMinBandwidth() {
+ return minBandwidth;
+ }
+
+ /**
+ * Sets the value of the minBandwidth property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setMinBandwidth(Long value) {
+ this.minBandwidth = value;
+ }
+
+ /**
+ * Gets the value of the maxBandwidth property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getMaxBandwidth() {
+ return maxBandwidth;
+ }
+
+ /**
+ * Sets the value of the maxBandwidth property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setMaxBandwidth(Long value) {
+ this.maxBandwidth = value;
+ }
+
+ /**
+ * Gets the value of the minWidth property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getMinWidth() {
+ return minWidth;
+ }
+
+ /**
+ * Sets the value of the minWidth property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setMinWidth(Long value) {
+ this.minWidth = value;
+ }
+
+ /**
+ * Gets the value of the maxWidth property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getMaxWidth() {
+ return maxWidth;
+ }
+
+ /**
+ * Sets the value of the maxWidth property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setMaxWidth(Long value) {
+ this.maxWidth = value;
+ }
+
+ /**
+ * Gets the value of the minHeight property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getMinHeight() {
+ return minHeight;
+ }
+
+ /**
+ * Sets the value of the minHeight property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setMinHeight(Long value) {
+ this.minHeight = value;
+ }
+
+ /**
+ * Gets the value of the maxHeight property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getMaxHeight() {
+ return maxHeight;
+ }
+
+ /**
+ * Sets the value of the maxHeight property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setMaxHeight(Long value) {
+ this.maxHeight = value;
+ }
+
+ /**
+ * Gets the value of the minFrameRate property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMinFrameRate() {
+ return minFrameRate;
+ }
+
+ /**
+ * Sets the value of the minFrameRate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMinFrameRate(String value) {
+ this.minFrameRate = value;
+ }
+
+ /**
+ * Gets the value of the maxFrameRate property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMaxFrameRate() {
+ return maxFrameRate;
+ }
+
+ /**
+ * Sets the value of the maxFrameRate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMaxFrameRate(String value) {
+ this.maxFrameRate = value;
+ }
+
+ /**
+ * Gets the value of the segmentAlignment property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getSegmentAlignment() {
+ if (segmentAlignment == null) {
+ return "false";
+ } else {
+ return segmentAlignment;
+ }
+ }
+
+ /**
+ * Sets the value of the segmentAlignment property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setSegmentAlignment(String value) {
+ this.segmentAlignment = value;
+ }
+
+ /**
+ * Gets the value of the subsegmentAlignment property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getSubsegmentAlignment() {
+ if (subsegmentAlignment == null) {
+ return "false";
+ } else {
+ return subsegmentAlignment;
+ }
+ }
+
+ /**
+ * Sets the value of the subsegmentAlignment property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setSubsegmentAlignment(String value) {
+ this.subsegmentAlignment = value;
+ }
+
+ /**
+ * Gets the value of the subsegmentStartsWithSAP property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public long getSubsegmentStartsWithSAP() {
+ if (subsegmentStartsWithSAP == null) {
+ return 0L;
+ } else {
+ return subsegmentStartsWithSAP;
+ }
+ }
+
+ /**
+ * Sets the value of the subsegmentStartsWithSAP property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setSubsegmentStartsWithSAP(Long value) {
+ this.subsegmentStartsWithSAP = value;
+ }
+
+ /**
+ * Gets the value of the bitstreamSwitching property.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public Boolean isBitstreamSwitching() {
+ return bitstreamSwitching;
+ }
+
+ /**
+ * Sets the value of the bitstreamSwitching property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setBitstreamSwitching(Boolean value) {
+ this.bitstreamSwitching = value;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/BaseURLType.java b/common/src/main/java/ctbrec/recorder/download/dash/BaseURLType.java
new file mode 100644
index 00000000..d724e069
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/BaseURLType.java
@@ -0,0 +1,202 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+import javax.xml.namespace.QName;
+
+
+/**
+ * Java class for BaseURLType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="BaseURLType">
+ * <simpleContent>
+ * <extension base="<http://www.w3.org/2001/XMLSchema>anyURI">
+ * <attribute name="serviceLocation" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="byteRange" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="availabilityTimeOffset" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * <attribute name="availabilityTimeComplete" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </extension>
+ * </simpleContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "BaseURLType", propOrder = {
+ "value"
+})
+public class BaseURLType {
+
+ @XmlValue
+ @XmlSchemaType(name = "anyURI")
+ protected String value;
+ @XmlAttribute(name = "serviceLocation")
+ protected String serviceLocation;
+ @XmlAttribute(name = "byteRange")
+ protected String byteRange;
+ @XmlAttribute(name = "availabilityTimeOffset")
+ protected Double availabilityTimeOffset;
+ @XmlAttribute(name = "availabilityTimeComplete")
+ protected Boolean availabilityTimeComplete;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the value property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of the serviceLocation property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getServiceLocation() {
+ return serviceLocation;
+ }
+
+ /**
+ * Sets the value of the serviceLocation property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setServiceLocation(String value) {
+ this.serviceLocation = value;
+ }
+
+ /**
+ * Gets the value of the byteRange property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getByteRange() {
+ return byteRange;
+ }
+
+ /**
+ * Sets the value of the byteRange property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setByteRange(String value) {
+ this.byteRange = value;
+ }
+
+ /**
+ * Gets the value of the availabilityTimeOffset property.
+ *
+ * @return
+ * possible object is
+ * {@link Double }
+ *
+ */
+ public Double getAvailabilityTimeOffset() {
+ return availabilityTimeOffset;
+ }
+
+ /**
+ * Sets the value of the availabilityTimeOffset property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Double }
+ *
+ */
+ public void setAvailabilityTimeOffset(Double value) {
+ this.availabilityTimeOffset = value;
+ }
+
+ /**
+ * Gets the value of the availabilityTimeComplete property.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public Boolean isAvailabilityTimeComplete() {
+ return availabilityTimeComplete;
+ }
+
+ /**
+ * Sets the value of the availabilityTimeComplete property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setAvailabilityTimeComplete(Boolean value) {
+ this.availabilityTimeComplete = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/ContentComponentType.java b/common/src/main/java/ctbrec/recorder/download/dash/ContentComponentType.java
new file mode 100644
index 00000000..abd84d30
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/ContentComponentType.java
@@ -0,0 +1,351 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for ContentComponentType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="ContentComponentType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="Accessibility" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="Role" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="Rating" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="Viewpoint" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * <attribute name="lang" type="{http://www.w3.org/2001/XMLSchema}language" />
+ * <attribute name="contentType" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="par" type="{urn:mpeg:dash:schema:mpd:2011}RatioType" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "ContentComponentType", propOrder = {
+ "accessibility",
+ "role",
+ "rating",
+ "viewpoint",
+ "any"
+})
+public class ContentComponentType {
+
+ @XmlElement(name = "Accessibility")
+ protected List accessibility;
+ @XmlElement(name = "Role")
+ protected List role;
+ @XmlElement(name = "Rating")
+ protected List rating;
+ @XmlElement(name = "Viewpoint")
+ protected List viewpoint;
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "id")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long id;
+ @XmlAttribute(name = "lang")
+ @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+ @XmlSchemaType(name = "language")
+ protected String lang;
+ @XmlAttribute(name = "contentType")
+ protected String contentType;
+ @XmlAttribute(name = "par")
+ protected String par;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the accessibility property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the accessibility property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAccessibility().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getAccessibility() {
+ if (accessibility == null) {
+ accessibility = new ArrayList();
+ }
+ return this.accessibility;
+ }
+
+ /**
+ * Gets the value of the role property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the role property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getRole().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getRole() {
+ if (role == null) {
+ role = new ArrayList();
+ }
+ return this.role;
+ }
+
+ /**
+ * Gets the value of the rating property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the rating property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getRating().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getRating() {
+ if (rating == null) {
+ rating = new ArrayList();
+ }
+ return this.rating;
+ }
+
+ /**
+ * Gets the value of the viewpoint property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the viewpoint property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getViewpoint().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getViewpoint() {
+ if (viewpoint == null) {
+ viewpoint = new ArrayList();
+ }
+ return this.viewpoint;
+ }
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the id property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * Sets the value of the id property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setId(Long value) {
+ this.id = value;
+ }
+
+ /**
+ * Gets the value of the lang property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getLang() {
+ return lang;
+ }
+
+ /**
+ * Sets the value of the lang property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setLang(String value) {
+ this.lang = value;
+ }
+
+ /**
+ * Gets the value of the contentType property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+ /**
+ * Sets the value of the contentType property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setContentType(String value) {
+ this.contentType = value;
+ }
+
+ /**
+ * Gets the value of the par property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getPar() {
+ return par;
+ }
+
+ /**
+ * Sets the value of the par property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setPar(String value) {
+ this.par = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/DashDownload.java b/common/src/main/java/ctbrec/recorder/download/dash/DashDownload.java
new file mode 100644
index 00000000..351d5010
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/DashDownload.java
@@ -0,0 +1,334 @@
+package ctbrec.recorder.download.dash;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URL;
+import java.nio.file.Path;
+import java.text.DecimalFormat;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ctbrec.Config;
+import ctbrec.Model;
+import ctbrec.Recording;
+import ctbrec.io.HttpClient;
+import ctbrec.recorder.download.Download;
+import ctbrec.recorder.download.dash.SegmentTimelineType.S;
+import okhttp3.Request;
+import okhttp3.Response;
+
+public class DashDownload implements Download {
+ private static final Logger LOG = LoggerFactory.getLogger(DashDownload.class);
+
+ private int audioCounter = 0;
+ private int videoCounter = 0;
+ private DecimalFormat df = new DecimalFormat("00000");
+ private boolean videoInitLoaded = false;
+ private boolean audioInitLoaded = false;
+ private BigInteger lastAudioTimestamp = BigInteger.ZERO;
+ private BigInteger lastVideoTimestamp = BigInteger.ZERO;
+ private Object downloadFinished = new Object();
+ private HttpClient httpClient;
+ private Config config;
+ private Model model;
+ private Instant startTime;
+ private Instant endTime;
+ private Path downloadDir;
+ private String manifestUrl;
+ private boolean running = false;
+
+ private File targetFile;
+
+ public DashDownload(HttpClient httpClient, String manifestUrl) {
+ this.httpClient = httpClient;
+ this.manifestUrl = manifestUrl;
+ }
+
+ private String getManifest(String url) throws IOException {
+ // @formatter:off
+ Request request = new Request.Builder()
+ .url(url)
+ .header("Accept", "*/*")
+ .header("Accept-Language", "en-US,en;q=0.5")
+ .header("User-Agent", config.getSettings().httpUserAgent)
+ .header("Origin", model.getSite().getBaseUrl())
+ .header("Referer", model.getSite().getBaseUrl())
+ .header("Connection", "keep-alive")
+ .build(); // @formatter:on
+ LOG.trace("Loading manifest {}", url);
+ try (Response response = httpClient.execute(request)) {
+ return response.body().string();
+ }
+ }
+
+ private AdaptationSetType chooseBestVideo(List videoStreams) {
+ AdaptationSetType best = null;
+ long bestWidth = 0;
+ for (AdaptationSetType stream : videoStreams) {
+ if (stream.getWidth() > bestWidth) {
+ bestWidth = stream.getWidth();
+ best = stream;
+ }
+ }
+ return best;
+ }
+
+ private RepresentationType chooseBestRepresentation(List representations) {
+ RepresentationType best = null;
+ long bestBandwidth = 0;
+ for (RepresentationType rep : representations) {
+ if (rep.getBandwidth() > bestBandwidth) {
+ bestBandwidth = rep.getBandwidth();
+ best = rep;
+ }
+ }
+ return best;
+ }
+
+ private int downloadSegments(MPDtype mpd, AdaptationSetType adaptationSet, boolean isVideo) throws IOException {
+ if (adaptationSet == null) {
+ return 0;
+ }
+
+ SegmentTemplateType segmentTemplate = adaptationSet.getSegmentTemplate();
+ RepresentationType representation = chooseBestRepresentation(adaptationSet.getRepresentation());
+
+ int downloaded = downloadInitChunksForVideoAndAudio(isVideo, mpd, segmentTemplate, representation);
+
+ String media = segmentTemplate.getMedia();
+ media = media.replaceAll("\\$RepresentationID\\$", representation.getId()); // NOSONAR
+
+ List segments = segmentTemplate.getSegmentTimeline().getS();
+ if (!segments.isEmpty()) {
+ BigInteger timestamp = segments.get(0).getT();
+ BigInteger duration = BigInteger.ZERO;
+ for (S s : segments) {
+ timestamp = timestamp.add(duration);
+ if (isVideo && timestamp.compareTo(lastVideoTimestamp) > 0 || !isVideo && timestamp.compareTo(lastAudioTimestamp) > 0) {
+ if (isVideo) {
+ lastVideoTimestamp = timestamp;
+ } else {
+ lastAudioTimestamp = timestamp;
+ }
+ String segmentUrl = media.replaceAll("\\$Time\\$", timestamp.toString());
+ duration = s.getD();
+ URL absUrl = new URL(new URL(mpd.getLocation().get(0)), segmentUrl);
+ download(downloadDir.toFile().getCanonicalPath(), absUrl, isVideo);
+ downloaded++;
+ }
+ }
+ }
+
+ return downloaded;
+ }
+
+ private int downloadInitChunksForVideoAndAudio(boolean isVideo, MPDtype mpd, SegmentTemplateType segmentTemplate, RepresentationType representation)
+ throws IOException {
+ if (isVideo && !videoInitLoaded || !isVideo && !audioInitLoaded) {
+ String initialization = segmentTemplate.getInitializationAttribute();
+ initialization = initialization.replaceAll("\\$RepresentationID\\$", representation.getId());
+ URL initUrl = new URL(new URL(mpd.getLocation().get(0)), initialization);
+ download(downloadDir.toFile().getCanonicalPath(), initUrl, isVideo);
+ if (isVideo) {
+ LOG.debug("Video init chunk loaded");
+ videoInitLoaded = true;
+ } else {
+ LOG.debug("Audio init chunk loaded");
+ audioInitLoaded = true;
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ private void download(String dir, URL url, boolean isVideo) throws IOException {
+ // @formatter:off
+ Request request = new Request.Builder()
+ .url(url)
+ .header("Accept", "*/*")
+ .header("Accept-Language", "en-US,en;q=0.5")
+ .header("User-Agent", config.getSettings().httpUserAgent)
+ .header("Origin", model.getSite().getBaseUrl())
+ .header("Referer", model.getSite().getBaseUrl())
+ .header("Connection", "keep-alive")
+ .build(); // @formatter:on
+ int tries = 1;
+ try (Response response = httpClient.execute(request)) {
+ InputStream in = response.body().byteStream();
+ String absFile = url.getFile();
+ String prefix = isVideo ? "video" : "audio";
+ int c = isVideo ? videoCounter++ : audioCounter++;
+ File targetFile = new File(dir, prefix + '_' + df.format(c) + '_' + new File(absFile).getName());
+ while(tries <= 10) {
+ if (!targetFile.exists() || targetFile.length() == 0) {
+ LOG.trace("Loading segment, try {}, {} {} {}", tries, response.code(), response.headers().values("Content-Length"), url);
+ try (FileOutputStream out = new FileOutputStream(targetFile)) {
+ byte[] b = new byte[1024];
+ int len = -1;
+ while ((len = in.read(b)) >= 0) {
+ out.write(b, 0, len);
+ }
+ out.flush();
+ }
+ } else {
+ break;
+ }
+ tries++;
+ }
+ }
+ }
+
+ @Override
+ public void init(Config config, Model model) {
+ this.config = config;
+ this.model = model;
+ startTime = Instant.now();
+ targetFile = Config.getInstance().getFileForRecording(model, "mp4");
+ downloadDir = targetFile.getParentFile().toPath();
+ }
+
+ @Override
+ public void start() throws IOException {
+ try {
+ running = true;
+ JAXBContext jc = JAXBContext.newInstance(MPDtype.class.getPackage().getName());
+ Unmarshaller u = jc.createUnmarshaller();
+ while (running && !Thread.currentThread().isInterrupted()) {
+ downloadManifestAndItsSegments(u);
+ }
+ } catch (Exception e) {
+ LOG.error("Error while downloading dash stream", e);
+ } finally {
+ running = false;
+ endTime = Instant.now();
+ synchronized (downloadFinished) {
+ downloadFinished.notifyAll();
+ }
+ }
+ }
+
+ private void downloadManifestAndItsSegments(Unmarshaller u) throws IOException, JAXBException {
+ String manifest = getManifest(manifestUrl);
+ LOG.trace("Manifest: {}", manifest);
+ @SuppressWarnings("unchecked")
+ JAXBElement root = (JAXBElement) u.unmarshal(new ByteArrayInputStream(manifest.getBytes()));
+ MPDtype mpd = root.getValue();
+ List periods = mpd.getPeriod();
+ for (PeriodType period : periods) {
+ List videoStreams = new ArrayList<>();
+ List audioStreams = new ArrayList<>();
+
+ List adaptationSets = period.getAdaptationSet();
+ for (AdaptationSetType adaptationSet : adaptationSets) {
+ String mimeType = adaptationSet.getMimeType();
+ if (mimeType.equalsIgnoreCase("video/mp4")) {
+ videoStreams.add(adaptationSet);
+ } else if (mimeType.equalsIgnoreCase("audio/mp4")) {
+ audioStreams.add(adaptationSet);
+ }
+ }
+
+ downloadDir.toFile().mkdirs();
+
+ AdaptationSetType video = chooseBestVideo(videoStreams);
+ int downloaded = downloadSegments(mpd, video, true);
+
+ AdaptationSetType audio = audioStreams.isEmpty() ? null : audioStreams.get(0);
+ downloaded += downloadSegments(mpd, audio, false);
+
+ if (downloaded == 0) {
+ LOG.trace("No new segments - Sleeping a bit");
+ waitSomeTime();
+ }
+ }
+ }
+
+ @Override
+ public void stop() {
+ if (running) {
+ internalStop();
+ try {
+ while(running) {
+ synchronized (downloadFinished) {
+ downloadFinished.wait(TimeUnit.SECONDS.toMillis(1));
+ }
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ LOG.error("Couldn't wait for download to finish", e);
+ }
+ }
+ }
+
+ void internalStop() {
+ running = false;
+ }
+
+ @Override
+ public Model getModel() {
+ return model;
+ }
+
+ @Override
+ public Instant getStartTime() {
+ return startTime;
+ }
+
+ @Override
+ public Duration getLength() {
+ return Duration.between(startTime, Optional.ofNullable(endTime).orElse(Instant.now()));
+ }
+
+ @Override
+ public void postprocess(Recording recording) {
+ try {
+ new FfmpegMuxer(downloadDir.toFile(), targetFile.getName());
+ } catch (IOException e) {
+ LOG.error("Error while merging dash segments", e);
+ }
+ }
+
+ @Override
+ public File getTarget() {
+ return targetFile;
+ }
+
+ @Override
+ public String getPath(Model model) {
+ String absolutePath = targetFile.getAbsolutePath();
+ String recordingsDir = Config.getInstance().getSettings().recordingsDir;
+ String relativePath = absolutePath.replaceFirst(Pattern.quote(recordingsDir), "");
+ return relativePath;
+ }
+
+ /**
+ * Causes the current thread to sleep for a short amount of time. This is used to slow down retries, if something is wrong with the playlist. E.g. HTTP 403
+ * or 404
+ */
+ private void waitSomeTime() {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/DescriptorType.java b/common/src/main/java/ctbrec/recorder/download/dash/DescriptorType.java
new file mode 100644
index 00000000..ae5aa090
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/DescriptorType.java
@@ -0,0 +1,187 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for DescriptorType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="DescriptorType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="schemeIdUri" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ * <attribute name="value" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "DescriptorType", propOrder = {
+ "any"
+})
+public class DescriptorType {
+
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "schemeIdUri", required = true)
+ @XmlSchemaType(name = "anyURI")
+ protected String schemeIdUri;
+ @XmlAttribute(name = "value")
+ protected String value;
+ @XmlAttribute(name = "id")
+ protected String id;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the schemeIdUri property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getSchemeIdUri() {
+ return schemeIdUri;
+ }
+
+ /**
+ * Sets the value of the schemeIdUri property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setSchemeIdUri(String value) {
+ this.schemeIdUri = value;
+ }
+
+ /**
+ * Gets the value of the value property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of the id property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Sets the value of the id property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setId(String value) {
+ this.id = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/EventStreamType.java b/common/src/main/java/ctbrec/recorder/download/dash/EventStreamType.java
new file mode 100644
index 00000000..fefb70b6
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/EventStreamType.java
@@ -0,0 +1,283 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for EventStreamType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="EventStreamType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="Event" type="{urn:mpeg:dash:schema:mpd:2011}EventType" maxOccurs="unbounded" minOccurs="0"/>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute ref="{http://www.w3.org/1999/xlink}href"/>
+ * <attribute ref="{http://www.w3.org/1999/xlink}actuate"/>
+ * <attribute name="messageData" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ * <attribute name="schemeIdUri" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ * <attribute name="value" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="timescale" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "EventStreamType", propOrder = {
+ "event",
+ "any"
+})
+public class EventStreamType {
+
+ @XmlElement(name = "Event")
+ protected List event;
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
+ protected String href;
+ @XmlAttribute(name = "actuate", namespace = "http://www.w3.org/1999/xlink")
+ protected ActuateType actuate;
+ @XmlAttribute(name = "messageData")
+ @XmlSchemaType(name = "anyURI")
+ protected String messageData;
+ @XmlAttribute(name = "schemeIdUri", required = true)
+ @XmlSchemaType(name = "anyURI")
+ protected String schemeIdUri;
+ @XmlAttribute(name = "value")
+ protected String value;
+ @XmlAttribute(name = "timescale")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long timescale;
+
+ /**
+ * Gets the value of the event property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the event property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getEvent().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link EventType }
+ *
+ *
+ */
+ public List getEvent() {
+ if (event == null) {
+ event = new ArrayList();
+ }
+ return this.event;
+ }
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the href property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getHref() {
+ return href;
+ }
+
+ /**
+ * Sets the value of the href property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setHref(String value) {
+ this.href = value;
+ }
+
+ /**
+ * Gets the value of the actuate property.
+ *
+ * @return
+ * possible object is
+ * {@link ActuateType }
+ *
+ */
+ public ActuateType getActuate() {
+ if (actuate == null) {
+ return ActuateType.ON_REQUEST;
+ } else {
+ return actuate;
+ }
+ }
+
+ /**
+ * Sets the value of the actuate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link ActuateType }
+ *
+ */
+ public void setActuate(ActuateType value) {
+ this.actuate = value;
+ }
+
+ /**
+ * Gets the value of the messageData property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMessageData() {
+ return messageData;
+ }
+
+ /**
+ * Sets the value of the messageData property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMessageData(String value) {
+ this.messageData = value;
+ }
+
+ /**
+ * Gets the value of the schemeIdUri property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getSchemeIdUri() {
+ return schemeIdUri;
+ }
+
+ /**
+ * Sets the value of the schemeIdUri property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setSchemeIdUri(String value) {
+ this.schemeIdUri = value;
+ }
+
+ /**
+ * Gets the value of the value property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value of the value property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value of the timescale property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getTimescale() {
+ return timescale;
+ }
+
+ /**
+ * Sets the value of the timescale property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setTimescale(Long value) {
+ this.timescale = value;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/EventType.java b/common/src/main/java/ctbrec/recorder/download/dash/EventType.java
new file mode 100644
index 00000000..5f28b5ef
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/EventType.java
@@ -0,0 +1,221 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for EventType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="EventType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="presentationTime" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" default="0" />
+ * <attribute name="duration" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" />
+ * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * <attribute name="messageData" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "EventType", propOrder = {
+ "any"
+})
+public class EventType {
+
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "presentationTime")
+ @XmlSchemaType(name = "unsignedLong")
+ protected BigInteger presentationTime;
+ @XmlAttribute(name = "duration")
+ @XmlSchemaType(name = "unsignedLong")
+ protected BigInteger duration;
+ @XmlAttribute(name = "id")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long id;
+ @XmlAttribute(name = "messageData")
+ protected String messageData;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the presentationTime property.
+ *
+ * @return
+ * possible object is
+ * {@link BigInteger }
+ *
+ */
+ public BigInteger getPresentationTime() {
+ if (presentationTime == null) {
+ return new BigInteger("0");
+ } else {
+ return presentationTime;
+ }
+ }
+
+ /**
+ * Sets the value of the presentationTime property.
+ *
+ * @param value
+ * allowed object is
+ * {@link BigInteger }
+ *
+ */
+ public void setPresentationTime(BigInteger value) {
+ this.presentationTime = value;
+ }
+
+ /**
+ * Gets the value of the duration property.
+ *
+ * @return
+ * possible object is
+ * {@link BigInteger }
+ *
+ */
+ public BigInteger getDuration() {
+ return duration;
+ }
+
+ /**
+ * Sets the value of the duration property.
+ *
+ * @param value
+ * allowed object is
+ * {@link BigInteger }
+ *
+ */
+ public void setDuration(BigInteger value) {
+ this.duration = value;
+ }
+
+ /**
+ * Gets the value of the id property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * Sets the value of the id property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setId(Long value) {
+ this.id = value;
+ }
+
+ /**
+ * Gets the value of the messageData property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMessageData() {
+ return messageData;
+ }
+
+ /**
+ * Sets the value of the messageData property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMessageData(String value) {
+ this.messageData = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/FfmpegMuxer.java b/common/src/main/java/ctbrec/recorder/download/dash/FfmpegMuxer.java
new file mode 100644
index 00000000..13763b2c
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/FfmpegMuxer.java
@@ -0,0 +1,101 @@
+package ctbrec.recorder.download.dash;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Arrays;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ctbrec.io.StreamRedirectThread;
+
+public class FfmpegMuxer {
+ private static final Logger LOG = LoggerFactory.getLogger(FfmpegMuxer.class);
+ private static final int ALL_GOOD = 0;
+
+ File segmentDir;
+
+ public FfmpegMuxer(File segmentDir, String targetFileName) throws IOException {
+ this.segmentDir = segmentDir;
+ String[] videoSegments = segmentDir.list((dir, name) -> name.startsWith("video_"));
+ Arrays.sort(videoSegments);
+ String[] audioSegments = segmentDir.list((dir, name) -> name.startsWith("audio_"));
+ Arrays.sort(audioSegments);
+
+ File mp4VideoTrack = new File(segmentDir, "video.mp4");
+ mergeSegments(videoSegments, mp4VideoTrack);
+ File mp4AudioTrack = new File(segmentDir, "audio.mp4");
+ mergeSegments(audioSegments, mp4AudioTrack);
+
+ int exitCode = mergeTracks(mp4VideoTrack, mp4AudioTrack, new File(segmentDir, targetFileName));
+ if (exitCode == ALL_GOOD) {
+ LOG.debug("Deleting merged video and audio tracks");
+ Files.delete(mp4VideoTrack.toPath());
+ Files.delete(mp4AudioTrack.toPath());
+ LOG.debug("Deleting segments");
+ deleteFiles(segmentDir, videoSegments);
+ deleteFiles(segmentDir, audioSegments);
+ } else {
+ throw new ProcessExitedUncleanException("FFMPEG exited with " + exitCode);
+ }
+ }
+
+ private void deleteFiles(File dir, String[] files) {
+ for (String file : files) {
+ File absFile = new File(dir, file);
+ try {
+ Files.delete(absFile.toPath());
+ } catch(IOException e) {
+ LOG.info("Couldn't delete segment {}", absFile, e);
+ }
+ }
+ }
+
+ private void mergeSegments(String[] segments, File toFile) throws IOException {
+ try (FileOutputStream out = new FileOutputStream(toFile)) {
+ for (String segment : segments) {
+ try (FileInputStream in = new FileInputStream(new File(segmentDir, segment))) {
+ byte[] buffer = new byte[1024];
+ int len = -1;
+ while ((len = in.read(buffer)) >= 0) {
+ out.write(buffer, 0, len);
+ }
+ }
+ }
+ }
+ }
+
+ private int mergeTracks(File mp4VideoTrack, File mp4AudioTrack, File output) throws IOException {
+ try {
+ LOG.debug("Merging:\n{}\n{}\n{}", mp4VideoTrack, mp4AudioTrack, output);
+ // @formatter:off
+ String[] cmdline = new String[] {
+ "ffmpeg",
+ "-i", mp4VideoTrack.getCanonicalPath(),
+ "-i", mp4AudioTrack.getCanonicalPath(),
+ "-c:v", "copy",
+ "-c:a", "copy",
+ output.getCanonicalPath()
+ };
+ // @formatter:on
+ LOG.debug("Command line: {}", Arrays.toString(cmdline));
+ Process ffmpeg = Runtime.getRuntime().exec(cmdline);
+ new Thread(new StreamRedirectThread(ffmpeg.getInputStream(), System.out)).start(); // NOSONAR
+ new Thread(new StreamRedirectThread(ffmpeg.getErrorStream(), System.err)).start(); // NOSONAR
+ return ffmpeg.waitFor();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ LOG.error("Interrupted while waiting for FFMPEG", e);
+ return 1;
+ }
+ }
+
+ public static class ProcessExitedUncleanException extends RuntimeException {
+ public ProcessExitedUncleanException(String msg) {
+ super(msg);
+ }
+ }
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/MPDtype.java b/common/src/main/java/ctbrec/recorder/download/dash/MPDtype.java
new file mode 100644
index 00000000..956f2be7
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/MPDtype.java
@@ -0,0 +1,731 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.datatype.Duration;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for MPDtype complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="MPDtype">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="ProgramInformation" type="{urn:mpeg:dash:schema:mpd:2011}ProgramInformationType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="BaseURL" type="{urn:mpeg:dash:schema:mpd:2011}BaseURLType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="Location" type="{http://www.w3.org/2001/XMLSchema}anyURI" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="Period" type="{urn:mpeg:dash:schema:mpd:2011}PeriodType" maxOccurs="unbounded"/>
+ * <element name="Metrics" type="{urn:mpeg:dash:schema:mpd:2011}MetricsType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="EssentialProperty" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="SupplementalProperty" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="UTCTiming" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="profiles" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="type" type="{urn:mpeg:dash:schema:mpd:2011}PresentationType" default="static" />
+ * <attribute name="availabilityStartTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
+ * <attribute name="availabilityEndTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
+ * <attribute name="publishTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
+ * <attribute name="mediaPresentationDuration" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <attribute name="minimumUpdatePeriod" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <attribute name="minBufferTime" use="required" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <attribute name="timeShiftBufferDepth" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <attribute name="suggestedPresentationDelay" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <attribute name="maxSegmentDuration" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <attribute name="maxSubsegmentDuration" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "MPDtype", propOrder = {
+ "programInformation",
+ "baseURL",
+ "location",
+ "period",
+ "metrics",
+ "essentialProperty",
+ "supplementalProperty",
+ "utcTiming",
+ "any"
+})
+public class MPDtype {
+
+ @XmlElement(name = "ProgramInformation")
+ protected List programInformation;
+ @XmlElement(name = "BaseURL")
+ protected List baseURL;
+ @XmlElement(name = "Location")
+ @XmlSchemaType(name = "anyURI")
+ protected List location;
+ @XmlElement(name = "Period", required = true)
+ protected List period;
+ @XmlElement(name = "Metrics")
+ protected List metrics;
+ @XmlElement(name = "EssentialProperty")
+ protected List essentialProperty;
+ @XmlElement(name = "SupplementalProperty")
+ protected List supplementalProperty;
+ @XmlElement(name = "UTCTiming")
+ protected List utcTiming;
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "id")
+ protected String id;
+ @XmlAttribute(name = "profiles", required = true)
+ protected String profiles;
+ @XmlAttribute(name = "type")
+ protected PresentationType type;
+ @XmlAttribute(name = "availabilityStartTime")
+ @XmlSchemaType(name = "dateTime")
+ protected XMLGregorianCalendar availabilityStartTime;
+ @XmlAttribute(name = "availabilityEndTime")
+ @XmlSchemaType(name = "dateTime")
+ protected XMLGregorianCalendar availabilityEndTime;
+ @XmlAttribute(name = "publishTime")
+ @XmlSchemaType(name = "dateTime")
+ protected XMLGregorianCalendar publishTime;
+ @XmlAttribute(name = "mediaPresentationDuration")
+ protected Duration mediaPresentationDuration;
+ @XmlAttribute(name = "minimumUpdatePeriod")
+ protected Duration minimumUpdatePeriod;
+ @XmlAttribute(name = "minBufferTime", required = true)
+ protected Duration minBufferTime;
+ @XmlAttribute(name = "timeShiftBufferDepth")
+ protected Duration timeShiftBufferDepth;
+ @XmlAttribute(name = "suggestedPresentationDelay")
+ protected Duration suggestedPresentationDelay;
+ @XmlAttribute(name = "maxSegmentDuration")
+ protected Duration maxSegmentDuration;
+ @XmlAttribute(name = "maxSubsegmentDuration")
+ protected Duration maxSubsegmentDuration;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the programInformation property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the programInformation property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getProgramInformation().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link ProgramInformationType }
+ *
+ *
+ */
+ public List getProgramInformation() {
+ if (programInformation == null) {
+ programInformation = new ArrayList();
+ }
+ return this.programInformation;
+ }
+
+ /**
+ * Gets the value of the baseURL property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the baseURL property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getBaseURL().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link BaseURLType }
+ *
+ *
+ */
+ public List getBaseURL() {
+ if (baseURL == null) {
+ baseURL = new ArrayList();
+ }
+ return this.baseURL;
+ }
+
+ /**
+ * Gets the value of the location property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the location property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getLocation().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link String }
+ *
+ *
+ */
+ public List getLocation() {
+ if (location == null) {
+ location = new ArrayList();
+ }
+ return this.location;
+ }
+
+ /**
+ * Gets the value of the period property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the period property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getPeriod().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link PeriodType }
+ *
+ *
+ */
+ public List getPeriod() {
+ if (period == null) {
+ period = new ArrayList();
+ }
+ return this.period;
+ }
+
+ /**
+ * Gets the value of the metrics property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the metrics property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getMetrics().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link MetricsType }
+ *
+ *
+ */
+ public List getMetrics() {
+ if (metrics == null) {
+ metrics = new ArrayList();
+ }
+ return this.metrics;
+ }
+
+ /**
+ * Gets the value of the essentialProperty property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the essentialProperty property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getEssentialProperty().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getEssentialProperty() {
+ if (essentialProperty == null) {
+ essentialProperty = new ArrayList();
+ }
+ return this.essentialProperty;
+ }
+
+ /**
+ * Gets the value of the supplementalProperty property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the supplementalProperty property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getSupplementalProperty().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getSupplementalProperty() {
+ if (supplementalProperty == null) {
+ supplementalProperty = new ArrayList();
+ }
+ return this.supplementalProperty;
+ }
+
+ /**
+ * Gets the value of the utcTiming property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the utcTiming property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getUTCTiming().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getUTCTiming() {
+ if (utcTiming == null) {
+ utcTiming = new ArrayList();
+ }
+ return this.utcTiming;
+ }
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the id property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Sets the value of the id property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setId(String value) {
+ this.id = value;
+ }
+
+ /**
+ * Gets the value of the profiles property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getProfiles() {
+ return profiles;
+ }
+
+ /**
+ * Sets the value of the profiles property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setProfiles(String value) {
+ this.profiles = value;
+ }
+
+ /**
+ * Gets the value of the type property.
+ *
+ * @return
+ * possible object is
+ * {@link PresentationType }
+ *
+ */
+ public PresentationType getType() {
+ if (type == null) {
+ return PresentationType.STATIC;
+ } else {
+ return type;
+ }
+ }
+
+ /**
+ * Sets the value of the type property.
+ *
+ * @param value
+ * allowed object is
+ * {@link PresentationType }
+ *
+ */
+ public void setType(PresentationType value) {
+ this.type = value;
+ }
+
+ /**
+ * Gets the value of the availabilityStartTime property.
+ *
+ * @return
+ * possible object is
+ * {@link XMLGregorianCalendar }
+ *
+ */
+ public XMLGregorianCalendar getAvailabilityStartTime() {
+ return availabilityStartTime;
+ }
+
+ /**
+ * Sets the value of the availabilityStartTime property.
+ *
+ * @param value
+ * allowed object is
+ * {@link XMLGregorianCalendar }
+ *
+ */
+ public void setAvailabilityStartTime(XMLGregorianCalendar value) {
+ this.availabilityStartTime = value;
+ }
+
+ /**
+ * Gets the value of the availabilityEndTime property.
+ *
+ * @return
+ * possible object is
+ * {@link XMLGregorianCalendar }
+ *
+ */
+ public XMLGregorianCalendar getAvailabilityEndTime() {
+ return availabilityEndTime;
+ }
+
+ /**
+ * Sets the value of the availabilityEndTime property.
+ *
+ * @param value
+ * allowed object is
+ * {@link XMLGregorianCalendar }
+ *
+ */
+ public void setAvailabilityEndTime(XMLGregorianCalendar value) {
+ this.availabilityEndTime = value;
+ }
+
+ /**
+ * Gets the value of the publishTime property.
+ *
+ * @return
+ * possible object is
+ * {@link XMLGregorianCalendar }
+ *
+ */
+ public XMLGregorianCalendar getPublishTime() {
+ return publishTime;
+ }
+
+ /**
+ * Sets the value of the publishTime property.
+ *
+ * @param value
+ * allowed object is
+ * {@link XMLGregorianCalendar }
+ *
+ */
+ public void setPublishTime(XMLGregorianCalendar value) {
+ this.publishTime = value;
+ }
+
+ /**
+ * Gets the value of the mediaPresentationDuration property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getMediaPresentationDuration() {
+ return mediaPresentationDuration;
+ }
+
+ /**
+ * Sets the value of the mediaPresentationDuration property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setMediaPresentationDuration(Duration value) {
+ this.mediaPresentationDuration = value;
+ }
+
+ /**
+ * Gets the value of the minimumUpdatePeriod property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getMinimumUpdatePeriod() {
+ return minimumUpdatePeriod;
+ }
+
+ /**
+ * Sets the value of the minimumUpdatePeriod property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setMinimumUpdatePeriod(Duration value) {
+ this.minimumUpdatePeriod = value;
+ }
+
+ /**
+ * Gets the value of the minBufferTime property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getMinBufferTime() {
+ return minBufferTime;
+ }
+
+ /**
+ * Sets the value of the minBufferTime property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setMinBufferTime(Duration value) {
+ this.minBufferTime = value;
+ }
+
+ /**
+ * Gets the value of the timeShiftBufferDepth property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getTimeShiftBufferDepth() {
+ return timeShiftBufferDepth;
+ }
+
+ /**
+ * Sets the value of the timeShiftBufferDepth property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setTimeShiftBufferDepth(Duration value) {
+ this.timeShiftBufferDepth = value;
+ }
+
+ /**
+ * Gets the value of the suggestedPresentationDelay property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getSuggestedPresentationDelay() {
+ return suggestedPresentationDelay;
+ }
+
+ /**
+ * Sets the value of the suggestedPresentationDelay property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setSuggestedPresentationDelay(Duration value) {
+ this.suggestedPresentationDelay = value;
+ }
+
+ /**
+ * Gets the value of the maxSegmentDuration property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getMaxSegmentDuration() {
+ return maxSegmentDuration;
+ }
+
+ /**
+ * Sets the value of the maxSegmentDuration property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setMaxSegmentDuration(Duration value) {
+ this.maxSegmentDuration = value;
+ }
+
+ /**
+ * Gets the value of the maxSubsegmentDuration property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getMaxSubsegmentDuration() {
+ return maxSubsegmentDuration;
+ }
+
+ /**
+ * Sets the value of the maxSubsegmentDuration property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setMaxSubsegmentDuration(Duration value) {
+ this.maxSubsegmentDuration = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/MergerMuxer.java b/common/src/main/java/ctbrec/recorder/download/dash/MergerMuxer.java
new file mode 100644
index 00000000..af01cb35
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/MergerMuxer.java
@@ -0,0 +1,66 @@
+package ctbrec.recorder.download.dash;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Arrays;
+
+import org.mp4parser.Container;
+import org.mp4parser.muxer.Movie;
+import org.mp4parser.muxer.Track;
+import org.mp4parser.muxer.builder.DefaultMp4Builder;
+import org.mp4parser.muxer.container.mp4.MovieCreator;
+
+public class MergerMuxer {
+ File segmentDir;
+
+ public MergerMuxer(File segmentDir) throws IOException {
+ this.segmentDir = segmentDir;
+ String[] videoSegments = segmentDir.list((dir, name) -> name.startsWith("video_"));
+ Arrays.sort(videoSegments);
+ String[] audioSegments = segmentDir.list((dir, name) -> name.startsWith("audio_"));
+ Arrays.sort(audioSegments);
+
+ File mp4VideoTrack = new File(segmentDir, "video.mp4");
+ mergeSegments(videoSegments, mp4VideoTrack);
+ File mp4AudioTrack = new File(segmentDir, "audio.mp4");
+ mergeSegments(audioSegments, mp4AudioTrack);
+
+ mergeTracks(mp4VideoTrack, mp4AudioTrack, new File(segmentDir, "merged.mp4"));
+ Files.delete(mp4VideoTrack.toPath());
+ Files.delete(mp4AudioTrack.toPath());
+ }
+
+ private void mergeSegments(String[] segments, File toFile) throws IOException {
+ try (FileOutputStream out = new FileOutputStream(toFile)) {
+ for (String segment : segments) {
+ try (FileInputStream in = new FileInputStream(new File(segmentDir, segment))) {
+ byte[] buffer = new byte[1024];
+ int len = -1;
+ while ((len = in.read(buffer)) >= 0) {
+ out.write(buffer, 0, len);
+ }
+ }
+ }
+ }
+ }
+
+ private void mergeTracks(File mp4VideoTrack, File mp4AudioTrack, File output) throws IOException {
+ Movie videoMovie = MovieCreator.build(mp4VideoTrack.getCanonicalPath());
+ Track videoTrack = videoMovie.getTracks().get(0);
+ Movie audioMovie = MovieCreator.build(mp4AudioTrack.getCanonicalPath());
+ Track audioTrack = audioMovie.getTracks().get(0);
+
+ Movie merged = new Movie();
+ merged.addTrack(videoTrack);
+ merged.addTrack(audioTrack);
+
+ try (FileOutputStream out = new FileOutputStream(output)) {
+ DefaultMp4Builder builder = new DefaultMp4Builder();
+ Container stdMp4 = builder.build(merged);
+ stdMp4.writeContainer(out.getChannel());
+ }
+ }
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/MetricsType.java b/common/src/main/java/ctbrec/recorder/download/dash/MetricsType.java
new file mode 100644
index 00000000..01414738
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/MetricsType.java
@@ -0,0 +1,198 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for MetricsType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="MetricsType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="Reporting" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded"/>
+ * <element name="Range" type="{urn:mpeg:dash:schema:mpd:2011}RangeType" maxOccurs="unbounded" minOccurs="0"/>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="metrics" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "MetricsType", propOrder = {
+ "reporting",
+ "range",
+ "any"
+})
+public class MetricsType {
+
+ @XmlElement(name = "Reporting", required = true)
+ protected List reporting;
+ @XmlElement(name = "Range")
+ protected List range;
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "metrics", required = true)
+ protected String metrics;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the reporting property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the reporting property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getReporting().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getReporting() {
+ if (reporting == null) {
+ reporting = new ArrayList();
+ }
+ return this.reporting;
+ }
+
+ /**
+ * Gets the value of the range property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the range property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getRange().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link RangeType }
+ *
+ *
+ */
+ public List getRange() {
+ if (range == null) {
+ range = new ArrayList();
+ }
+ return this.range;
+ }
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the metrics property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMetrics() {
+ return metrics;
+ }
+
+ /**
+ * Sets the value of the metrics property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMetrics(String value) {
+ this.metrics = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/MultipleSegmentBaseType.java b/common/src/main/java/ctbrec/recorder/download/dash/MultipleSegmentBaseType.java
new file mode 100644
index 00000000..bc34a9fa
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/MultipleSegmentBaseType.java
@@ -0,0 +1,163 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * Java class for MultipleSegmentBaseType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="MultipleSegmentBaseType">
+ * <complexContent>
+ * <extension base="{urn:mpeg:dash:schema:mpd:2011}SegmentBaseType">
+ * <sequence>
+ * <element name="SegmentTimeline" type="{urn:mpeg:dash:schema:mpd:2011}SegmentTimelineType" minOccurs="0"/>
+ * <element name="BitstreamSwitching" type="{urn:mpeg:dash:schema:mpd:2011}URLType" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="duration" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * <attribute name="startNumber" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "MultipleSegmentBaseType", propOrder = {
+ "segmentTimeline",
+ "bitstreamSwitching"
+})
+@XmlSeeAlso({
+ SegmentTemplateType.class,
+ SegmentListType.class
+})
+public class MultipleSegmentBaseType
+ extends SegmentBaseType
+{
+
+ @XmlElement(name = "SegmentTimeline")
+ protected SegmentTimelineType segmentTimeline;
+ @XmlElement(name = "BitstreamSwitching")
+ protected URLType bitstreamSwitching;
+ @XmlAttribute(name = "duration")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long duration;
+ @XmlAttribute(name = "startNumber")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long startNumber;
+
+ /**
+ * Gets the value of the segmentTimeline property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentTimelineType }
+ *
+ */
+ public SegmentTimelineType getSegmentTimeline() {
+ return segmentTimeline;
+ }
+
+ /**
+ * Sets the value of the segmentTimeline property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentTimelineType }
+ *
+ */
+ public void setSegmentTimeline(SegmentTimelineType value) {
+ this.segmentTimeline = value;
+ }
+
+ /**
+ * Gets the value of the bitstreamSwitching property.
+ *
+ * @return
+ * possible object is
+ * {@link URLType }
+ *
+ */
+ public URLType getBitstreamSwitching() {
+ return bitstreamSwitching;
+ }
+
+ /**
+ * Sets the value of the bitstreamSwitching property.
+ *
+ * @param value
+ * allowed object is
+ * {@link URLType }
+ *
+ */
+ public void setBitstreamSwitching(URLType value) {
+ this.bitstreamSwitching = value;
+ }
+
+ /**
+ * Gets the value of the duration property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getDuration() {
+ return duration;
+ }
+
+ /**
+ * Sets the value of the duration property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setDuration(Long value) {
+ this.duration = value;
+ }
+
+ /**
+ * Gets the value of the startNumber property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getStartNumber() {
+ return startNumber;
+ }
+
+ /**
+ * Sets the value of the startNumber property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setStartNumber(Long value) {
+ this.startNumber = value;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/ObjectFactory.java b/common/src/main/java/ctbrec/recorder/download/dash/ObjectFactory.java
new file mode 100644
index 00000000..cd0be3e1
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/ObjectFactory.java
@@ -0,0 +1,244 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlElementDecl;
+import javax.xml.bind.annotation.XmlRegistry;
+import javax.xml.namespace.QName;
+
+
+/**
+ * This object contains factory methods for each
+ * Java content interface and Java element interface
+ * generated in the ctbrec.dash package.
+ * An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups. Factory methods for each of these are
+ * provided in this class.
+ *
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+ private final static QName _MPD_QNAME = new QName("urn:mpeg:dash:schema:mpd:2011", "MPD");
+
+ /**
+ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: ctbrec.dash
+ *
+ */
+ public ObjectFactory() {
+ }
+
+ /**
+ * Create an instance of {@link SegmentTimelineType }
+ *
+ */
+ public SegmentTimelineType createSegmentTimelineType() {
+ return new SegmentTimelineType();
+ }
+
+ /**
+ * Create an instance of {@link MPDtype }
+ *
+ */
+ public MPDtype createMPDtype() {
+ return new MPDtype();
+ }
+
+ /**
+ * Create an instance of {@link PeriodType }
+ *
+ */
+ public PeriodType createPeriodType() {
+ return new PeriodType();
+ }
+
+ /**
+ * Create an instance of {@link RepresentationBaseType }
+ *
+ */
+ public RepresentationBaseType createRepresentationBaseType() {
+ return new RepresentationBaseType();
+ }
+
+ /**
+ * Create an instance of {@link EventType }
+ *
+ */
+ public EventType createEventType() {
+ return new EventType();
+ }
+
+ /**
+ * Create an instance of {@link SubsetType }
+ *
+ */
+ public SubsetType createSubsetType() {
+ return new SubsetType();
+ }
+
+ /**
+ * Create an instance of {@link ProgramInformationType }
+ *
+ */
+ public ProgramInformationType createProgramInformationType() {
+ return new ProgramInformationType();
+ }
+
+ /**
+ * Create an instance of {@link BaseURLType }
+ *
+ */
+ public BaseURLType createBaseURLType() {
+ return new BaseURLType();
+ }
+
+ /**
+ * Create an instance of {@link RepresentationType }
+ *
+ */
+ public RepresentationType createRepresentationType() {
+ return new RepresentationType();
+ }
+
+ /**
+ * Create an instance of {@link RangeType }
+ *
+ */
+ public RangeType createRangeType() {
+ return new RangeType();
+ }
+
+ /**
+ * Create an instance of {@link EventStreamType }
+ *
+ */
+ public EventStreamType createEventStreamType() {
+ return new EventStreamType();
+ }
+
+ /**
+ * Create an instance of {@link SegmentBaseType }
+ *
+ */
+ public SegmentBaseType createSegmentBaseType() {
+ return new SegmentBaseType();
+ }
+
+ /**
+ * Create an instance of {@link MetricsType }
+ *
+ */
+ public MetricsType createMetricsType() {
+ return new MetricsType();
+ }
+
+ /**
+ * Create an instance of {@link SegmentTemplateType }
+ *
+ */
+ public SegmentTemplateType createSegmentTemplateType() {
+ return new SegmentTemplateType();
+ }
+
+ /**
+ * Create an instance of {@link URLType }
+ *
+ */
+ public URLType createURLType() {
+ return new URLType();
+ }
+
+ /**
+ * Create an instance of {@link SwitchingType }
+ *
+ */
+ public SwitchingType createSwitchingType() {
+ return new SwitchingType();
+ }
+
+ /**
+ * Create an instance of {@link AdaptationSetType }
+ *
+ */
+ public AdaptationSetType createAdaptationSetType() {
+ return new AdaptationSetType();
+ }
+
+ /**
+ * Create an instance of {@link SegmentURLType }
+ *
+ */
+ public SegmentURLType createSegmentURLType() {
+ return new SegmentURLType();
+ }
+
+ /**
+ * Create an instance of {@link DescriptorType }
+ *
+ */
+ public DescriptorType createDescriptorType() {
+ return new DescriptorType();
+ }
+
+ /**
+ * Create an instance of {@link SegmentListType }
+ *
+ */
+ public SegmentListType createSegmentListType() {
+ return new SegmentListType();
+ }
+
+ /**
+ * Create an instance of {@link ContentComponentType }
+ *
+ */
+ public ContentComponentType createContentComponentType() {
+ return new ContentComponentType();
+ }
+
+ /**
+ * Create an instance of {@link MultipleSegmentBaseType }
+ *
+ */
+ public MultipleSegmentBaseType createMultipleSegmentBaseType() {
+ return new MultipleSegmentBaseType();
+ }
+
+ /**
+ * Create an instance of {@link SubRepresentationType }
+ *
+ */
+ public SubRepresentationType createSubRepresentationType() {
+ return new SubRepresentationType();
+ }
+
+ /**
+ * Create an instance of {@link SegmentTimelineType.S }
+ *
+ */
+ public SegmentTimelineType.S createSegmentTimelineTypeS() {
+ return new SegmentTimelineType.S();
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link MPDtype }{@code >}}
+ *
+ */
+ @XmlElementDecl(namespace = "urn:mpeg:dash:schema:mpd:2011", name = "MPD")
+ public JAXBElement createMPD(MPDtype value) {
+ return new JAXBElement(_MPD_QNAME, MPDtype.class, null, value);
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/PeriodType.java b/common/src/main/java/ctbrec/recorder/download/dash/PeriodType.java
new file mode 100644
index 00000000..22ea5b54
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/PeriodType.java
@@ -0,0 +1,553 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.datatype.Duration;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for PeriodType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="PeriodType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="BaseURL" type="{urn:mpeg:dash:schema:mpd:2011}BaseURLType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="SegmentBase" type="{urn:mpeg:dash:schema:mpd:2011}SegmentBaseType" minOccurs="0"/>
+ * <element name="SegmentList" type="{urn:mpeg:dash:schema:mpd:2011}SegmentListType" minOccurs="0"/>
+ * <element name="SegmentTemplate" type="{urn:mpeg:dash:schema:mpd:2011}SegmentTemplateType" minOccurs="0"/>
+ * <element name="AssetIdentifier" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" minOccurs="0"/>
+ * <element name="EventStream" type="{urn:mpeg:dash:schema:mpd:2011}EventStreamType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="AdaptationSet" type="{urn:mpeg:dash:schema:mpd:2011}AdaptationSetType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="Subset" type="{urn:mpeg:dash:schema:mpd:2011}SubsetType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="SupplementalProperty" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute ref="{http://www.w3.org/1999/xlink}href"/>
+ * <attribute ref="{http://www.w3.org/1999/xlink}actuate"/>
+ * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="start" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <attribute name="duration" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <attribute name="bitstreamSwitching" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "PeriodType", propOrder = {
+ "baseURL",
+ "segmentBase",
+ "segmentList",
+ "segmentTemplate",
+ "assetIdentifier",
+ "eventStream",
+ "adaptationSet",
+ "subset",
+ "supplementalProperty",
+ "any"
+})
+public class PeriodType {
+
+ @XmlElement(name = "BaseURL")
+ protected List baseURL;
+ @XmlElement(name = "SegmentBase")
+ protected SegmentBaseType segmentBase;
+ @XmlElement(name = "SegmentList")
+ protected SegmentListType segmentList;
+ @XmlElement(name = "SegmentTemplate")
+ protected SegmentTemplateType segmentTemplate;
+ @XmlElement(name = "AssetIdentifier")
+ protected DescriptorType assetIdentifier;
+ @XmlElement(name = "EventStream")
+ protected List eventStream;
+ @XmlElement(name = "AdaptationSet")
+ protected List adaptationSet;
+ @XmlElement(name = "Subset")
+ protected List subset;
+ @XmlElement(name = "SupplementalProperty")
+ protected List supplementalProperty;
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
+ protected String href;
+ @XmlAttribute(name = "actuate", namespace = "http://www.w3.org/1999/xlink")
+ protected ActuateType actuate;
+ @XmlAttribute(name = "id")
+ protected String id;
+ @XmlAttribute(name = "start")
+ protected Duration start;
+ @XmlAttribute(name = "duration")
+ protected Duration duration;
+ @XmlAttribute(name = "bitstreamSwitching")
+ protected Boolean bitstreamSwitching;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the baseURL property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the baseURL property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getBaseURL().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link BaseURLType }
+ *
+ *
+ */
+ public List getBaseURL() {
+ if (baseURL == null) {
+ baseURL = new ArrayList();
+ }
+ return this.baseURL;
+ }
+
+ /**
+ * Gets the value of the segmentBase property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentBaseType }
+ *
+ */
+ public SegmentBaseType getSegmentBase() {
+ return segmentBase;
+ }
+
+ /**
+ * Sets the value of the segmentBase property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentBaseType }
+ *
+ */
+ public void setSegmentBase(SegmentBaseType value) {
+ this.segmentBase = value;
+ }
+
+ /**
+ * Gets the value of the segmentList property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentListType }
+ *
+ */
+ public SegmentListType getSegmentList() {
+ return segmentList;
+ }
+
+ /**
+ * Sets the value of the segmentList property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentListType }
+ *
+ */
+ public void setSegmentList(SegmentListType value) {
+ this.segmentList = value;
+ }
+
+ /**
+ * Gets the value of the segmentTemplate property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentTemplateType }
+ *
+ */
+ public SegmentTemplateType getSegmentTemplate() {
+ return segmentTemplate;
+ }
+
+ /**
+ * Sets the value of the segmentTemplate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentTemplateType }
+ *
+ */
+ public void setSegmentTemplate(SegmentTemplateType value) {
+ this.segmentTemplate = value;
+ }
+
+ /**
+ * Gets the value of the assetIdentifier property.
+ *
+ * @return
+ * possible object is
+ * {@link DescriptorType }
+ *
+ */
+ public DescriptorType getAssetIdentifier() {
+ return assetIdentifier;
+ }
+
+ /**
+ * Sets the value of the assetIdentifier property.
+ *
+ * @param value
+ * allowed object is
+ * {@link DescriptorType }
+ *
+ */
+ public void setAssetIdentifier(DescriptorType value) {
+ this.assetIdentifier = value;
+ }
+
+ /**
+ * Gets the value of the eventStream property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the eventStream property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getEventStream().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link EventStreamType }
+ *
+ *
+ */
+ public List getEventStream() {
+ if (eventStream == null) {
+ eventStream = new ArrayList();
+ }
+ return this.eventStream;
+ }
+
+ /**
+ * Gets the value of the adaptationSet property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the adaptationSet property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAdaptationSet().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link AdaptationSetType }
+ *
+ *
+ */
+ public List getAdaptationSet() {
+ if (adaptationSet == null) {
+ adaptationSet = new ArrayList();
+ }
+ return this.adaptationSet;
+ }
+
+ /**
+ * Gets the value of the subset property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the subset property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getSubset().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link SubsetType }
+ *
+ *
+ */
+ public List getSubset() {
+ if (subset == null) {
+ subset = new ArrayList();
+ }
+ return this.subset;
+ }
+
+ /**
+ * Gets the value of the supplementalProperty property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the supplementalProperty property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getSupplementalProperty().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getSupplementalProperty() {
+ if (supplementalProperty == null) {
+ supplementalProperty = new ArrayList();
+ }
+ return this.supplementalProperty;
+ }
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the href property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getHref() {
+ return href;
+ }
+
+ /**
+ * Sets the value of the href property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setHref(String value) {
+ this.href = value;
+ }
+
+ /**
+ * Gets the value of the actuate property.
+ *
+ * @return
+ * possible object is
+ * {@link ActuateType }
+ *
+ */
+ public ActuateType getActuate() {
+ if (actuate == null) {
+ return ActuateType.ON_REQUEST;
+ } else {
+ return actuate;
+ }
+ }
+
+ /**
+ * Sets the value of the actuate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link ActuateType }
+ *
+ */
+ public void setActuate(ActuateType value) {
+ this.actuate = value;
+ }
+
+ /**
+ * Gets the value of the id property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Sets the value of the id property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setId(String value) {
+ this.id = value;
+ }
+
+ /**
+ * Gets the value of the start property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getStart() {
+ return start;
+ }
+
+ /**
+ * Sets the value of the start property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setStart(Duration value) {
+ this.start = value;
+ }
+
+ /**
+ * Gets the value of the duration property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getDuration() {
+ return duration;
+ }
+
+ /**
+ * Sets the value of the duration property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setDuration(Duration value) {
+ this.duration = value;
+ }
+
+ /**
+ * Gets the value of the bitstreamSwitching property.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public boolean isBitstreamSwitching() {
+ if (bitstreamSwitching == null) {
+ return false;
+ } else {
+ return bitstreamSwitching;
+ }
+ }
+
+ /**
+ * Sets the value of the bitstreamSwitching property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setBitstreamSwitching(Boolean value) {
+ this.bitstreamSwitching = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/PresentationType.java b/common/src/main/java/ctbrec/recorder/download/dash/PresentationType.java
new file mode 100644
index 00000000..2ac216f8
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/PresentationType.java
@@ -0,0 +1,58 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * Java class for PresentationType.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <simpleType name="PresentationType">
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ * <enumeration value="static"/>
+ * <enumeration value="dynamic"/>
+ * </restriction>
+ * </simpleType>
+ *
+ *
+ */
+@XmlType(name = "PresentationType")
+@XmlEnum
+public enum PresentationType {
+
+ @XmlEnumValue("static")
+ STATIC("static"),
+ @XmlEnumValue("dynamic")
+ DYNAMIC("dynamic");
+ private final String value;
+
+ PresentationType(String v) {
+ value = v;
+ }
+
+ public String value() {
+ return value;
+ }
+
+ public static PresentationType fromValue(String v) {
+ for (PresentationType c: PresentationType.values()) {
+ if (c.value.equals(v)) {
+ return c;
+ }
+ }
+ throw new IllegalArgumentException(v);
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/ProgramInformationType.java b/common/src/main/java/ctbrec/recorder/download/dash/ProgramInformationType.java
new file mode 100644
index 00000000..21221500
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/ProgramInformationType.java
@@ -0,0 +1,249 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for ProgramInformationType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="ProgramInformationType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="Title" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ * <element name="Source" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ * <element name="Copyright" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="lang" type="{http://www.w3.org/2001/XMLSchema}language" />
+ * <attribute name="moreInformationURL" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "ProgramInformationType", propOrder = {
+ "title",
+ "source",
+ "copyright",
+ "any"
+})
+public class ProgramInformationType {
+
+ @XmlElement(name = "Title")
+ protected String title;
+ @XmlElement(name = "Source")
+ protected String source;
+ @XmlElement(name = "Copyright")
+ protected String copyright;
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "lang")
+ @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+ @XmlSchemaType(name = "language")
+ protected String lang;
+ @XmlAttribute(name = "moreInformationURL")
+ @XmlSchemaType(name = "anyURI")
+ protected String moreInformationURL;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the title property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Sets the value of the title property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setTitle(String value) {
+ this.title = value;
+ }
+
+ /**
+ * Gets the value of the source property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getSource() {
+ return source;
+ }
+
+ /**
+ * Sets the value of the source property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setSource(String value) {
+ this.source = value;
+ }
+
+ /**
+ * Gets the value of the copyright property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getCopyright() {
+ return copyright;
+ }
+
+ /**
+ * Sets the value of the copyright property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setCopyright(String value) {
+ this.copyright = value;
+ }
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the lang property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getLang() {
+ return lang;
+ }
+
+ /**
+ * Sets the value of the lang property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setLang(String value) {
+ this.lang = value;
+ }
+
+ /**
+ * Gets the value of the moreInformationURL property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMoreInformationURL() {
+ return moreInformationURL;
+ }
+
+ /**
+ * Sets the value of the moreInformationURL property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMoreInformationURL(String value) {
+ this.moreInformationURL = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/RangeType.java b/common/src/main/java/ctbrec/recorder/download/dash/RangeType.java
new file mode 100644
index 00000000..77c5b9e6
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/RangeType.java
@@ -0,0 +1,93 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.datatype.Duration;
+
+
+/**
+ * Java class for RangeType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="RangeType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <attribute name="starttime" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * <attribute name="duration" type="{http://www.w3.org/2001/XMLSchema}duration" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "RangeType")
+public class RangeType {
+
+ @XmlAttribute(name = "starttime")
+ protected Duration starttime;
+ @XmlAttribute(name = "duration")
+ protected Duration duration;
+
+ /**
+ * Gets the value of the starttime property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getStarttime() {
+ return starttime;
+ }
+
+ /**
+ * Sets the value of the starttime property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setStarttime(Duration value) {
+ this.starttime = value;
+ }
+
+ /**
+ * Gets the value of the duration property.
+ *
+ * @return
+ * possible object is
+ * {@link Duration }
+ *
+ */
+ public Duration getDuration() {
+ return duration;
+ }
+
+ /**
+ * Sets the value of the duration property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Duration }
+ *
+ */
+ public void setDuration(Duration value) {
+ this.duration = value;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/RepresentationBaseType.java b/common/src/main/java/ctbrec/recorder/download/dash/RepresentationBaseType.java
new file mode 100644
index 00000000..f28402f0
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/RepresentationBaseType.java
@@ -0,0 +1,723 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for RepresentationBaseType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="RepresentationBaseType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="FramePacking" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="AudioChannelConfiguration" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="ContentProtection" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="EssentialProperty" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="SupplementalProperty" type="{urn:mpeg:dash:schema:mpd:2011}DescriptorType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="InbandEventStream" type="{urn:mpeg:dash:schema:mpd:2011}EventStreamType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="Switching" type="{urn:mpeg:dash:schema:mpd:2011}SwitchingType" maxOccurs="unbounded" minOccurs="0"/>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="profiles" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="width" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * <attribute name="height" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * <attribute name="sar" type="{urn:mpeg:dash:schema:mpd:2011}RatioType" />
+ * <attribute name="frameRate" type="{urn:mpeg:dash:schema:mpd:2011}FrameRateType" />
+ * <attribute name="audioSamplingRate" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="mimeType" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="segmentProfiles" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="codecs" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="maximumSAPPeriod" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * <attribute name="startWithSAP" type="{urn:mpeg:dash:schema:mpd:2011}SAPType" />
+ * <attribute name="maxPlayoutRate" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * <attribute name="codingDependency" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+ * <attribute name="scanType" type="{urn:mpeg:dash:schema:mpd:2011}VideoScanType" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "RepresentationBaseType", propOrder = {
+ "framePacking",
+ "audioChannelConfiguration",
+ "contentProtection",
+ "essentialProperty",
+ "supplementalProperty",
+ "inbandEventStream",
+ "switching",
+ "any"
+})
+@XmlSeeAlso({
+ RepresentationType.class,
+ AdaptationSetType.class,
+ SubRepresentationType.class
+})
+public class RepresentationBaseType {
+
+ @XmlElement(name = "FramePacking")
+ protected List framePacking;
+ @XmlElement(name = "AudioChannelConfiguration")
+ protected List audioChannelConfiguration;
+ @XmlElement(name = "ContentProtection")
+ protected List contentProtection;
+ @XmlElement(name = "EssentialProperty")
+ protected List essentialProperty;
+ @XmlElement(name = "SupplementalProperty")
+ protected List supplementalProperty;
+ @XmlElement(name = "InbandEventStream")
+ protected List inbandEventStream;
+ @XmlElement(name = "Switching")
+ protected List switching;
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "profiles")
+ protected String profiles;
+ @XmlAttribute(name = "width")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long width;
+ @XmlAttribute(name = "height")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long height;
+ @XmlAttribute(name = "sar")
+ protected String sar;
+ @XmlAttribute(name = "frameRate")
+ protected String frameRate;
+ @XmlAttribute(name = "audioSamplingRate")
+ protected String audioSamplingRate;
+ @XmlAttribute(name = "mimeType")
+ protected String mimeType;
+ @XmlAttribute(name = "segmentProfiles")
+ protected String segmentProfiles;
+ @XmlAttribute(name = "codecs")
+ protected String codecs;
+ @XmlAttribute(name = "maximumSAPPeriod")
+ protected Double maximumSAPPeriod;
+ @XmlAttribute(name = "startWithSAP")
+ protected Long startWithSAP;
+ @XmlAttribute(name = "maxPlayoutRate")
+ protected Double maxPlayoutRate;
+ @XmlAttribute(name = "codingDependency")
+ protected Boolean codingDependency;
+ @XmlAttribute(name = "scanType")
+ protected VideoScanType scanType;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the framePacking property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the framePacking property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getFramePacking().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getFramePacking() {
+ if (framePacking == null) {
+ framePacking = new ArrayList();
+ }
+ return this.framePacking;
+ }
+
+ /**
+ * Gets the value of the audioChannelConfiguration property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the audioChannelConfiguration property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAudioChannelConfiguration().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getAudioChannelConfiguration() {
+ if (audioChannelConfiguration == null) {
+ audioChannelConfiguration = new ArrayList();
+ }
+ return this.audioChannelConfiguration;
+ }
+
+ /**
+ * Gets the value of the contentProtection property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the contentProtection property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getContentProtection().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getContentProtection() {
+ if (contentProtection == null) {
+ contentProtection = new ArrayList();
+ }
+ return this.contentProtection;
+ }
+
+ /**
+ * Gets the value of the essentialProperty property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the essentialProperty property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getEssentialProperty().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getEssentialProperty() {
+ if (essentialProperty == null) {
+ essentialProperty = new ArrayList();
+ }
+ return this.essentialProperty;
+ }
+
+ /**
+ * Gets the value of the supplementalProperty property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the supplementalProperty property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getSupplementalProperty().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DescriptorType }
+ *
+ *
+ */
+ public List getSupplementalProperty() {
+ if (supplementalProperty == null) {
+ supplementalProperty = new ArrayList();
+ }
+ return this.supplementalProperty;
+ }
+
+ /**
+ * Gets the value of the inbandEventStream property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the inbandEventStream property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getInbandEventStream().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link EventStreamType }
+ *
+ *
+ */
+ public List getInbandEventStream() {
+ if (inbandEventStream == null) {
+ inbandEventStream = new ArrayList();
+ }
+ return this.inbandEventStream;
+ }
+
+ /**
+ * Gets the value of the switching property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the switching property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getSwitching().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link SwitchingType }
+ *
+ *
+ */
+ public List getSwitching() {
+ if (switching == null) {
+ switching = new ArrayList();
+ }
+ return this.switching;
+ }
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the profiles property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getProfiles() {
+ return profiles;
+ }
+
+ /**
+ * Sets the value of the profiles property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setProfiles(String value) {
+ this.profiles = value;
+ }
+
+ /**
+ * Gets the value of the width property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getWidth() {
+ return width;
+ }
+
+ /**
+ * Sets the value of the width property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setWidth(Long value) {
+ this.width = value;
+ }
+
+ /**
+ * Gets the value of the height property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getHeight() {
+ return height;
+ }
+
+ /**
+ * Sets the value of the height property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setHeight(Long value) {
+ this.height = value;
+ }
+
+ /**
+ * Gets the value of the sar property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getSar() {
+ return sar;
+ }
+
+ /**
+ * Sets the value of the sar property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setSar(String value) {
+ this.sar = value;
+ }
+
+ /**
+ * Gets the value of the frameRate property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getFrameRate() {
+ return frameRate;
+ }
+
+ /**
+ * Sets the value of the frameRate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setFrameRate(String value) {
+ this.frameRate = value;
+ }
+
+ /**
+ * Gets the value of the audioSamplingRate property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getAudioSamplingRate() {
+ return audioSamplingRate;
+ }
+
+ /**
+ * Sets the value of the audioSamplingRate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setAudioSamplingRate(String value) {
+ this.audioSamplingRate = value;
+ }
+
+ /**
+ * Gets the value of the mimeType property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ /**
+ * Sets the value of the mimeType property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMimeType(String value) {
+ this.mimeType = value;
+ }
+
+ /**
+ * Gets the value of the segmentProfiles property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getSegmentProfiles() {
+ return segmentProfiles;
+ }
+
+ /**
+ * Sets the value of the segmentProfiles property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setSegmentProfiles(String value) {
+ this.segmentProfiles = value;
+ }
+
+ /**
+ * Gets the value of the codecs property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getCodecs() {
+ return codecs;
+ }
+
+ /**
+ * Sets the value of the codecs property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setCodecs(String value) {
+ this.codecs = value;
+ }
+
+ /**
+ * Gets the value of the maximumSAPPeriod property.
+ *
+ * @return
+ * possible object is
+ * {@link Double }
+ *
+ */
+ public Double getMaximumSAPPeriod() {
+ return maximumSAPPeriod;
+ }
+
+ /**
+ * Sets the value of the maximumSAPPeriod property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Double }
+ *
+ */
+ public void setMaximumSAPPeriod(Double value) {
+ this.maximumSAPPeriod = value;
+ }
+
+ /**
+ * Gets the value of the startWithSAP property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getStartWithSAP() {
+ return startWithSAP;
+ }
+
+ /**
+ * Sets the value of the startWithSAP property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setStartWithSAP(Long value) {
+ this.startWithSAP = value;
+ }
+
+ /**
+ * Gets the value of the maxPlayoutRate property.
+ *
+ * @return
+ * possible object is
+ * {@link Double }
+ *
+ */
+ public Double getMaxPlayoutRate() {
+ return maxPlayoutRate;
+ }
+
+ /**
+ * Sets the value of the maxPlayoutRate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Double }
+ *
+ */
+ public void setMaxPlayoutRate(Double value) {
+ this.maxPlayoutRate = value;
+ }
+
+ /**
+ * Gets the value of the codingDependency property.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public Boolean isCodingDependency() {
+ return codingDependency;
+ }
+
+ /**
+ * Sets the value of the codingDependency property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setCodingDependency(Boolean value) {
+ this.codingDependency = value;
+ }
+
+ /**
+ * Gets the value of the scanType property.
+ *
+ * @return
+ * possible object is
+ * {@link VideoScanType }
+ *
+ */
+ public VideoScanType getScanType() {
+ return scanType;
+ }
+
+ /**
+ * Sets the value of the scanType property.
+ *
+ * @param value
+ * allowed object is
+ * {@link VideoScanType }
+ *
+ */
+ public void setScanType(VideoScanType value) {
+ this.scanType = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/RepresentationType.java b/common/src/main/java/ctbrec/recorder/download/dash/RepresentationType.java
new file mode 100644
index 00000000..abcb5077
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/RepresentationType.java
@@ -0,0 +1,337 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * Java class for RepresentationType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="RepresentationType">
+ * <complexContent>
+ * <extension base="{urn:mpeg:dash:schema:mpd:2011}RepresentationBaseType">
+ * <sequence>
+ * <element name="BaseURL" type="{urn:mpeg:dash:schema:mpd:2011}BaseURLType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="SubRepresentation" type="{urn:mpeg:dash:schema:mpd:2011}SubRepresentationType" maxOccurs="unbounded" minOccurs="0"/>
+ * <element name="SegmentBase" type="{urn:mpeg:dash:schema:mpd:2011}SegmentBaseType" minOccurs="0"/>
+ * <element name="SegmentList" type="{urn:mpeg:dash:schema:mpd:2011}SegmentListType" minOccurs="0"/>
+ * <element name="SegmentTemplate" type="{urn:mpeg:dash:schema:mpd:2011}SegmentTemplateType" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="id" use="required" type="{urn:mpeg:dash:schema:mpd:2011}StringNoWhitespaceType" />
+ * <attribute name="bandwidth" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * <attribute name="qualityRanking" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * <attribute name="dependencyId" type="{urn:mpeg:dash:schema:mpd:2011}StringVectorType" />
+ * <attribute name="mediaStreamStructureId" type="{urn:mpeg:dash:schema:mpd:2011}StringVectorType" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "RepresentationType", propOrder = {
+ "baseURL",
+ "subRepresentation",
+ "segmentBase",
+ "segmentList",
+ "segmentTemplate"
+})
+public class RepresentationType
+ extends RepresentationBaseType
+{
+
+ @XmlElement(name = "BaseURL")
+ protected List baseURL;
+ @XmlElement(name = "SubRepresentation")
+ protected List subRepresentation;
+ @XmlElement(name = "SegmentBase")
+ protected SegmentBaseType segmentBase;
+ @XmlElement(name = "SegmentList")
+ protected SegmentListType segmentList;
+ @XmlElement(name = "SegmentTemplate")
+ protected SegmentTemplateType segmentTemplate;
+ @XmlAttribute(name = "id", required = true)
+ protected String id;
+ @XmlAttribute(name = "bandwidth", required = true)
+ @XmlSchemaType(name = "unsignedInt")
+ protected long bandwidth;
+ @XmlAttribute(name = "qualityRanking")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long qualityRanking;
+ @XmlAttribute(name = "dependencyId")
+ protected List dependencyId;
+ @XmlAttribute(name = "mediaStreamStructureId")
+ protected List mediaStreamStructureId;
+
+ /**
+ * Gets the value of the baseURL property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the baseURL property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getBaseURL().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link BaseURLType }
+ *
+ *
+ */
+ public List getBaseURL() {
+ if (baseURL == null) {
+ baseURL = new ArrayList();
+ }
+ return this.baseURL;
+ }
+
+ /**
+ * Gets the value of the subRepresentation property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the subRepresentation property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getSubRepresentation().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link SubRepresentationType }
+ *
+ *
+ */
+ public List getSubRepresentation() {
+ if (subRepresentation == null) {
+ subRepresentation = new ArrayList();
+ }
+ return this.subRepresentation;
+ }
+
+ /**
+ * Gets the value of the segmentBase property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentBaseType }
+ *
+ */
+ public SegmentBaseType getSegmentBase() {
+ return segmentBase;
+ }
+
+ /**
+ * Sets the value of the segmentBase property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentBaseType }
+ *
+ */
+ public void setSegmentBase(SegmentBaseType value) {
+ this.segmentBase = value;
+ }
+
+ /**
+ * Gets the value of the segmentList property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentListType }
+ *
+ */
+ public SegmentListType getSegmentList() {
+ return segmentList;
+ }
+
+ /**
+ * Sets the value of the segmentList property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentListType }
+ *
+ */
+ public void setSegmentList(SegmentListType value) {
+ this.segmentList = value;
+ }
+
+ /**
+ * Gets the value of the segmentTemplate property.
+ *
+ * @return
+ * possible object is
+ * {@link SegmentTemplateType }
+ *
+ */
+ public SegmentTemplateType getSegmentTemplate() {
+ return segmentTemplate;
+ }
+
+ /**
+ * Sets the value of the segmentTemplate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link SegmentTemplateType }
+ *
+ */
+ public void setSegmentTemplate(SegmentTemplateType value) {
+ this.segmentTemplate = value;
+ }
+
+ /**
+ * Gets the value of the id property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Sets the value of the id property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setId(String value) {
+ this.id = value;
+ }
+
+ /**
+ * Gets the value of the bandwidth property.
+ *
+ */
+ public long getBandwidth() {
+ return bandwidth;
+ }
+
+ /**
+ * Sets the value of the bandwidth property.
+ *
+ */
+ public void setBandwidth(long value) {
+ this.bandwidth = value;
+ }
+
+ /**
+ * Gets the value of the qualityRanking property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getQualityRanking() {
+ return qualityRanking;
+ }
+
+ /**
+ * Sets the value of the qualityRanking property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setQualityRanking(Long value) {
+ this.qualityRanking = value;
+ }
+
+ /**
+ * Gets the value of the dependencyId property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the dependencyId property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getDependencyId().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link String }
+ *
+ *
+ */
+ public List getDependencyId() {
+ if (dependencyId == null) {
+ dependencyId = new ArrayList();
+ }
+ return this.dependencyId;
+ }
+
+ /**
+ * Gets the value of the mediaStreamStructureId property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the mediaStreamStructureId property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getMediaStreamStructureId().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link String }
+ *
+ *
+ */
+ public List getMediaStreamStructureId() {
+ if (mediaStreamStructureId == null) {
+ mediaStreamStructureId = new ArrayList();
+ }
+ return this.mediaStreamStructureId;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/SegmentBaseType.java b/common/src/main/java/ctbrec/recorder/download/dash/SegmentBaseType.java
new file mode 100644
index 00000000..ca8a3011
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/SegmentBaseType.java
@@ -0,0 +1,335 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for SegmentBaseType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="SegmentBaseType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="Initialization" type="{urn:mpeg:dash:schema:mpd:2011}URLType" minOccurs="0"/>
+ * <element name="RepresentationIndex" type="{urn:mpeg:dash:schema:mpd:2011}URLType" minOccurs="0"/>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="timescale" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
+ * <attribute name="presentationTimeOffset" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" />
+ * <attribute name="indexRange" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="indexRangeExact" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+ * <attribute name="availabilityTimeOffset" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * <attribute name="availabilityTimeComplete" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "SegmentBaseType", propOrder = {
+ "initialization",
+ "representationIndex",
+ "any"
+})
+@XmlSeeAlso({
+ MultipleSegmentBaseType.class
+})
+public class SegmentBaseType {
+
+ @XmlElement(name = "Initialization")
+ protected URLType initialization;
+ @XmlElement(name = "RepresentationIndex")
+ protected URLType representationIndex;
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAttribute(name = "timescale")
+ @XmlSchemaType(name = "unsignedInt")
+ protected Long timescale;
+ @XmlAttribute(name = "presentationTimeOffset")
+ @XmlSchemaType(name = "unsignedLong")
+ protected BigInteger presentationTimeOffset;
+ @XmlAttribute(name = "indexRange")
+ protected String indexRange;
+ @XmlAttribute(name = "indexRangeExact")
+ protected Boolean indexRangeExact;
+ @XmlAttribute(name = "availabilityTimeOffset")
+ protected Double availabilityTimeOffset;
+ @XmlAttribute(name = "availabilityTimeComplete")
+ protected Boolean availabilityTimeComplete;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the initialization property.
+ *
+ * @return
+ * possible object is
+ * {@link URLType }
+ *
+ */
+ public URLType getInitialization() {
+ return initialization;
+ }
+
+ /**
+ * Sets the value of the initialization property.
+ *
+ * @param value
+ * allowed object is
+ * {@link URLType }
+ *
+ */
+ public void setInitialization(URLType value) {
+ this.initialization = value;
+ }
+
+ /**
+ * Gets the value of the representationIndex property.
+ *
+ * @return
+ * possible object is
+ * {@link URLType }
+ *
+ */
+ public URLType getRepresentationIndex() {
+ return representationIndex;
+ }
+
+ /**
+ * Sets the value of the representationIndex property.
+ *
+ * @param value
+ * allowed object is
+ * {@link URLType }
+ *
+ */
+ public void setRepresentationIndex(URLType value) {
+ this.representationIndex = value;
+ }
+
+ /**
+ * Gets the value of the any property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the any property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getAny().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link Element }
+ * {@link Object }
+ *
+ *
+ */
+ public List getAny() {
+ if (any == null) {
+ any = new ArrayList();
+ }
+ return this.any;
+ }
+
+ /**
+ * Gets the value of the timescale property.
+ *
+ * @return
+ * possible object is
+ * {@link Long }
+ *
+ */
+ public Long getTimescale() {
+ return timescale;
+ }
+
+ /**
+ * Sets the value of the timescale property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Long }
+ *
+ */
+ public void setTimescale(Long value) {
+ this.timescale = value;
+ }
+
+ /**
+ * Gets the value of the presentationTimeOffset property.
+ *
+ * @return
+ * possible object is
+ * {@link BigInteger }
+ *
+ */
+ public BigInteger getPresentationTimeOffset() {
+ return presentationTimeOffset;
+ }
+
+ /**
+ * Sets the value of the presentationTimeOffset property.
+ *
+ * @param value
+ * allowed object is
+ * {@link BigInteger }
+ *
+ */
+ public void setPresentationTimeOffset(BigInteger value) {
+ this.presentationTimeOffset = value;
+ }
+
+ /**
+ * Gets the value of the indexRange property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getIndexRange() {
+ return indexRange;
+ }
+
+ /**
+ * Sets the value of the indexRange property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setIndexRange(String value) {
+ this.indexRange = value;
+ }
+
+ /**
+ * Gets the value of the indexRangeExact property.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public boolean isIndexRangeExact() {
+ if (indexRangeExact == null) {
+ return false;
+ } else {
+ return indexRangeExact;
+ }
+ }
+
+ /**
+ * Sets the value of the indexRangeExact property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setIndexRangeExact(Boolean value) {
+ this.indexRangeExact = value;
+ }
+
+ /**
+ * Gets the value of the availabilityTimeOffset property.
+ *
+ * @return
+ * possible object is
+ * {@link Double }
+ *
+ */
+ public Double getAvailabilityTimeOffset() {
+ return availabilityTimeOffset;
+ }
+
+ /**
+ * Sets the value of the availabilityTimeOffset property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Double }
+ *
+ */
+ public void setAvailabilityTimeOffset(Double value) {
+ this.availabilityTimeOffset = value;
+ }
+
+ /**
+ * Gets the value of the availabilityTimeComplete property.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public Boolean isAvailabilityTimeComplete() {
+ return availabilityTimeComplete;
+ }
+
+ /**
+ * Sets the value of the availabilityTimeComplete property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setAvailabilityTimeComplete(Boolean value) {
+ this.availabilityTimeComplete = value;
+ }
+
+ /**
+ * Gets a map that contains attributes that aren't bound to any typed property on this class.
+ *
+ *
+ * the map is keyed by the name of the attribute and
+ * the value is the string value of the attribute.
+ *
+ * the map returned by this method is live, and you can add new attribute
+ * by updating the map directly. Because of this design, there's no setter.
+ *
+ *
+ * @return
+ * always non-null
+ */
+ public Map getOtherAttributes() {
+ return otherAttributes;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/SegmentListType.java b/common/src/main/java/ctbrec/recorder/download/dash/SegmentListType.java
new file mode 100644
index 00000000..4039478d
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/SegmentListType.java
@@ -0,0 +1,138 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * Java class for SegmentListType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="SegmentListType">
+ * <complexContent>
+ * <extension base="{urn:mpeg:dash:schema:mpd:2011}MultipleSegmentBaseType">
+ * <sequence>
+ * <element name="SegmentURL" type="{urn:mpeg:dash:schema:mpd:2011}SegmentURLType" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <attribute ref="{http://www.w3.org/1999/xlink}href"/>
+ * <attribute ref="{http://www.w3.org/1999/xlink}actuate"/>
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "SegmentListType", propOrder = {
+ "segmentURL"
+})
+public class SegmentListType
+ extends MultipleSegmentBaseType
+{
+
+ @XmlElement(name = "SegmentURL")
+ protected List segmentURL;
+ @XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
+ protected String href;
+ @XmlAttribute(name = "actuate", namespace = "http://www.w3.org/1999/xlink")
+ protected ActuateType actuate;
+
+ /**
+ * Gets the value of the segmentURL property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the segmentURL property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getSegmentURL().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link SegmentURLType }
+ *
+ *
+ */
+ public List getSegmentURL() {
+ if (segmentURL == null) {
+ segmentURL = new ArrayList();
+ }
+ return this.segmentURL;
+ }
+
+ /**
+ * Gets the value of the href property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getHref() {
+ return href;
+ }
+
+ /**
+ * Sets the value of the href property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setHref(String value) {
+ this.href = value;
+ }
+
+ /**
+ * Gets the value of the actuate property.
+ *
+ * @return
+ * possible object is
+ * {@link ActuateType }
+ *
+ */
+ public ActuateType getActuate() {
+ if (actuate == null) {
+ return ActuateType.ON_REQUEST;
+ } else {
+ return actuate;
+ }
+ }
+
+ /**
+ * Sets the value of the actuate property.
+ *
+ * @param value
+ * allowed object is
+ * {@link ActuateType }
+ *
+ */
+ public void setActuate(ActuateType value) {
+ this.actuate = value;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/SegmentTemplateType.java b/common/src/main/java/ctbrec/recorder/download/dash/SegmentTemplateType.java
new file mode 100644
index 00000000..f7c3220b
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/SegmentTemplateType.java
@@ -0,0 +1,149 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * Java class for SegmentTemplateType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="SegmentTemplateType">
+ * <complexContent>
+ * <extension base="{urn:mpeg:dash:schema:mpd:2011}MultipleSegmentBaseType">
+ * <attribute name="media" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="index" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="initialization" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="bitstreamSwitching" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "SegmentTemplateType")
+public class SegmentTemplateType
+ extends MultipleSegmentBaseType
+{
+
+ @XmlAttribute(name = "media")
+ protected String media;
+ @XmlAttribute(name = "index")
+ protected String index;
+ @XmlAttribute(name = "initialization")
+ protected String initializationAttribute;
+ @XmlAttribute(name = "bitstreamSwitching")
+ protected String bitstreamSwitchingAttribute;
+
+ /**
+ * Gets the value of the media property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMedia() {
+ return media;
+ }
+
+ /**
+ * Sets the value of the media property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMedia(String value) {
+ this.media = value;
+ }
+
+ /**
+ * Gets the value of the index property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getIndex() {
+ return index;
+ }
+
+ /**
+ * Sets the value of the index property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setIndex(String value) {
+ this.index = value;
+ }
+
+ /**
+ * Gets the value of the initializationAttribute property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getInitializationAttribute() {
+ return initializationAttribute;
+ }
+
+ /**
+ * Sets the value of the initializationAttribute property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setInitializationAttribute(String value) {
+ this.initializationAttribute = value;
+ }
+
+ /**
+ * Gets the value of the bitstreamSwitchingAttribute property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getBitstreamSwitchingAttribute() {
+ return bitstreamSwitchingAttribute;
+ }
+
+ /**
+ * Sets the value of the bitstreamSwitchingAttribute property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setBitstreamSwitchingAttribute(String value) {
+ this.bitstreamSwitchingAttribute = value;
+ }
+
+}
diff --git a/common/src/main/java/ctbrec/recorder/download/dash/SegmentTimelineType.java b/common/src/main/java/ctbrec/recorder/download/dash/SegmentTimelineType.java
new file mode 100644
index 00000000..d9cc9e9c
--- /dev/null
+++ b/common/src/main/java/ctbrec/recorder/download/dash/SegmentTimelineType.java
@@ -0,0 +1,312 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2019.08.24 at 05:06:14 PM CEST
+//
+
+
+package ctbrec.recorder.download.dash;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
+
+/**
+ * Java class for SegmentTimelineType complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType name="SegmentTimelineType">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="S" maxOccurs="unbounded">
+ * <complexType>
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <attribute name="t" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" />
+ * <attribute name="n" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" />
+ * <attribute name="d" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" />
+ * <attribute name="r" type="{http://www.w3.org/2001/XMLSchema}integer" default="0" />
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </element>
+ * <any processContents='lax' namespace='##other' maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * <anyAttribute processContents='lax' namespace='##other'/>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "SegmentTimelineType", propOrder = {
+ "s",
+ "any"
+})
+public class SegmentTimelineType {
+
+ @XmlElement(name = "S", required = true)
+ protected List s;
+ @XmlAnyElement(lax = true)
+ protected List any;
+ @XmlAnyAttribute
+ private Map otherAttributes = new HashMap();
+
+ /**
+ * Gets the value of the s property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the s property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getS().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link SegmentTimelineType.S }
+ *
+ *
+ */
+ public List getS() {
+ if (s == null) {
+ s = new ArrayList();
+ }
+ return this.s;
+ }
+
+ /**
+ * Gets the value of the any property.
+ *
+ *