From 54279504bb190031a73129e2c8e25cd24e0cd8f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fl=C3=A1vio=20Ribeiro?= <email@flavioribeiro.com>
Date: Thu, 31 Oct 2019 19:42:33 -0400
Subject: [PATCH 01/32] return element name unrecognized in adaptation set

---
 mpd/mpd.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mpd/mpd.go b/mpd/mpd.go
index e490abb..9fc11f2 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -236,7 +236,7 @@ func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
 				}
 				representations = append(representations, rp)
 			default:
-				return errors.New("Unrecognized element in AdaptationSet")
+				return errors.New("Unrecognized element in AdaptationSet: " + tt.Name.Local)
 			}
 		case xml.EndElement:
 			if tt == start.End() {

From b6bd25ebaa21ff6a5a42fc059decf0ce480aed03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fl=C3=A1vio=20Ribeiro?= <email@flavioribeiro.com>
Date: Thu, 31 Oct 2019 20:11:48 -0400
Subject: [PATCH 02/32] extend elements in adaptation set to cover
 accessibility elements

---
 mpd/mpd.go | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/mpd/mpd.go b/mpd/mpd.go
index 9fc11f2..ba5b670 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -235,6 +235,12 @@ func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
 					return err
 				}
 				representations = append(representations, rp)
+			case "Accessibility":
+				ac := new(Accessibility)
+				err = d.DecodeElement(ac, &tt)
+				if err != nil {
+					return err
+				}
 			default:
 				return errors.New("Unrecognized element in AdaptationSet: " + tt.Name.Local)
 			}
@@ -430,6 +436,11 @@ type Representation struct {
 	SegmentTemplate           *SegmentTemplate           `xml:"SegmentTemplate,omitempty"`
 }
 
+type Accessibility struct {
+	SchemeIdUri *string `xml:"schemeIdUri,omitempty"`
+	Value       *int64  `xml:"value,omitempty"`
+}
+
 type AudioChannelConfiguration struct {
 	SchemeIDURI *string `xml:"schemeIdUri,attr"`
 	// Value will be an int for non-Dolby Schemes, and a hexstring for Dolby Schemes, hence we make it a string

From 22110e3d53509673b8438f4cdfe017b12a1089ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fl=C3=A1vio=20Ribeiro?= <email@flavioribeiro.com>
Date: Thu, 19 Dec 2019 13:57:09 -0300
Subject: [PATCH 03/32] mpd: support float durations for SegmentTemplate

---
 mpd/mpd.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mpd/mpd.go b/mpd/mpd.go
index 42d5658..a19850e 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -417,7 +417,7 @@ type SegmentTemplate struct {
 	AdaptationSet          *AdaptationSet   `xml:"-"`
 	SegmentTimeline        *SegmentTimeline `xml:"SegmentTimeline,omitempty"`
 	PresentationTimeOffset *uint64          `xml:"presentationTimeOffset,attr,omitempty"`
-	Duration               *int64           `xml:"duration,attr"`
+	Duration               *float64         `xml:"duration,attr"`
 	Initialization         *string          `xml:"initialization,attr"`
 	Media                  *string          `xml:"media,attr"`
 	StartNumber            *int64           `xml:"startNumber,attr"`
@@ -934,9 +934,9 @@ func (as *AdaptationSet) AddContentProtection(cp ContentProtectioner) error {
 // media - template string for media segments.
 // startNumber - the number to start segments from ($Number$) (i.e. 0).
 // timescale - sets the timescale for duration (i.e. 1000, represents milliseconds).
-func (as *AdaptationSet) SetNewSegmentTemplate(duration int64, init string, media string, startNumber int64, timescale int64) (*SegmentTemplate, error) {
+func (as *AdaptationSet) SetNewSegmentTemplate(duration float64, init string, media string, startNumber int64, timescale int64) (*SegmentTemplate, error) {
 	st := &SegmentTemplate{
-		Duration:       Int64ptr(duration),
+		Duration:       Float64ptr(duration),
 		Initialization: Strptr(init),
 		Media:          Strptr(media),
 		StartNumber:    Int64ptr(startNumber),

From 7cf0e9b0802ea25b24bf9188806924c68b3eea04 Mon Sep 17 00:00:00 2001
From: Krystal Mejia <krystalmejia24@users.noreply.github.com>
Date: Fri, 14 Feb 2020 08:34:54 -0500
Subject: [PATCH 04/32] essential property should be an Element not an
 attribute (#4)

---
 mpd/mpd.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mpd/mpd.go b/mpd/mpd.go
index 1b6551f..1e0c245 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -119,7 +119,7 @@ type CommonAttributesAndElements struct {
 	FramePacking              *DescriptorType       `xml:"framePacking,attr"`
 	AudioChannelConfiguration *DescriptorType       `xml:"audioChannelConfiguration,attr"`
 	ContentProtection         []ContentProtectioner `xml:"ContentProtection,omitempty"`
-	EssentialProperty         *DescriptorType       `xml:"essentialProperty,attr"`
+	EssentialProperty         *DescriptorType       `xml:"EssentialProperty,omitempty"`
 	SupplementalProperty      *DescriptorType       `xml:"supplmentalProperty,attr"`
 	InbandEventStream         *DescriptorType       `xml:"inbandEventStream,attr"`
 }

From c978edf9d310d2c5bff7c89e86d50b289020ad46 Mon Sep 17 00:00:00 2001
From: Krystal Mejia <krystalmejia24@users.noreply.github.com>
Date: Mon, 9 Mar 2020 13:40:59 -0400
Subject: [PATCH 05/32] adding accessibility element for unmarshalling
 adaptation sets (#6)

---
 mpd/mpd.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/mpd/mpd.go b/mpd/mpd.go
index 1e0c245..e2f9dfb 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -181,6 +181,7 @@ func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
 		segmentList           *SegmentList
 		segmentTemplate       *SegmentTemplate
 		representations       []*Representation
+		accessibility         []*Accessibility
 	)
 
 	// decode inner elements
@@ -261,6 +262,7 @@ func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
 				if err != nil {
 					return err
 				}
+				accessibility = append(accessibility, ac)
 			default:
 				return fmt.Errorf("unrecognized element in AdaptationSet %q", tt.Name.Local)
 			}
@@ -274,6 +276,7 @@ func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
 				as.SegmentList = segmentList
 				as.SegmentTemplate = segmentTemplate
 				as.Representations = representations
+				as.AccessibilityElems = accessibility
 				return nil
 			}
 		}

From dcd6d6a37ebe1252dab7b8fd890dabc853b3bf6a Mon Sep 17 00:00:00 2001
From: Krystal Mejia <krystalmejia24@users.noreply.github.com>
Date: Tue, 17 Mar 2020 17:52:58 -0400
Subject: [PATCH 06/32] sync upstream (#7)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* add support for EventStreams

* no slice of pointers

* add MPD@Location

* add test for MPD@Location

* remove unnecessary ptrs import

* Fix DescriptorTypes

* Demonstate multiple descriptor types

* extend elements in adaptation set to cover accessibility elements

* Remove crazy nested Unmarshal

* hmm swear sliceds of nils were giving me trouble earlier

* Include DRM with Adapatationset switching & correct order by removing ContentProtection from AdaptationSet

Co-authored-by: Matthew Neil <mjneil@users.noreply.github.com>
Co-authored-by: Robert Peck <rpeck@brightcove.com>
Co-authored-by: Flávio Ribeiro <email@flavioribeiro.com>
---
 mpd/events.go                                |  18 ++
 mpd/events_test.go                           |  66 ++++++
 mpd/fixtures/adaptationset_switching.mpd     |  49 ++++
 mpd/fixtures/audio_channel_configuration.mpd |  23 ++
 mpd/fixtures/events.mpd                      |  10 +
 mpd/fixtures/location.mpd                    |   4 +
 mpd/fixtures/multiple_supplementals.mpd      |  37 +++
 mpd/mpd.go                                   | 231 ++++++-------------
 mpd/mpd_test.go                              |  42 ++++
 9 files changed, 323 insertions(+), 157 deletions(-)
 create mode 100644 mpd/events.go
 create mode 100644 mpd/events_test.go
 create mode 100644 mpd/fixtures/adaptationset_switching.mpd
 create mode 100644 mpd/fixtures/audio_channel_configuration.mpd
 create mode 100644 mpd/fixtures/events.mpd
 create mode 100644 mpd/fixtures/location.mpd
 create mode 100644 mpd/fixtures/multiple_supplementals.mpd

diff --git a/mpd/events.go b/mpd/events.go
new file mode 100644
index 0000000..ef7b981
--- /dev/null
+++ b/mpd/events.go
@@ -0,0 +1,18 @@
+package mpd
+
+import "encoding/xml"
+
+type EventStream struct {
+	XMLName     xml.Name `xml:"EventStream"`
+	SchemeIDURI *string  `xml:"schemeIdUri,attr"`
+	Value       *string  `xml:"value,attr,omitempty"`
+	Timescale   *int64   `xml:"timescale,attr"`
+	Events      []Event  `xml:"Event,omitempty"`
+}
+
+type Event struct {
+	XMLName          xml.Name `xml:"Event"`
+	ID               *string  `xml:"id,attr,omitempty"`
+	PresentationTime *int64   `xml:"presentationTime,attr,omitempty"`
+	Duration         *int64   `xml:"duration,attr,omitempty"`
+}
diff --git a/mpd/events_test.go b/mpd/events_test.go
new file mode 100644
index 0000000..1c75d30
--- /dev/null
+++ b/mpd/events_test.go
@@ -0,0 +1,66 @@
+package mpd
+
+import (
+	"testing"
+
+	"github.com/zencoder/go-dash/helpers/ptrs"
+	"github.com/zencoder/go-dash/helpers/require"
+	"github.com/zencoder/go-dash/helpers/testfixtures"
+)
+
+const (
+	VALID_EVENT_STREAM_SCHEME_ID_URI       = "urn:example:eventstream"
+	VALID_EVENT_STREAM_VALUE               = "eventstream"
+	VALID_EVENT_STREAM_TIMESCALE     int64 = 10
+)
+
+func newEventStreamMPD() *MPD {
+	m := NewDynamicMPD(
+		DASH_PROFILE_LIVE,
+		VALID_AVAILABILITY_START_TIME,
+		VALID_MIN_BUFFER_TIME,
+	)
+	p := m.GetCurrentPeriod()
+
+	es := EventStream{
+		SchemeIDURI: ptrs.Strptr(VALID_EVENT_STREAM_SCHEME_ID_URI),
+		Value:       ptrs.Strptr(VALID_EVENT_STREAM_VALUE),
+		Timescale:   ptrs.Int64ptr(VALID_EVENT_STREAM_TIMESCALE),
+	}
+
+	e0 := Event{
+		ID:               ptrs.Strptr("event-0"),
+		PresentationTime: ptrs.Int64ptr(100),
+		Duration:         ptrs.Int64ptr(50),
+	}
+
+	e1 := Event{
+		ID:               ptrs.Strptr("event-1"),
+		PresentationTime: ptrs.Int64ptr(200),
+		Duration:         ptrs.Int64ptr(50),
+	}
+
+	es.Events = append(es.Events, e0, e1)
+	p.EventStreams = append(p.EventStreams, es)
+
+	return m
+}
+
+func TestEventStreamsWriteToString(t *testing.T) {
+	m := newEventStreamMPD()
+
+	got, err := m.WriteToString()
+	require.NoError(t, err)
+
+	testfixtures.CompareFixture(t, "fixtures/events.mpd", got)
+}
+
+func TestReadEventStreams(t *testing.T) {
+	m, err := ReadFromFile("fixtures/events.mpd")
+	require.NoError(t, err)
+
+	got, err := m.WriteToString()
+	require.NoError(t, err)
+
+	testfixtures.CompareFixture(t, "fixtures/events.mpd", got)
+}
diff --git a/mpd/fixtures/adaptationset_switching.mpd b/mpd/fixtures/adaptationset_switching.mpd
new file mode 100644
index 0000000..05c61a4
--- /dev/null
+++ b/mpd/fixtures/adaptationset_switching.mpd
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" mediaPresentationDuration="PT30.016S" minBufferTime="PT2.000S">
+  <Period>
+    <BaseURL>http://localhost:8002/dash/</BaseURL>
+    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="1" segmentAlignment="true" lang="English">
+      <AudioChannelConfiguration></AudioChannelConfiguration>
+      <Representation audioSamplingRate="48000" bandwidth="255000" codecs="mp4a.40.2" id="audio_1">
+        <SegmentList timescale="48000" duration="479232">
+          <Initialization sourceURL="b4324d65-ad06-4735-9535-5cd4af84ebb6/dcb11457-9092-4410-b204-67b3c6d9a9e2/init.m4f"></Initialization>
+          <SegmentURL media="b4324d65-ad06-4735-9535-5cd4af84ebb6/dcb11457-9092-4410-b204-67b3c6d9a9e2/segment0.m4f"></SegmentURL>
+        </SegmentList>
+      </Representation>
+    </AdaptationSet>
+    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="2" segmentAlignment="true">
+      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
+        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+      </ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
+        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
+        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+      </ContentProtection>
+      <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="3"></SupplementalProperty>
+      <Representation bandwidth="4172274" codecs="avc1.640028" frameRate="30000/1001" height="720" id="video_1" width="1280">
+        <SegmentList timescale="30000" duration="225120">
+          <Initialization sourceURL="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/init.m4f"></Initialization>
+          <SegmentURL media="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/segment0.m4f"></SegmentURL>
+        </SegmentList>
+      </Representation>
+    </AdaptationSet>
+    <AdaptationSet mimeType="video/hevc" startWithSAP="1" scanType="progressive" id="3" segmentAlignment="true">
+      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
+        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+      </ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
+        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
+        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+      </ContentProtection>
+      <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="2"></SupplementalProperty>
+      <Representation bandwidth="4172274" codecs="avc1.640028" frameRate="30000/1001" height="720" id="video_1" width="1280">
+        <SegmentList timescale="30000" duration="225120">
+          <Initialization sourceURL="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/init.m4f"></Initialization>
+          <SegmentURL media="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/segment0.m4f"></SegmentURL>
+        </SegmentList>
+      </Representation>
+    </AdaptationSet>
+  </Period>
+</MPD>
diff --git a/mpd/fixtures/audio_channel_configuration.mpd b/mpd/fixtures/audio_channel_configuration.mpd
new file mode 100644
index 0000000..18c7544
--- /dev/null
+++ b/mpd/fixtures/audio_channel_configuration.mpd
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" mediaPresentationDuration="PT30.016S" minBufferTime="PT2.000S">
+  <Period>
+    <BaseURL>http://localhost:8002/dash/</BaseURL>
+    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="1" segmentAlignment="true" lang="English">
+      <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"></AudioChannelConfiguration>
+      <Representation audioSamplingRate="48000" bandwidth="255000" codecs="mp4a.40.2" id="audio_1">
+        <SegmentList timescale="48000" duration="479232">
+          <Initialization sourceURL="b4324d65-ad06-4735-9535-5cd4af84ebb6/dcb11457-9092-4410-b204-67b3c6d9a9e2/init.m4f"></Initialization>
+          <SegmentURL media="b4324d65-ad06-4735-9535-5cd4af84ebb6/dcb11457-9092-4410-b204-67b3c6d9a9e2/segment0.m4f"></SegmentURL>
+        </SegmentList>
+      </Representation>
+    </AdaptationSet>
+    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="2" segmentAlignment="true">
+      <Representation bandwidth="4172274" codecs="avc1.640028" frameRate="30000/1001" height="720" id="video_1" width="1280">
+        <SegmentList timescale="30000" duration="225120">
+          <Initialization sourceURL="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/init.m4f"></Initialization>
+          <SegmentURL media="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/segment0.m4f"></SegmentURL>
+        </SegmentList>
+      </Representation>
+    </AdaptationSet>
+  </Period>
+</MPD>
diff --git a/mpd/fixtures/events.mpd b/mpd/fixtures/events.mpd
new file mode 100644
index 0000000..b54d314
--- /dev/null
+++ b/mpd/fixtures/events.mpd
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic" minBufferTime="PT1.97S" availabilityStartTime="1970-01-01T00:00:00Z">
+  <Period>
+    <EventStream schemeIdUri="urn:example:eventstream" value="eventstream" timescale="10">
+      <Event id="event-0" presentationTime="100" duration="50"></Event>
+      <Event id="event-1" presentationTime="200" duration="50"></Event>
+    </EventStream>
+  </Period>
+  <UTCTiming></UTCTiming>
+</MPD>
diff --git a/mpd/fixtures/location.mpd b/mpd/fixtures/location.mpd
new file mode 100644
index 0000000..2d1bff6
--- /dev/null
+++ b/mpd/fixtures/location.mpd
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z" minimumUpdatePeriod="PT5S" publishTime="1970-01-01T00:00:00Z">
+  <Location>https://example.com/location.mpd</Location>
+</MPD>
diff --git a/mpd/fixtures/multiple_supplementals.mpd b/mpd/fixtures/multiple_supplementals.mpd
new file mode 100644
index 0000000..c7e2987
--- /dev/null
+++ b/mpd/fixtures/multiple_supplementals.mpd
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" mediaPresentationDuration="PT30.016S" minBufferTime="PT2.000S">
+  <Period>
+    <BaseURL>http://localhost:8002/dash/</BaseURL>
+    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="1" segmentAlignment="true" lang="English">
+      <AudioChannelConfiguration></AudioChannelConfiguration>
+      <Representation audioSamplingRate="48000" bandwidth="255000" codecs="mp4a.40.2" id="audio_1">
+        <SegmentList timescale="48000" duration="479232">
+          <Initialization sourceURL="b4324d65-ad06-4735-9535-5cd4af84ebb6/dcb11457-9092-4410-b204-67b3c6d9a9e2/init.m4f"></Initialization>
+          <SegmentURL media="b4324d65-ad06-4735-9535-5cd4af84ebb6/dcb11457-9092-4410-b204-67b3c6d9a9e2/segment0.m4f"></SegmentURL>
+        </SegmentList>
+      </Representation>
+    </AdaptationSet>
+    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="2" segmentAlignment="true">
+      <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="3"></SupplementalProperty>
+      <SupplementalProperty schemeIdUri="a" value="1"></SupplementalProperty>
+      <SupplementalProperty schemeIdUri="b" value="2"></SupplementalProperty>
+      <Representation bandwidth="4172274" codecs="avc1.640028" frameRate="30000/1001" height="720" id="video_1" width="1280">
+        <SegmentList timescale="30000" duration="225120">
+          <Initialization sourceURL="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/init.m4f"></Initialization>
+          <SegmentURL media="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/segment0.m4f"></SegmentURL>
+        </SegmentList>
+      </Representation>
+    </AdaptationSet>
+    <AdaptationSet mimeType="video/hevc" startWithSAP="1" scanType="progressive" id="3" segmentAlignment="true">
+      <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="2"></SupplementalProperty>
+      <SupplementalProperty schemeIdUri="c" value="3"></SupplementalProperty>
+      <SupplementalProperty schemeIdUri="d" value="4"></SupplementalProperty>
+      <Representation bandwidth="4172274" codecs="avc1.640028" frameRate="30000/1001" height="720" id="video_1" width="1280">
+        <SegmentList timescale="30000" duration="225120">
+          <Initialization sourceURL="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/init.m4f"></Initialization>
+          <SegmentURL media="b4324d65-ad06-4735-9535-5cd4af84ebb6/f2ad47b2-5362-46e6-ad1d-dff7b10f00b8/segment0.m4f"></SegmentURL>
+        </SegmentList>
+      </Representation>
+    </AdaptationSet>
+  </Period>
+</MPD>
diff --git a/mpd/mpd.go b/mpd/mpd.go
index e2f9dfb..df4f52a 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -5,7 +5,6 @@ import (
 	"encoding/hex"
 	"encoding/xml"
 	"errors"
-	"fmt"
 	"strings"
 	"time"
 
@@ -79,6 +78,7 @@ type MPD struct {
 	TimeShiftBufferDepth       *string   `xml:"timeShiftBufferDepth,attr"`
 	SuggestedPresentationDelay *Duration `xml:"suggestedPresentationDelay,attr,omitempty"`
 	BaseURL                    string    `xml:"BaseURL,omitempty"`
+	Location                   string    `xml:"Location,omitempty"`
 	period                     *Period
 	Periods                    []*Period       `xml:"Period,omitempty"`
 	UTCTiming                  *DescriptorType `xml:"UTCTiming,omitempty"`
@@ -93,6 +93,7 @@ type Period struct {
 	SegmentList     *SegmentList     `xml:"SegmentList,omitempty"`
 	SegmentTemplate *SegmentTemplate `xml:"SegmentTemplate,omitempty"`
 	AdaptationSets  []*AdaptationSet `xml:"AdaptationSet,omitempty"`
+	EventStreams    []EventStream    `xml:"EventStream,omitempty"`
 }
 
 type DescriptorType struct {
@@ -116,172 +117,88 @@ type CommonAttributesAndElements struct {
 	StartWithSAP              *int64                `xml:"startWithSAP,attr"`
 	MaxPlayoutRate            *string               `xml:"maxPlayoutRate,attr"`
 	ScanType                  *string               `xml:"scanType,attr"`
-	FramePacking              *DescriptorType       `xml:"framePacking,attr"`
-	AudioChannelConfiguration *DescriptorType       `xml:"audioChannelConfiguration,attr"`
+	FramePacking              []DescriptorType      `xml:"FramePacking,omitempty"`
+	AudioChannelConfiguration []DescriptorType      `xml:"AudioChannelConfiguration,omitempty"`
 	ContentProtection         []ContentProtectioner `xml:"ContentProtection,omitempty"`
-	EssentialProperty         *DescriptorType       `xml:"EssentialProperty,omitempty"`
-	SupplementalProperty      *DescriptorType       `xml:"supplmentalProperty,attr"`
+	EssentialProperty         []DescriptorType      `xml:"EssentialProperty,omitempty"`
+	SupplementalProperty      []DescriptorType      `xml:"SupplementalProperty,omitempty"`
 	InbandEventStream         *DescriptorType       `xml:"inbandEventStream,attr"`
 }
 
-type AdaptationSet struct {
-	CommonAttributesAndElements
-	XMLName            xml.Name              `xml:"AdaptationSet"`
-	ID                 *string               `xml:"id,attr"`
-	SegmentAlignment   *bool                 `xml:"segmentAlignment,attr"`
-	Lang               *string               `xml:"lang,attr"`
-	Group              *string               `xml:"group,attr"`
-	PAR                *string               `xml:"par,attr"`
-	MinBandwidth       *string               `xml:"minBandwidth,attr"`
-	MaxBandwidth       *string               `xml:"maxBandwidth,attr"`
-	MinWidth           *string               `xml:"minWidth,attr"`
-	MaxWidth           *string               `xml:"maxWidth,attr"`
-	MinHeight          *string               `xml:"minHeight,attr"`
-	MaxHeight          *string               `xml:"maxHeight,attr"`
-	ContentType        *string               `xml:"contentType,attr"`
-	ContentProtection  []ContentProtectioner `xml:"ContentProtection,omitempty"` // Common attribute, can be deprecated here
-	Roles              []*Role               `xml:"Role,omitempty"`
-	SegmentBase        *SegmentBase          `xml:"SegmentBase,omitempty"`
-	SegmentList        *SegmentList          `xml:"SegmentList,omitempty"`
-	SegmentTemplate    *SegmentTemplate      `xml:"SegmentTemplate,omitempty"` // Live Profile Only
-	Representations    []*Representation     `xml:"Representation,omitempty"`
-	AccessibilityElems []*Accessibility      `xml:"Accessibility,omitempty"`
+type contentProtections []ContentProtectioner
+
+func (as *contentProtections) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+	var scheme string
+	for _, a := range start.Attr {
+		if a.Name.Local == "schemeIdUri" {
+			scheme = a.Value
+			break
+		}
+	}
+	var target ContentProtectioner
+	switch scheme {
+	case CONTENT_PROTECTION_ROOT_SCHEME_ID_URI:
+		target = &CENCContentProtection{}
+	case CONTENT_PROTECTION_PLAYREADY_SCHEME_ID:
+		target = &PlayreadyContentProtection{}
+	case CONTENT_PROTECTION_WIDEVINE_SCHEME_ID:
+		target = &WidevineContentProtection{}
+	default:
+		target = &ContentProtection{}
+	}
+	if err := d.DecodeElement(target, &start); err != nil {
+		return err
+	}
+	*as = append(*as, target)
+	return nil
 }
 
-func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+// wrappedAdaptationSet provides the default xml unmarshal
+// to take care of the majority of our unmarshalling
+type wrappedAdaptationSet AdaptationSet
 
-	adaptationSet := struct {
-		CommonAttributesAndElements
-		XMLName            xml.Name              `xml:"AdaptationSet"`
-		ID                 *string               `xml:"id,attr"`
-		SegmentAlignment   *bool                 `xml:"segmentAlignment,attr"`
-		Lang               *string               `xml:"lang,attr"`
-		Group              *string               `xml:"group,attr"`
-		PAR                *string               `xml:"par,attr"`
-		MinBandwidth       *string               `xml:"minBandwidth,attr"`
-		MaxBandwidth       *string               `xml:"maxBandwidth,attr"`
-		MinWidth           *string               `xml:"minWidth,attr"`
-		MaxWidth           *string               `xml:"maxWidth,attr"`
-		MinHeight          *string               `xml:"minHeight,attr"`
-		MaxHeight          *string               `xml:"maxHeight,attr"`
-		ContentType        *string               `xml:"contentType,attr"`
-		ContentProtection  []ContentProtectioner `xml:"ContentProtection,omitempty"` // Common attribute, can be deprecated here
-		Roles              []*Role               `xml:"Role,omitempty"`
-		SegmentBase        *SegmentBase          `xml:"SegmentBase,omitempty"`
-		SegmentList        *SegmentList          `xml:"SegmentList,omitempty"`
-		SegmentTemplate    *SegmentTemplate      `xml:"SegmentTemplate,omitempty"` // Live Profile Only
-		Representations    []*Representation     `xml:"Representation,omitempty"`
-		AccessibilityElems []*Accessibility      `xml:"Accessibility,omitempty"`
-	}{}
-
-	var (
-		contentProtectionTags []ContentProtectioner
-		roles                 []*Role
-		segmentBase           *SegmentBase
-		segmentList           *SegmentList
-		segmentTemplate       *SegmentTemplate
-		representations       []*Representation
-		accessibility         []*Accessibility
-	)
-
-	// decode inner elements
-	for {
-		t, err := d.Token()
-		if err != nil {
-			return err
-		}
+// dtoAdaptationSet parses the items out of AdaptationSet
+// that give us trouble:
+// * Content Protection interface
+type dtoAdaptationSet struct {
+	wrappedAdaptationSet
+	ContentProtection contentProtections `xml:"ContentProtection,omitempty"`
+}
 
-		switch tt := t.(type) {
-		case xml.StartElement:
-			switch tt.Name.Local {
-			case "ContentProtection":
-				var (
-					schemeUri string
-					cp        ContentProtectioner
-				)
-
-				for _, attr := range tt.Attr {
-					if attr.Name.Local == "schemeIdUri" {
-						schemeUri = attr.Value
-					}
-				}
-				switch schemeUri {
-				case CONTENT_PROTECTION_ROOT_SCHEME_ID_URI:
-					cp = new(CENCContentProtection)
-				case CONTENT_PROTECTION_PLAYREADY_SCHEME_ID:
-					cp = new(PlayreadyContentProtection)
-				case CONTENT_PROTECTION_WIDEVINE_SCHEME_ID:
-					cp = new(WidevineContentProtection)
-				default:
-					cp = new(ContentProtection)
-				}
-
-				err = d.DecodeElement(cp, &tt)
-				if err != nil {
-					return err
-				}
-				contentProtectionTags = append(contentProtectionTags, cp)
-			case "Role":
-				rl := new(Role)
-				err = d.DecodeElement(rl, &tt)
-				if err != nil {
-					return err
-				}
-				roles = append(roles, rl)
-			case "SegmentBase":
-				sb := new(SegmentBase)
-				err = d.DecodeElement(sb, &tt)
-				if err != nil {
-					return err
-				}
-				segmentBase = sb
-			case "SegmentList":
-				sl := new(SegmentList)
-				err = d.DecodeElement(sl, &tt)
-				if err != nil {
-					return err
-				}
-				segmentList = sl
-			case "SegmentTemplate":
-				st := new(SegmentTemplate)
-				err = d.DecodeElement(st, &tt)
-				if err != nil {
-					return err
-				}
-				segmentTemplate = st
-			case "Representation":
-				rp := new(Representation)
-				err = d.DecodeElement(rp, &tt)
-				if err != nil {
-					return err
-				}
-				representations = append(representations, rp)
-			case "Accessibility":
-				ac := new(Accessibility)
-				err = d.DecodeElement(ac, &tt)
-				if err != nil {
-					return err
-				}
-				accessibility = append(accessibility, ac)
-			default:
-				return fmt.Errorf("unrecognized element in AdaptationSet %q", tt.Name.Local)
-			}
-		case xml.EndElement:
-			if tt == start.End() {
-				_ = d.DecodeElement(&adaptationSet, &start)
-				*as = adaptationSet
-				as.ContentProtection = contentProtectionTags
-				as.Roles = roles
-				as.SegmentBase = segmentBase
-				as.SegmentList = segmentList
-				as.SegmentTemplate = segmentTemplate
-				as.Representations = representations
-				as.AccessibilityElems = accessibility
-				return nil
-			}
-		}
+type AdaptationSet struct {
+	CommonAttributesAndElements
+	XMLName            xml.Name          `xml:"AdaptationSet"`
+	ID                 *string           `xml:"id,attr"`
+	SegmentAlignment   *bool             `xml:"segmentAlignment,attr"`
+	Lang               *string           `xml:"lang,attr"`
+	Group              *string           `xml:"group,attr"`
+	PAR                *string           `xml:"par,attr"`
+	MinBandwidth       *string           `xml:"minBandwidth,attr"`
+	MaxBandwidth       *string           `xml:"maxBandwidth,attr"`
+	MinWidth           *string           `xml:"minWidth,attr"`
+	MaxWidth           *string           `xml:"maxWidth,attr"`
+	MinHeight          *string           `xml:"minHeight,attr"`
+	MaxHeight          *string           `xml:"maxHeight,attr"`
+	ContentType        *string           `xml:"contentType,attr"`
+	Roles              []*Role           `xml:"Role,omitempty"`
+	SegmentBase        *SegmentBase      `xml:"SegmentBase,omitempty"`
+	SegmentList        *SegmentList      `xml:"SegmentList,omitempty"`
+	SegmentTemplate    *SegmentTemplate  `xml:"SegmentTemplate,omitempty"` // Live Profile Only
+	Representations    []*Representation `xml:"Representation,omitempty"`
+	AccessibilityElems []*Accessibility  `xml:"Accessibility,omitempty"`
+}
 
+func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+	var n dtoAdaptationSet
+	if err := d.DecodeElement(&n, &start); err != nil {
+		return err
 	}
+	*as = AdaptationSet(n.wrappedAdaptationSet)
+	as.ContentProtection = make([]ContentProtectioner, len(n.ContentProtection))
+	for i := range n.ContentProtection {
+		as.ContentProtection[i] = n.ContentProtection[i]
+	}
+	return nil
 }
 
 // Constants for DRM / ContentProtection
diff --git a/mpd/mpd_test.go b/mpd/mpd_test.go
index 6358c0f..9ecb43c 100644
--- a/mpd/mpd_test.go
+++ b/mpd/mpd_test.go
@@ -2,10 +2,12 @@ package mpd
 
 import (
 	"encoding/base64"
+	"path/filepath"
 	"testing"
 
 	. "github.com/zencoder/go-dash/helpers/ptrs"
 	"github.com/zencoder/go-dash/helpers/require"
+	"github.com/zencoder/go-dash/helpers/testfixtures"
 )
 
 const (
@@ -41,6 +43,7 @@ const (
 	VALID_SUBTITLE_ID                 string = "subtitle_en"
 	VALID_SUBTITLE_URL                string = "http://example.com/content/sintel/subtitles/subtitles_en.vtt"
 	VALID_ROLE                        string = "main"
+	VALID_LOCATION                    string = "https://example.com/location.mpd"
 )
 
 func TestNewMPDLive(t *testing.T) {
@@ -484,3 +487,42 @@ func TestAddNewAccessibilityElement(t *testing.T) {
 	require.EqualStringPtr(t, Strptr((string)(ACCESSIBILITY_ELEMENT_SCHEME_DESCRIPTIVE_AUDIO)), elem.SchemeIdUri)
 	require.EqualStringPtr(t, Strptr("1"), elem.Value)
 }
+
+func TestLocationWriteToString(t *testing.T) {
+	m := &MPD{
+		XMLNs:                 Strptr("urn:mpeg:dash:schema:mpd:2011"),
+		Profiles:              Strptr((string)(DASH_PROFILE_LIVE)),
+		Type:                  Strptr("dynamic"),
+		AvailabilityStartTime: Strptr(VALID_AVAILABILITY_START_TIME),
+		MinimumUpdatePeriod:   Strptr(VALID_MINIMUM_UPDATE_PERIOD),
+		PublishTime:           Strptr(VALID_AVAILABILITY_START_TIME),
+		Location:              VALID_LOCATION,
+	}
+
+	got, err := m.WriteToString()
+	require.NoError(t, err)
+
+	testfixtures.CompareFixture(t, "fixtures/location.mpd", got)
+}
+
+func TestReadWriteIdentical(t *testing.T) {
+	const fixtures = "fixtures/"
+	var (
+		skipFixtures = map[string]struct{}{"invalid.mpd": {}}
+		matches, err = filepath.Glob(fixtures + "*.mpd")
+	)
+	require.NoError(t, err)
+	for _, file := range matches {
+		file := filepath.Base(file)
+		if _, ok := skipFixtures[file]; ok {
+			continue
+		}
+		t.Run(file, func(t *testing.T) {
+			m, err := ReadFromFile(fixtures + file)
+			require.NoError(t, err)
+			got, err := m.WriteToString()
+			require.NoError(t, err)
+			testfixtures.CompareFixture(t, fixtures+file, got)
+		})
+	}
+}

From e1a70e66546e58878da10b49f6befc193648f9c3 Mon Sep 17 00:00:00 2001
From: Sam Eng <35475933+sam-eng@users.noreply.github.com>
Date: Mon, 30 Mar 2020 14:18:31 -0400
Subject: [PATCH 07/32] Add selectionPriority (#5)

* add selectionPriority attribute

* implement selectionPriority
---
 mpd/fixtures/ondemand_profile.mpd | 2 +-
 mpd/mpd.go                        | 1 +
 mpd/mpd_read_write_test.go        | 4 +++-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/mpd/fixtures/ondemand_profile.mpd b/mpd/fixtures/ondemand_profile.mpd
index 47a7cc7..777fa11 100644
--- a/mpd/fixtures/ondemand_profile.mpd
+++ b/mpd/fixtures/ondemand_profile.mpd
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" mediaPresentationDuration="PT30S" minBufferTime="PT1.97S">
   <Period>
-    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="und">
+    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="und" selectionPriority="3">
       <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
         <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
diff --git a/mpd/mpd.go b/mpd/mpd.go
index df4f52a..6d9b832 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -180,6 +180,7 @@ type AdaptationSet struct {
 	MinHeight          *string           `xml:"minHeight,attr"`
 	MaxHeight          *string           `xml:"maxHeight,attr"`
 	ContentType        *string           `xml:"contentType,attr"`
+	SelectionPriority  *uint64           `xml:"selectionPriority,attr"`
 	Roles              []*Role           `xml:"Role,omitempty"`
 	SegmentBase        *SegmentBase      `xml:"SegmentBase,omitempty"`
 	SegmentList        *SegmentList      `xml:"SegmentList,omitempty"`
diff --git a/mpd/mpd_read_write_test.go b/mpd/mpd_read_write_test.go
index e2c0292..a04bb49 100644
--- a/mpd/mpd_read_write_test.go
+++ b/mpd/mpd_read_write_test.go
@@ -150,13 +150,14 @@ func TestAddNewAdaptationSetVideoWriteToString(t *testing.T) {
 	as.MaxWidth = ptrs.Strptr("720")
 	as.MinHeight = ptrs.Strptr("480")
 	as.MaxHeight = ptrs.Strptr("480")
+	as.SelectionPriority = ptrs.Uint64ptr(5)
 
 	xmlStr, err := m.WriteToString()
 	require.NoError(t, err)
 	expectedXML := `<?xml version="1.0" encoding="UTF-8"?>
 <MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" mediaPresentationDuration="PT6M16S" minBufferTime="PT1.97S">
   <Period>
-    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true" minWidth="720" maxWidth="720" minHeight="480" maxHeight="480"></AdaptationSet>
+    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true" minWidth="720" maxWidth="720" minHeight="480" maxHeight="480" selectionPriority="5"></AdaptationSet>
   </Period>
 </MPD>
 `
@@ -413,6 +414,7 @@ func OnDemandProfile() *MPD {
 	_, _ = audioAS.AddNewContentProtectionSchemeWidevineWithPSSH(getValidWVHeaderBytes())
 	_, _ = audioAS.AddNewContentProtectionSchemePlayreadyWithPSSH(VALID_PLAYREADY_PRO)
 	_, _ = audioAS.AddNewAccessibilityElement(ACCESSIBILITY_ELEMENT_SCHEME_DESCRIPTIVE_AUDIO, "1")
+	audioAS.SelectionPriority = ptrs.Uint64ptr(3)
 
 	audioRep, _ := audioAS.AddNewRepresentationAudio(44100, 128558, "mp4a.40.5", "800k/audio-und")
 	_ = audioRep.SetNewBaseURL("800k/output-audio-und.mp4")

From 3c33641417441e7b226f11e2eaebb90aa55d956f Mon Sep 17 00:00:00 2001
From: Thomas Symborski <thomas.symborski@gmail.com>
Date: Mon, 15 Jun 2020 23:07:27 -0400
Subject: [PATCH 08/32] dash: marshal ContentProtection into custom type

---
 mpd/mpd.go | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/mpd/mpd.go b/mpd/mpd.go
index 6d9b832..f373f01 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -104,25 +104,25 @@ type DescriptorType struct {
 
 // ISO 23009-1-2014 5.3.7
 type CommonAttributesAndElements struct {
-	Profiles                  *string               `xml:"profiles,attr"`
-	Width                     *string               `xml:"width,attr"`
-	Height                    *string               `xml:"height,attr"`
-	Sar                       *string               `xml:"sar,attr"`
-	FrameRate                 *string               `xml:"frameRate,attr"`
-	AudioSamplingRate         *string               `xml:"audioSamplingRate,attr"`
-	MimeType                  *string               `xml:"mimeType,attr"`
-	SegmentProfiles           *string               `xml:"segmentProfiles,attr"`
-	Codecs                    *string               `xml:"codecs,attr"`
-	MaximumSAPPeriod          *string               `xml:"maximumSAPPeriod,attr"`
-	StartWithSAP              *int64                `xml:"startWithSAP,attr"`
-	MaxPlayoutRate            *string               `xml:"maxPlayoutRate,attr"`
-	ScanType                  *string               `xml:"scanType,attr"`
-	FramePacking              []DescriptorType      `xml:"FramePacking,omitempty"`
-	AudioChannelConfiguration []DescriptorType      `xml:"AudioChannelConfiguration,omitempty"`
-	ContentProtection         []ContentProtectioner `xml:"ContentProtection,omitempty"`
-	EssentialProperty         []DescriptorType      `xml:"EssentialProperty,omitempty"`
-	SupplementalProperty      []DescriptorType      `xml:"SupplementalProperty,omitempty"`
-	InbandEventStream         *DescriptorType       `xml:"inbandEventStream,attr"`
+	Profiles                  *string            `xml:"profiles,attr"`
+	Width                     *string            `xml:"width,attr"`
+	Height                    *string            `xml:"height,attr"`
+	Sar                       *string            `xml:"sar,attr"`
+	FrameRate                 *string            `xml:"frameRate,attr"`
+	AudioSamplingRate         *string            `xml:"audioSamplingRate,attr"`
+	MimeType                  *string            `xml:"mimeType,attr"`
+	SegmentProfiles           *string            `xml:"segmentProfiles,attr"`
+	Codecs                    *string            `xml:"codecs,attr"`
+	MaximumSAPPeriod          *string            `xml:"maximumSAPPeriod,attr"`
+	StartWithSAP              *int64             `xml:"startWithSAP,attr"`
+	MaxPlayoutRate            *string            `xml:"maxPlayoutRate,attr"`
+	ScanType                  *string            `xml:"scanType,attr"`
+	FramePacking              []DescriptorType   `xml:"FramePacking,omitempty"`
+	AudioChannelConfiguration []DescriptorType   `xml:"AudioChannelConfiguration,omitempty"`
+	ContentProtection         contentProtections `xml:"ContentProtection,omitempty"`
+	EssentialProperty         []DescriptorType   `xml:"EssentialProperty,omitempty"`
+	SupplementalProperty      []DescriptorType   `xml:"SupplementalProperty,omitempty"`
+	InbandEventStream         *DescriptorType    `xml:"inbandEventStream,attr"`
 }
 
 type contentProtections []ContentProtectioner

From 7c810a9e85a7014d5ba1d8b81c5f7aab34bd5e7b Mon Sep 17 00:00:00 2001
From: Thomas Symborski <thomas.symborski@gmail.com>
Date: Mon, 15 Jun 2020 23:37:57 -0400
Subject: [PATCH 09/32] fix: existing type error

---
 mpd/mpd_test.go | 66 ++++++++++++++++++++++++-------------------------
 1 file changed, 33 insertions(+), 33 deletions(-)

diff --git a/mpd/mpd_test.go b/mpd/mpd_test.go
index 9ecb43c..8106f27 100644
--- a/mpd/mpd_test.go
+++ b/mpd/mpd_test.go
@@ -11,39 +11,39 @@ import (
 )
 
 const (
-	VALID_MEDIA_PRESENTATION_DURATION string = "PT6M16S"
-	VALID_MIN_BUFFER_TIME             string = "PT1.97S"
-	VALID_AVAILABILITY_START_TIME     string = "1970-01-01T00:00:00Z"
-	VALID_MINIMUM_UPDATE_PERIOD       string = "PT5S"
-	VALID_SCAN_TYPE                   string = "progressive"
-	VALID_SEGMENT_ALIGNMENT           bool   = true
-	VALID_START_WITH_SAP              int64  = 1
-	VALID_LANG                        string = "en"
-	VALID_DURATION                    int64  = 1968
-	VALID_INIT_PATH_AUDIO             string = "$RepresentationID$/audio/en/init.mp4"
-	VALID_MEDIA_PATH_AUDIO            string = "$RepresentationID$/audio/en/seg-$Number$.m4f"
-	VALID_START_NUMBER                int64  = 0
-	VALID_TIMESCALE                   int64  = 1000
-	VALID_AUDIO_SAMPLE_RATE           int64  = 44100
-	VALID_AUDIO_BITRATE               int64  = 67095
-	VALID_AUDIO_CODEC                 string = "mp4a.40.2"
-	VALID_AUDIO_ID                    string = "800"
-	VALID_VIDEO_BITRATE               int64  = 1518664
-	VALID_VIDEO_CODEC                 string = "avc1.4d401f"
-	VALID_VIDEO_ID                    string = "800"
-	VALID_VIDEO_FRAMERATE             string = "30000/1001"
-	VALID_VIDEO_WIDTH                 int64  = 960
-	VALID_VIDEO_HEIGHT                int64  = 540
-	VALID_BASE_URL_VIDEO              string = "800k/output-video-1.mp4"
-	VALID_INDEX_RANGE                 string = "629-756"
-	VALID_INIT_RANGE                  string = "0-628"
-	VALID_PLAYREADY_PRO               string = "BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA="
-	VALID_WV_HEADER                   string = "CAESEFq91S9VSk8quNBh92FCUVUaCGNhc3RsYWJzIhhXcjNWTDFWS1R5cTQwR0gzWVVKUlZRPT0yB2RlZmF1bHQ="
-	VALID_SUBTITLE_BANDWIDTH          int64  = 256
-	VALID_SUBTITLE_ID                 string = "subtitle_en"
-	VALID_SUBTITLE_URL                string = "http://example.com/content/sintel/subtitles/subtitles_en.vtt"
-	VALID_ROLE                        string = "main"
-	VALID_LOCATION                    string = "https://example.com/location.mpd"
+	VALID_MEDIA_PRESENTATION_DURATION string  = "PT6M16S"
+	VALID_MIN_BUFFER_TIME             string  = "PT1.97S"
+	VALID_AVAILABILITY_START_TIME     string  = "1970-01-01T00:00:00Z"
+	VALID_MINIMUM_UPDATE_PERIOD       string  = "PT5S"
+	VALID_SCAN_TYPE                   string  = "progressive"
+	VALID_SEGMENT_ALIGNMENT           bool    = true
+	VALID_START_WITH_SAP              int64   = 1
+	VALID_LANG                        string  = "en"
+	VALID_DURATION                    float64 = 1968
+	VALID_INIT_PATH_AUDIO             string  = "$RepresentationID$/audio/en/init.mp4"
+	VALID_MEDIA_PATH_AUDIO            string  = "$RepresentationID$/audio/en/seg-$Number$.m4f"
+	VALID_START_NUMBER                int64   = 0
+	VALID_TIMESCALE                   int64   = 1000
+	VALID_AUDIO_SAMPLE_RATE           int64   = 44100
+	VALID_AUDIO_BITRATE               int64   = 67095
+	VALID_AUDIO_CODEC                 string  = "mp4a.40.2"
+	VALID_AUDIO_ID                    string  = "800"
+	VALID_VIDEO_BITRATE               int64   = 1518664
+	VALID_VIDEO_CODEC                 string  = "avc1.4d401f"
+	VALID_VIDEO_ID                    string  = "800"
+	VALID_VIDEO_FRAMERATE             string  = "30000/1001"
+	VALID_VIDEO_WIDTH                 int64   = 960
+	VALID_VIDEO_HEIGHT                int64   = 540
+	VALID_BASE_URL_VIDEO              string  = "800k/output-video-1.mp4"
+	VALID_INDEX_RANGE                 string  = "629-756"
+	VALID_INIT_RANGE                  string  = "0-628"
+	VALID_PLAYREADY_PRO               string  = "BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA="
+	VALID_WV_HEADER                   string  = "CAESEFq91S9VSk8quNBh92FCUVUaCGNhc3RsYWJzIhhXcjNWTDFWS1R5cTQwR0gzWVVKUlZRPT0yB2RlZmF1bHQ="
+	VALID_SUBTITLE_BANDWIDTH          int64   = 256
+	VALID_SUBTITLE_ID                 string  = "subtitle_en"
+	VALID_SUBTITLE_URL                string  = "http://example.com/content/sintel/subtitles/subtitles_en.vtt"
+	VALID_ROLE                        string  = "main"
+	VALID_LOCATION                    string  = "https://example.com/location.mpd"
 )
 
 func TestNewMPDLive(t *testing.T) {

From f9149dfd2286d449560ad281edb8614807e4986a Mon Sep 17 00:00:00 2001
From: Thomas Symborski <thomas.symborski@gmail.com>
Date: Tue, 16 Jun 2020 21:28:07 -0400
Subject: [PATCH 10/32] wip: mpd: cenc: parse and marshal namespace on
 cenc:pssh

---
 helpers/require/require.go           |  1 +
 helpers/testfixtures/testfixtures.go |  1 +
 mpd/mpd.go                           | 41 ++++++++++++++++++++--------
 3 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/helpers/require/require.go b/helpers/require/require.go
index 41b128a..b687118 100644
--- a/helpers/require/require.go
+++ b/helpers/require/require.go
@@ -95,6 +95,7 @@ func EqualStringPtr(t *testing.T, expected, actual *string, msgs ...string) {
 }
 
 func EqualString(t *testing.T, expected, actual string, msgs ...string) {
+	t.Helper()
 	if expected != actual {
 		t.Errorf("Expected %s but got %s", expected, actual)
 		for _, msg := range msgs {
diff --git a/helpers/testfixtures/testfixtures.go b/helpers/testfixtures/testfixtures.go
index 8f45684..397d053 100644
--- a/helpers/testfixtures/testfixtures.go
+++ b/helpers/testfixtures/testfixtures.go
@@ -19,6 +19,7 @@ func LoadFixture(path string) (js string) {
 }
 
 func CompareFixture(t *testing.T, fixturePath string, actualContent string) {
+	t.Helper()
 	expectedContent := LoadFixture(fixturePath)
 	if os.Getenv("GENERATE_FIXTURES") != "" {
 		_ = ioutil.WriteFile(fixturePath, []byte(actualContent), os.ModePerm)
diff --git a/mpd/mpd.go b/mpd/mpd.go
index f373f01..16d7809 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -234,16 +234,21 @@ type CENCContentProtection struct {
 	Value      *string `xml:"value,attr"` // Default: cenc
 }
 
+type PSSH struct {
+	XMLNS *string `xml:"cenc,attr"`
+	Value *string `xml:",chardata"`
+}
+
 type PlayreadyContentProtection struct {
 	ContentProtection
 	PlayreadyXMLNS *string `xml:"mspr,attr,omitempty"`
 	PRO            *string `xml:"pro,omitempty"`
-	PSSH           *string `xml:"pssh,omitempty"`
+	PSSH           *PSSH   `xml:"pssh,omitempty"`
 }
 
 type WidevineContentProtection struct {
 	ContentProtection
-	PSSH *string `xml:"pssh,omitempty"`
+	PSSH *PSSH `xml:"pssh,omitempty"`
 }
 
 type ContentProtectionMarshal struct {
@@ -260,16 +265,29 @@ type CENCContentProtectionMarshal struct {
 	Value      *string `xml:"value,attr"` // Default: cenc
 }
 
+type PSSHMarshal struct {
+	XMLNS *string `xml:"xmlns:cenc,attr"`
+	Value *string `xml:",chardata"`
+}
+
+func psshToMarshal(pssh *PSSH) *PSSHMarshal {
+	if pssh == nil {
+		return nil
+	}
+
+	return &PSSHMarshal{XMLNS: pssh.XMLNS, Value: pssh.Value}
+}
+
 type PlayreadyContentProtectionMarshal struct {
 	ContentProtectionMarshal
-	PlayreadyXMLNS *string `xml:"xmlns:mspr,attr,omitempty"`
-	PRO            *string `xml:"mspr:pro,omitempty"`
-	PSSH           *string `xml:"cenc:pssh,omitempty"`
+	PlayreadyXMLNS *string      `xml:"xmlns:mspr,attr,omitempty"`
+	PRO            *string      `xml:"mspr:pro,omitempty"`
+	PSSH           *PSSHMarshal `xml:"cenc:pssh,omitempty"`
 }
 
 type WidevineContentProtectionMarshal struct {
 	ContentProtectionMarshal
-	PSSH *string `xml:"cenc:pssh,omitempty"`
+	PSSH *PSSHMarshal `xml:"cenc:pssh,omitempty"`
 }
 
 func (s ContentProtection) ContentProtected() {}
@@ -317,8 +335,9 @@ func (s PlayreadyContentProtection) MarshalXML(e *xml.Encoder, start xml.StartEl
 		},
 		s.PlayreadyXMLNS,
 		s.PRO,
-		s.PSSH,
+		psshToMarshal(s.PSSH),
 	})
+
 	if err != nil {
 		return err
 	}
@@ -334,7 +353,7 @@ func (s WidevineContentProtection) MarshalXML(e *xml.Encoder, start xml.StartEle
 			s.XMLNS,
 			s.Attrs,
 		},
-		s.PSSH,
+		psshToMarshal(s.PSSH),
 	})
 	if err != nil {
 		return err
@@ -742,7 +761,7 @@ func NewWidevineContentProtection(wvHeader []byte) (*WidevineContentProtection,
 		}
 
 		psshB64 := base64.StdEncoding.EncodeToString(psshBox)
-		cp.PSSH = &psshB64
+		cp.PSSH = &PSSH{Value: &psshB64, XMLNS: Strptr(CENC_XMLNS)}
 	}
 	return cp, nil
 }
@@ -814,7 +833,7 @@ func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyWithPSSH(pro stri
 	if err != nil {
 		return nil, err
 	}
-	cp.PSSH = Strptr(base64.StdEncoding.EncodeToString(psshBox))
+	cp.PSSH = &PSSH{Value: Strptr(base64.StdEncoding.EncodeToString(psshBox)), XMLNS: Strptr(CENC_XMLNS)}
 
 	err = as.AddContentProtection(cp)
 	if err != nil {
@@ -846,7 +865,7 @@ func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyV10WithPSSH(pro s
 	if err != nil {
 		return nil, err
 	}
-	cp.PSSH = Strptr(base64.StdEncoding.EncodeToString(psshBox))
+	cp.PSSH = &PSSH{Value: Strptr(base64.StdEncoding.EncodeToString(psshBox)), XMLNS: Strptr(CENC_XMLNS)}
 
 	err = as.AddContentProtection(cp)
 	if err != nil {

From 54010516d9b06a377800324c2790d350a9775ec5 Mon Sep 17 00:00:00 2001
From: Thomas Symborski <thomas.symborski@gmail.com>
Date: Tue, 16 Jun 2020 21:45:01 -0400
Subject: [PATCH 11/32] testing: update fixtures

---
 mpd/fixtures/hbbtv_profile.mpd        | 8 ++++----
 mpd/fixtures/live_profile.mpd         | 8 ++++----
 mpd/fixtures/live_profile_dynamic.mpd | 8 ++++----
 mpd/fixtures/ondemand_profile.mpd     | 8 ++++----
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/mpd/fixtures/hbbtv_profile.mpd b/mpd/fixtures/hbbtv_profile.mpd
index f7672e9..aab7070 100644
--- a/mpd/fixtures/hbbtv_profile.mpd
+++ b/mpd/fixtures/hbbtv_profile.mpd
@@ -4,11 +4,11 @@
     <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="en">
       <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
       </ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
         <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
       </ContentProtection>
       <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
       <SegmentTemplate duration="1968" initialization="$RepresentationID$/audio/en/init.mp4" media="$RepresentationID$/audio/en/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
@@ -20,11 +20,11 @@
     <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true">
       <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
       </ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
         <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
       </ContentProtection>
       <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
       <SegmentTemplate duration="1968" initialization="$RepresentationID$/video/1/init.mp4" media="$RepresentationID$/video/1/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
diff --git a/mpd/fixtures/live_profile.mpd b/mpd/fixtures/live_profile.mpd
index 20b4f44..e4b724d 100644
--- a/mpd/fixtures/live_profile.mpd
+++ b/mpd/fixtures/live_profile.mpd
@@ -4,11 +4,11 @@
     <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="en">
       <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
       </ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
         <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
       </ContentProtection>
       <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
       <SegmentTemplate duration="1968" initialization="$RepresentationID$/audio/en/init.mp4" media="$RepresentationID$/audio/en/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
@@ -18,11 +18,11 @@
     <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true">
       <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
       </ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
         <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
       </ContentProtection>
       <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
       <SegmentTemplate duration="1968" initialization="$RepresentationID$/video/1/init.mp4" media="$RepresentationID$/video/1/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
diff --git a/mpd/fixtures/live_profile_dynamic.mpd b/mpd/fixtures/live_profile_dynamic.mpd
index f06c190..2838ec3 100644
--- a/mpd/fixtures/live_profile_dynamic.mpd
+++ b/mpd/fixtures/live_profile_dynamic.mpd
@@ -4,11 +4,11 @@
     <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="en">
       <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
       </ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
         <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
       </ContentProtection>
       <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
       <SegmentTemplate duration="1968" initialization="$RepresentationID$/audio/en/init.mp4" media="$RepresentationID$/audio/en/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
@@ -18,11 +18,11 @@
     <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true">
       <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
       </ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
         <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
       </ContentProtection>
       <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
       <SegmentTemplate duration="1968" initialization="$RepresentationID$/video/1/init.mp4" media="$RepresentationID$/video/1/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
diff --git a/mpd/fixtures/ondemand_profile.mpd b/mpd/fixtures/ondemand_profile.mpd
index 777fa11..88eaf90 100644
--- a/mpd/fixtures/ondemand_profile.mpd
+++ b/mpd/fixtures/ondemand_profile.mpd
@@ -4,11 +4,11 @@
     <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="und" selectionPriority="3">
       <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
       </ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
         <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
       </ContentProtection>
       <Representation audioSamplingRate="44100" bandwidth="128558" codecs="mp4a.40.5" id="800k/audio-und">
         <BaseURL>800k/output-audio-und.mp4</BaseURL>
@@ -21,11 +21,11 @@
     <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true">
       <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh>AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
       </ContentProtection>
       <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
         <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh>AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
       </ContentProtection>
       <Representation bandwidth="1100690" codecs="avc1.4d401e" frameRate="30000/1001" height="360" id="800k/video-1" width="640">
         <BaseURL>800k/output-video-1.mp4</BaseURL>

From 8beae51c9938ef633e7f471056f068da1337bcf8 Mon Sep 17 00:00:00 2001
From: Keith Richards <keith.richards@cbsinteractive.com>
Date: Thu, 29 Oct 2020 19:40:27 +0000
Subject: [PATCH 12/32] Support Scte35 Splice Inserts in EventStream. Also
 adding namespace support for namespacing scte35 and xsi.

---
 README.md               |   2 +
 mpd/events.go           |   9 +-
 mpd/fixtures/scte35.mpd |  55 +++++++++++
 mpd/mpd.go              | 102 +++++++++++++------
 mpd/mpd_test.go         |  66 ++++++-------
 mpd/scte35.go           | 214 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 382 insertions(+), 66 deletions(-)
 create mode 100644 mpd/fixtures/scte35.mpd
 create mode 100644 mpd/scte35.go

diff --git a/README.md b/README.md
index 89887f0..673fde4 100644
--- a/README.md
+++ b/README.md
@@ -21,11 +21,13 @@ go get -u github.com/zencoder/go-dash
 * DRM (ContentProtection)
   * PlayReady
   * Widevine
+* Scte35 Splice Insert
 
 ## Known Limitations (for now) (PRs welcome)
 
 * No PSSH/PRO generation
 * Limited Profile Support
+* Scte35 Time Signal
 
 ## Example Usage
 
diff --git a/mpd/events.go b/mpd/events.go
index ef7b981..746ac06 100644
--- a/mpd/events.go
+++ b/mpd/events.go
@@ -11,8 +11,9 @@ type EventStream struct {
 }
 
 type Event struct {
-	XMLName          xml.Name `xml:"Event"`
-	ID               *string  `xml:"id,attr,omitempty"`
-	PresentationTime *int64   `xml:"presentationTime,attr,omitempty"`
-	Duration         *int64   `xml:"duration,attr,omitempty"`
+	XMLName           xml.Name                 `xml:"Event"`
+	ID                *string                  `xml:"id,attr,omitempty"`
+	SpliceInfoSection *Scte35SpliceInfoSection `xml:"SpliceInfoSection,omitempty"`
+	PresentationTime  *int64                   `xml:"presentationTime,attr,omitempty"`
+	Duration          *int64                   `xml:"duration,attr,omitempty"`
 }
diff --git a/mpd/fixtures/scte35.mpd b/mpd/fixtures/scte35.mpd
new file mode 100644
index 0000000..b0f7f44
--- /dev/null
+++ b/mpd/fixtures/scte35.mpd
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:scte35="urn:scte:scte35:2013:xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic" minBufferTime="PT30S" availabilityStartTime="2020-10-26T20:23:21.839000+00:00" minimumUpdatePeriod="PT15S" publishTime="2020-10-26T21:31:19" timeShiftBufferDepth="PT118.999S" suggestedPresentationDelay="PT25S" id="201">
+  <Period id="545" start="PT32.808S">
+    <SupplementalProperty schemeIdUri="urn:scte:dash:utc-time" value="2020-10-26T00:54:05.508Z"></SupplementalProperty>
+    <AdaptationSet mimeType="video/mp4" startWithSAP="1" subsegmentStartsWithSAP="1" segmentAlignment="true" subsegmentAlignment="true" bitstreamSwitching="true">
+      <Representation bandwidth="249984" codecs="avc1.64000D" frameRate="30000/1001" height="224" id="1" width="400">
+        <SegmentTemplate presentationTimeOffset="97434268" initialization="manifest_video_1_0_init.mp4?m=1603743253" media="manifest_video_1_0_$Number$.mp4?m=1603743253" startNumber="665" timescale="30000">
+          <SegmentTimeline>
+            <S t="118867680" d="180180" r="19"></S>
+          </SegmentTimeline>
+        </SegmentTemplate>
+      </Representation>
+    </AdaptationSet>
+    <AdaptationSet mimeType="audio/mp4" segmentAlignment="false" lang="und">
+      <Representation audioSamplingRate="48000" bandwidth="66574" codecs="mp4a.40.2" id="8">
+        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"></AudioChannelConfiguration>
+        <SegmentTemplate presentationTimeOffset="155895040" initialization="manifest_audio_2_0_init.mp4?m=1603743253" media="manifest_audio_2_0_$Number$.mp4?m=1603743253" startNumber="665" timescale="48000">
+          <SegmentTimeline>
+            <S t="190188800" d="288768"></S>
+            <S t="190477568" d="287744"></S>
+            <S t="190765312" d="288768"></S>
+            <S t="191054080" d="287744"></S>
+            <S t="191341824" d="288768"></S>
+            <S t="191630592" d="287744"></S>
+            <S t="191918336" d="288768"></S>
+            <S t="192207104" d="287744"></S>
+            <S t="192494848" d="288768"></S>
+            <S t="192783616" d="287744"></S>
+            <S t="193071360" d="288768"></S>
+            <S t="193360128" d="287744"></S>
+            <S t="193647872" d="288768"></S>
+            <S t="193936640" d="287744"></S>
+            <S t="194224384" d="288768"></S>
+            <S t="194513152" d="287744"></S>
+            <S t="194800896" d="288768" r="1"></S>
+            <S t="195378432" d="287744"></S>
+            <S t="195666176" d="288768"></S>
+          </SegmentTimeline>
+        </SegmentTemplate>
+      </Representation>
+    </AdaptationSet>
+    <EventStream schemeIdUri="urn:scte:scte35:2013:xml" timescale="90000">
+      <Event duration="4051047">
+        <scte35:SpliceInfoSection protocolVersion="0" ptsAdjustment="207000" tier="4095">
+          <scte35:SpliceInsert spliceEventId="1603904856" spliceEventCancelIndicator="false" outOfNetworkIndicator="true" spliceImmediateFlag="false" uniqueProgramId="1" availNum="1" availsExpected="1">
+            <scte35:Program>
+              <scte35:SpliceTime ptsTime="5905840702"></scte35:SpliceTime>
+            </scte35:Program>
+            <scte35:BreakDuration autoReturn="true" duration="4051047"></scte35:BreakDuration>
+          </scte35:SpliceInsert>
+        </scte35:SpliceInfoSection>
+      </Event>
+    </EventStream>
+  </Period>
+</MPD>
diff --git a/mpd/mpd.go b/mpd/mpd.go
index 6d9b832..e13fdd1 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -68,6 +68,9 @@ var (
 
 type MPD struct {
 	XMLNs                      *string   `xml:"xmlns,attr"`
+	Scte35NS                   *Scte35NS `xml:"scte35,attr,omitempty"`
+	XsiNS                      *XsiNS    `xml:"xsi,attr,omitempty"`
+	XsiSchemaLocation          *XsiSL    `xml:"schemaLocation,attr,omitempty"`
 	Profiles                   *string   `xml:"profiles,attr"`
 	Type                       *string   `xml:"type,attr"`
 	MediaPresentationDuration  *string   `xml:"mediaPresentationDuration,attr"`
@@ -82,18 +85,56 @@ type MPD struct {
 	period                     *Period
 	Periods                    []*Period       `xml:"Period,omitempty"`
 	UTCTiming                  *DescriptorType `xml:"UTCTiming,omitempty"`
+	ID                         string          `xml:"id,attr,omitempty"`
+}
+
+type XsiNS struct {
+	XmlName xml.Name
+	Value   string
+}
+
+func (s *XsiNS) UnmarshalXMLAttr(attr xml.Attr) error {
+	s.XmlName = attr.Name
+	s.Value = attr.Value
+	return nil
+}
+
+func (s *XsiNS) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
+	if strings.Contains(s.XmlName.Local, "xsi") {
+		return xml.Attr{Name: xml.Name{Local: "xmlns:xsi"}, Value: s.Value}, nil
+	}
+	return xml.Attr{}, nil
+}
+
+type XsiSL struct {
+	XmlName xml.Name
+	Value   string
+}
+
+func (s *XsiSL) UnmarshalXMLAttr(attr xml.Attr) error {
+	s.XmlName = attr.Name
+	s.Value = attr.Value
+	return nil
+}
+
+func (s *XsiSL) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
+	if strings.Contains(s.XmlName.Local, "schemaLocation") {
+		return xml.Attr{Name: xml.Name{Local: "xsi:schemaLocation"}, Value: s.Value}, nil
+	}
+	return xml.Attr{}, nil
 }
 
 type Period struct {
-	ID              string           `xml:"id,attr,omitempty"`
-	Duration        Duration         `xml:"duration,attr,omitempty"`
-	Start           *Duration        `xml:"start,attr,omitempty"`
-	BaseURL         string           `xml:"BaseURL,omitempty"`
-	SegmentBase     *SegmentBase     `xml:"SegmentBase,omitempty"`
-	SegmentList     *SegmentList     `xml:"SegmentList,omitempty"`
-	SegmentTemplate *SegmentTemplate `xml:"SegmentTemplate,omitempty"`
-	AdaptationSets  []*AdaptationSet `xml:"AdaptationSet,omitempty"`
-	EventStreams    []EventStream    `xml:"EventStream,omitempty"`
+	SupplementalProperty []DescriptorType `xml:"SupplementalProperty,omitempty"`
+	ID                   string           `xml:"id,attr,omitempty"`
+	Duration             Duration         `xml:"duration,attr,omitempty"`
+	Start                *Duration        `xml:"start,attr,omitempty"`
+	BaseURL              string           `xml:"BaseURL,omitempty"`
+	SegmentBase          *SegmentBase     `xml:"SegmentBase,omitempty"`
+	SegmentList          *SegmentList     `xml:"SegmentList,omitempty"`
+	SegmentTemplate      *SegmentTemplate `xml:"SegmentTemplate,omitempty"`
+	AdaptationSets       []*AdaptationSet `xml:"AdaptationSet,omitempty"`
+	EventStreams         []EventStream    `xml:"EventStream,omitempty"`
 }
 
 type DescriptorType struct {
@@ -115,6 +156,7 @@ type CommonAttributesAndElements struct {
 	Codecs                    *string               `xml:"codecs,attr"`
 	MaximumSAPPeriod          *string               `xml:"maximumSAPPeriod,attr"`
 	StartWithSAP              *int64                `xml:"startWithSAP,attr"`
+	SubsegmentStartsWithSAP   *int64                `xml:"subsegmentStartsWithSAP,attr,omitempty"`
 	MaxPlayoutRate            *string               `xml:"maxPlayoutRate,attr"`
 	ScanType                  *string               `xml:"scanType,attr"`
 	FramePacking              []DescriptorType      `xml:"FramePacking,omitempty"`
@@ -167,26 +209,28 @@ type dtoAdaptationSet struct {
 
 type AdaptationSet struct {
 	CommonAttributesAndElements
-	XMLName            xml.Name          `xml:"AdaptationSet"`
-	ID                 *string           `xml:"id,attr"`
-	SegmentAlignment   *bool             `xml:"segmentAlignment,attr"`
-	Lang               *string           `xml:"lang,attr"`
-	Group              *string           `xml:"group,attr"`
-	PAR                *string           `xml:"par,attr"`
-	MinBandwidth       *string           `xml:"minBandwidth,attr"`
-	MaxBandwidth       *string           `xml:"maxBandwidth,attr"`
-	MinWidth           *string           `xml:"minWidth,attr"`
-	MaxWidth           *string           `xml:"maxWidth,attr"`
-	MinHeight          *string           `xml:"minHeight,attr"`
-	MaxHeight          *string           `xml:"maxHeight,attr"`
-	ContentType        *string           `xml:"contentType,attr"`
-	SelectionPriority  *uint64           `xml:"selectionPriority,attr"`
-	Roles              []*Role           `xml:"Role,omitempty"`
-	SegmentBase        *SegmentBase      `xml:"SegmentBase,omitempty"`
-	SegmentList        *SegmentList      `xml:"SegmentList,omitempty"`
-	SegmentTemplate    *SegmentTemplate  `xml:"SegmentTemplate,omitempty"` // Live Profile Only
-	Representations    []*Representation `xml:"Representation,omitempty"`
-	AccessibilityElems []*Accessibility  `xml:"Accessibility,omitempty"`
+	XMLName             xml.Name          `xml:"AdaptationSet"`
+	ID                  *string           `xml:"id,attr"`
+	SegmentAlignment    *bool             `xml:"segmentAlignment,attr"`
+	SubsegmentAlignment *bool             `xml:"subsegmentAlignment,attr,omitempty"`
+	BitstreamSwitching  *bool             `xml:"bitstreamSwitching,attr,omitempty"`
+	Lang                *string           `xml:"lang,attr"`
+	Group               *string           `xml:"group,attr"`
+	PAR                 *string           `xml:"par,attr"`
+	MinBandwidth        *string           `xml:"minBandwidth,attr"`
+	MaxBandwidth        *string           `xml:"maxBandwidth,attr"`
+	MinWidth            *string           `xml:"minWidth,attr"`
+	MaxWidth            *string           `xml:"maxWidth,attr"`
+	MinHeight           *string           `xml:"minHeight,attr"`
+	MaxHeight           *string           `xml:"maxHeight,attr"`
+	ContentType         *string           `xml:"contentType,attr"`
+	SelectionPriority   *uint64           `xml:"selectionPriority,attr"`
+	Roles               []*Role           `xml:"Role,omitempty"`
+	SegmentBase         *SegmentBase      `xml:"SegmentBase,omitempty"`
+	SegmentList         *SegmentList      `xml:"SegmentList,omitempty"`
+	SegmentTemplate     *SegmentTemplate  `xml:"SegmentTemplate,omitempty"` // Live Profile Only
+	Representations     []*Representation `xml:"Representation,omitempty"`
+	AccessibilityElems  []*Accessibility  `xml:"Accessibility,omitempty"`
 }
 
 func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
diff --git a/mpd/mpd_test.go b/mpd/mpd_test.go
index 9ecb43c..6b6c7bf 100644
--- a/mpd/mpd_test.go
+++ b/mpd/mpd_test.go
@@ -11,39 +11,39 @@ import (
 )
 
 const (
-	VALID_MEDIA_PRESENTATION_DURATION string = "PT6M16S"
-	VALID_MIN_BUFFER_TIME             string = "PT1.97S"
-	VALID_AVAILABILITY_START_TIME     string = "1970-01-01T00:00:00Z"
-	VALID_MINIMUM_UPDATE_PERIOD       string = "PT5S"
-	VALID_SCAN_TYPE                   string = "progressive"
-	VALID_SEGMENT_ALIGNMENT           bool   = true
-	VALID_START_WITH_SAP              int64  = 1
-	VALID_LANG                        string = "en"
-	VALID_DURATION                    int64  = 1968
-	VALID_INIT_PATH_AUDIO             string = "$RepresentationID$/audio/en/init.mp4"
-	VALID_MEDIA_PATH_AUDIO            string = "$RepresentationID$/audio/en/seg-$Number$.m4f"
-	VALID_START_NUMBER                int64  = 0
-	VALID_TIMESCALE                   int64  = 1000
-	VALID_AUDIO_SAMPLE_RATE           int64  = 44100
-	VALID_AUDIO_BITRATE               int64  = 67095
-	VALID_AUDIO_CODEC                 string = "mp4a.40.2"
-	VALID_AUDIO_ID                    string = "800"
-	VALID_VIDEO_BITRATE               int64  = 1518664
-	VALID_VIDEO_CODEC                 string = "avc1.4d401f"
-	VALID_VIDEO_ID                    string = "800"
-	VALID_VIDEO_FRAMERATE             string = "30000/1001"
-	VALID_VIDEO_WIDTH                 int64  = 960
-	VALID_VIDEO_HEIGHT                int64  = 540
-	VALID_BASE_URL_VIDEO              string = "800k/output-video-1.mp4"
-	VALID_INDEX_RANGE                 string = "629-756"
-	VALID_INIT_RANGE                  string = "0-628"
-	VALID_PLAYREADY_PRO               string = "BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA="
-	VALID_WV_HEADER                   string = "CAESEFq91S9VSk8quNBh92FCUVUaCGNhc3RsYWJzIhhXcjNWTDFWS1R5cTQwR0gzWVVKUlZRPT0yB2RlZmF1bHQ="
-	VALID_SUBTITLE_BANDWIDTH          int64  = 256
-	VALID_SUBTITLE_ID                 string = "subtitle_en"
-	VALID_SUBTITLE_URL                string = "http://example.com/content/sintel/subtitles/subtitles_en.vtt"
-	VALID_ROLE                        string = "main"
-	VALID_LOCATION                    string = "https://example.com/location.mpd"
+	VALID_MEDIA_PRESENTATION_DURATION string  = "PT6M16S"
+	VALID_MIN_BUFFER_TIME             string  = "PT1.97S"
+	VALID_AVAILABILITY_START_TIME     string  = "1970-01-01T00:00:00Z"
+	VALID_MINIMUM_UPDATE_PERIOD       string  = "PT5S"
+	VALID_SCAN_TYPE                   string  = "progressive"
+	VALID_SEGMENT_ALIGNMENT           bool    = true
+	VALID_START_WITH_SAP              int64   = 1
+	VALID_LANG                        string  = "en"
+	VALID_DURATION                    float64 = 1968.0
+	VALID_INIT_PATH_AUDIO             string  = "$RepresentationID$/audio/en/init.mp4"
+	VALID_MEDIA_PATH_AUDIO            string  = "$RepresentationID$/audio/en/seg-$Number$.m4f"
+	VALID_START_NUMBER                int64   = 0
+	VALID_TIMESCALE                   int64   = 1000
+	VALID_AUDIO_SAMPLE_RATE           int64   = 44100
+	VALID_AUDIO_BITRATE               int64   = 67095
+	VALID_AUDIO_CODEC                 string  = "mp4a.40.2"
+	VALID_AUDIO_ID                    string  = "800"
+	VALID_VIDEO_BITRATE               int64   = 1518664
+	VALID_VIDEO_CODEC                 string  = "avc1.4d401f"
+	VALID_VIDEO_ID                    string  = "800"
+	VALID_VIDEO_FRAMERATE             string  = "30000/1001"
+	VALID_VIDEO_WIDTH                 int64   = 960
+	VALID_VIDEO_HEIGHT                int64   = 540
+	VALID_BASE_URL_VIDEO              string  = "800k/output-video-1.mp4"
+	VALID_INDEX_RANGE                 string  = "629-756"
+	VALID_INIT_RANGE                  string  = "0-628"
+	VALID_PLAYREADY_PRO               string  = "BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA="
+	VALID_WV_HEADER                   string  = "CAESEFq91S9VSk8quNBh92FCUVUaCGNhc3RsYWJzIhhXcjNWTDFWS1R5cTQwR0gzWVVKUlZRPT0yB2RlZmF1bHQ="
+	VALID_SUBTITLE_BANDWIDTH          int64   = 256
+	VALID_SUBTITLE_ID                 string  = "subtitle_en"
+	VALID_SUBTITLE_URL                string  = "http://example.com/content/sintel/subtitles/subtitles_en.vtt"
+	VALID_ROLE                        string  = "main"
+	VALID_LOCATION                    string  = "https://example.com/location.mpd"
 )
 
 func TestNewMPDLive(t *testing.T) {
diff --git a/mpd/scte35.go b/mpd/scte35.go
new file mode 100644
index 0000000..2621178
--- /dev/null
+++ b/mpd/scte35.go
@@ -0,0 +1,214 @@
+package mpd
+
+import (
+	"encoding/xml"
+	"strings"
+)
+
+type Scte35NS struct {
+	XmlName xml.Name
+	Value   string
+}
+
+func (s *Scte35NS) UnmarshalXMLAttr(attr xml.Attr) error {
+	s.XmlName = attr.Name
+	s.Value = attr.Value
+	return nil
+}
+
+func (s *Scte35NS) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
+	if strings.Contains(s.XmlName.Local, "scte35") {
+		return xml.Attr{Name: xml.Name{Local: "xmlns:scte35"}, Value: s.Value}, nil
+	}
+	return xml.Attr{}, nil
+}
+
+type Scte35SpliceInfoSection struct {
+	ProtocolVersion    *string             `xml:"protocolVersion,attr,omitempty"`
+	PtsAdjustment      *int64              `xml:"ptsAdjustment,attr,omitempty"`
+	Tier               *int64              `xml:"tier,attr,omitempty"`
+	Scte35SpliceInsert *Scte35SpliceInsert `xml:"SpliceInsert",omitempty"`
+}
+
+type Scte35SpliceInsert struct {
+	SpliceEventId              *string              `xml:"spliceEventId,attr,omitempty"`
+	SpliceEventCancelIndicator bool                 `xml:"spliceEventCancelIndicator,attr"`
+	OutOfNetworkIndicator      bool                 `xml:"outOfNetworkIndicator,attr,omitempty"`
+	SpliceImmediateFlag        bool                 `xml:"spliceImmediateFlag,attr"`
+	UniqueProgramId            *string              `xml:"uniqueProgramId,attr,omitempty"`
+	AvailNum                   *int64               `xml:"availNum,attr,omitempty"`
+	AvailsExpected             *int64               `xml:"availsExpected,attr,omitempty"`
+	Program                    *Scte35Program       `xml:"Program,omitempty"`
+	BreakDuration              *Scte35BreakDuration `xml:"BreakDuration,omitempty"`
+}
+
+type Scte35Program struct {
+	Scte35SpliceTime *Scte35SpliceTime `xml:"SpliceTime,omitempty"`
+}
+
+type Scte35SpliceTime struct {
+	PtsTime *int64 `xml:"ptsTime,attr,omitempty"`
+}
+
+type Scte35BreakDuration struct {
+	AutoReturn bool   `xml:"autoReturn,attr,omitempty"`
+	Duration   *int64 `xml:"duration,attr,omitempty"`
+}
+
+// Wrappers for handlings unmarshalling, since golang's xml namespace handling is horrifying.
+type wrappedScte35Program Scte35Program
+type wrappedScte35SpliceTime Scte35SpliceTime
+type wrappedScte35BreakDuration Scte35BreakDuration
+type wrappedScte35SpliceInsert Scte35SpliceInsert
+type wrappedScte35SpliceInfoSection Scte35SpliceInfoSection
+
+type dtoScte35Program struct {
+	wrappedScte35Program
+}
+
+type dtoScte35SpliceTime struct {
+	wrappedScte35SpliceTime
+}
+
+type dtoScte35BreakDuration struct {
+	wrappedScte35BreakDuration
+}
+
+type dtoScte35SpliceInsert struct {
+	wrappedScte35SpliceInsert
+}
+
+type dtoScte35SpliceInfoSection struct {
+	wrappedScte35SpliceInfoSection
+}
+
+// Wrappers for handling marshalling, since golangs xml namespace handling is horrifying.
+type Scte35ProgramMarshal struct {
+	XMLName          xml.Name
+	Scte35SpliceTime *Scte35SpliceTime `xml:",omitempty"`
+}
+
+type Scte35SpliceTimeMarshal struct {
+	XMLName xml.Name
+	PtsTime *int64 `xml:"ptsTime,attr,omitempty"`
+}
+
+type Scte35BreakDurationMarshal struct {
+	XMLName    xml.Name
+	AutoReturn bool   `xml:"autoReturn,attr,omitempty"`
+	Duration   *int64 `xml:"duration,attr,omitempty"`
+}
+
+type Scte35SpliceInfoSectionMarshal struct {
+	XMLName            xml.Name
+	ProtocolVersion    *string             `xml:"protocolVersion,attr,omitempty"`
+	PtsAdjustment      *int64              `xml:"ptsAdjustment,attr,omitempty"`
+	Tier               *int64              `xml:"tier,attr,omitempty"`
+	Scte35SpliceInsert *Scte35SpliceInsert `xml:"SpliceInsert",omitempty"`
+}
+
+type Scte35SpliceInsertMarshal struct {
+	XMLName                    xml.Name
+	SpliceEventId              *string              `xml:"spliceEventId,attr,omitempty"`
+	SpliceEventCancelIndicator bool                 `xml:"spliceEventCancelIndicator,attr"`
+	OutOfNetworkIndicator      bool                 `xml:"outOfNetworkIndicator,attr,omitempty"`
+	SpliceImmediateFlag        bool                 `xml:"spliceImmediateFlag,attr"`
+	UniqueProgramId            *string              `xml:"uniqueProgramId,attr,omitempty"`
+	AvailNum                   *int64               `xml:"availNum,attr,omitempty"`
+	AvailsExpected             *int64               `xml:"availsExpected,attr,omitempty"`
+	Program                    *Scte35Program       `xml:"Program,omitempty"`
+	BreakDuration              *Scte35BreakDuration `xml:"BreakDuration,omitempty"`
+}
+
+// unmarshal/marshal functions for Scte35 structures
+func (s *Scte35Program) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+	var _s dtoScte35Program
+	if err := d.DecodeElement(&_s, &start); err != nil {
+		return err
+	}
+	*s = Scte35Program(_s.wrappedScte35Program)
+	return nil
+}
+
+func (s *Scte35Program) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+	return e.Encode(&Scte35ProgramMarshal{
+		XMLName:          xml.Name{Local: "scte35:Program"},
+		Scte35SpliceTime: s.Scte35SpliceTime,
+	})
+}
+
+func (s *Scte35SpliceTime) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+	var _s dtoScte35SpliceTime
+	if err := d.DecodeElement(&_s, &start); err != nil {
+		return err
+	}
+	*s = Scte35SpliceTime(_s.wrappedScte35SpliceTime)
+	return nil
+}
+
+func (s *Scte35SpliceTime) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+	return e.Encode(&Scte35SpliceTimeMarshal{
+		XMLName: xml.Name{Local: "scte35:SpliceTime"},
+		PtsTime: s.PtsTime,
+	})
+}
+
+func (s *Scte35BreakDuration) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+	var _s dtoScte35BreakDuration
+	if err := d.DecodeElement(&_s, &start); err != nil {
+		return err
+	}
+	*s = Scte35BreakDuration(_s.wrappedScte35BreakDuration)
+	return nil
+}
+
+func (s *Scte35BreakDuration) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+	return e.Encode(&Scte35BreakDurationMarshal{
+		XMLName:    xml.Name{Local: "scte35:BreakDuration"},
+		AutoReturn: s.AutoReturn,
+		Duration:   s.Duration,
+	})
+}
+
+func (s *Scte35SpliceInsert) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+	var _s dtoScte35SpliceInsert
+	if err := d.DecodeElement(&_s, &start); err != nil {
+		return err
+	}
+	*s = Scte35SpliceInsert(_s.wrappedScte35SpliceInsert)
+	return nil
+}
+
+func (s *Scte35SpliceInsert) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+	return e.Encode(&Scte35SpliceInsertMarshal{
+		XMLName:                    xml.Name{Local: "scte35:SpliceInsert"},
+		SpliceEventId:              s.SpliceEventId,
+		SpliceEventCancelIndicator: s.SpliceEventCancelIndicator,
+		OutOfNetworkIndicator:      s.OutOfNetworkIndicator,
+		SpliceImmediateFlag:        s.SpliceImmediateFlag,
+		UniqueProgramId:            s.UniqueProgramId,
+		AvailNum:                   s.AvailNum,
+		AvailsExpected:             s.AvailsExpected,
+		Program:                    s.Program,
+		BreakDuration:              s.BreakDuration,
+	})
+}
+
+func (s *Scte35SpliceInfoSection) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+	var _s dtoScte35SpliceInfoSection
+	if err := d.DecodeElement(&_s, &start); err != nil {
+		return err
+	}
+	*s = Scte35SpliceInfoSection(_s.wrappedScte35SpliceInfoSection)
+	return nil
+}
+
+func (s *Scte35SpliceInfoSection) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+	return e.Encode(&Scte35SpliceInfoSectionMarshal{
+		XMLName:            xml.Name{Local: "scte35:SpliceInfoSection"},
+		ProtocolVersion:    s.ProtocolVersion,
+		PtsAdjustment:      s.PtsAdjustment,
+		Tier:               s.Tier,
+		Scte35SpliceInsert: s.Scte35SpliceInsert,
+	})
+}

From ff2c68a4597fd616f41c588813c1a14f9d2cc999 Mon Sep 17 00:00:00 2001
From: Vishal Shah <vishshah00@gmail.com>
Date: Tue, 6 Jul 2021 19:50:23 -0700
Subject: [PATCH 13/32] fix: add github actions

---
 .github/workflows/build.yaml | 24 ++++++++++++++++++++++++
 Makefile                     |  2 +-
 go.mod                       |  2 +-
 3 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 .github/workflows/build.yaml

diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
new file mode 100644
index 0000000..9046565
--- /dev/null
+++ b/.github/workflows/build.yaml
@@ -0,0 +1,24 @@
+name: CI
+
+on:
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+    - name: Set up Go 1.16
+      uses: actions/setup-go@v2
+      with:
+        go-version: ^1.16
+
+    - name: Check out code into the Go module directory
+      uses: actions/checkout@v2
+
+    - name: Regenerate and Test
+      run: |
+        make clean fmt
+        make generate
diff --git a/Makefile b/Makefile
index 4606220..76ee3cf 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ endif
 .DEFAULT_GOAL := all
 
 .PHONY: all
-all: test
+all: clean fmt test
 
 .PHONY: test
 test:
diff --git a/go.mod b/go.mod
index da472a9..68e1baf 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
 module github.com/zencoder/go-dash/v3
 
-go 1.13
+go 1.16

From 5f022e391705f2f8e466a1a09ef58c37615328d3 Mon Sep 17 00:00:00 2001
From: Vishal Shah <vishshah00@gmail.com>
Date: Tue, 20 Jul 2021 17:57:20 -0700
Subject: [PATCH 14/32] fix: xml syntax error

---
 mpd/scte35.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mpd/scte35.go b/mpd/scte35.go
index 2621178..defbb2f 100644
--- a/mpd/scte35.go
+++ b/mpd/scte35.go
@@ -27,7 +27,7 @@ type Scte35SpliceInfoSection struct {
 	ProtocolVersion    *string             `xml:"protocolVersion,attr,omitempty"`
 	PtsAdjustment      *int64              `xml:"ptsAdjustment,attr,omitempty"`
 	Tier               *int64              `xml:"tier,attr,omitempty"`
-	Scte35SpliceInsert *Scte35SpliceInsert `xml:"SpliceInsert",omitempty"`
+	Scte35SpliceInsert *Scte35SpliceInsert `xml:"SpliceInsert,omitempty"`
 }
 
 type Scte35SpliceInsert struct {
@@ -104,7 +104,7 @@ type Scte35SpliceInfoSectionMarshal struct {
 	ProtocolVersion    *string             `xml:"protocolVersion,attr,omitempty"`
 	PtsAdjustment      *int64              `xml:"ptsAdjustment,attr,omitempty"`
 	Tier               *int64              `xml:"tier,attr,omitempty"`
-	Scte35SpliceInsert *Scte35SpliceInsert `xml:"SpliceInsert",omitempty"`
+	Scte35SpliceInsert *Scte35SpliceInsert `xml:"SpliceInsert,omitempty"`
 }
 
 type Scte35SpliceInsertMarshal struct {

From 66e55d5fe3ff65b413aa75799f6d70394e73c3b6 Mon Sep 17 00:00:00 2001
From: Thomas Symborski <thomas.symborski@gmail.com>
Date: Sun, 15 Aug 2021 13:59:15 -0400
Subject: [PATCH 15/32] mpd: map top-level cenc and mspr values in mpd element

---
 mpd/mpd.go | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mpd/mpd.go b/mpd/mpd.go
index 5f00840..4d673f0 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -73,6 +73,8 @@ type MPD struct {
 	Scte35NS                   *Scte35NS `xml:"scte35,attr,omitempty"`
 	XsiNS                      *XsiNS    `xml:"xsi,attr,omitempty"`
 	XsiSchemaLocation          *XsiSL    `xml:"schemaLocation,attr,omitempty"`
+	XsiCENC                    *XsiNS    `xml:"cenc,attr,omitempty"`
+	XsiMSPR                    *XsiNS    `xml:"mspr,attr,omitempty"`
 	Profiles                   *string   `xml:"profiles,attr"`
 	Type                       *string   `xml:"type,attr"`
 	MediaPresentationDuration  *string   `xml:"mediaPresentationDuration,attr"`

From c356e550b00d332f14f97fd79f5d1d43565226cd Mon Sep 17 00:00:00 2001
From: Thomas Symborski <thomas.symborski@gmail.com>
Date: Sun, 15 Aug 2021 14:18:19 -0400
Subject: [PATCH 16/32] fix: change mapping for extra xmlns attrs

---
 mpd/mpd.go | 46 ++++++++++++++++++++++------------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/mpd/mpd.go b/mpd/mpd.go
index 4d673f0..871cc41 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -5,6 +5,7 @@ import (
 	"encoding/hex"
 	"encoding/xml"
 	"errors"
+	"fmt"
 	"strings"
 	"time"
 
@@ -69,45 +70,42 @@ var (
 )
 
 type MPD struct {
-	XMLNs                      *string   `xml:"xmlns,attr"`
-	Scte35NS                   *Scte35NS `xml:"scte35,attr,omitempty"`
-	XsiNS                      *XsiNS    `xml:"xsi,attr,omitempty"`
-	XsiSchemaLocation          *XsiSL    `xml:"schemaLocation,attr,omitempty"`
-	XsiCENC                    *XsiNS    `xml:"cenc,attr,omitempty"`
-	XsiMSPR                    *XsiNS    `xml:"mspr,attr,omitempty"`
-	Profiles                   *string   `xml:"profiles,attr"`
-	Type                       *string   `xml:"type,attr"`
-	MediaPresentationDuration  *string   `xml:"mediaPresentationDuration,attr"`
-	MinBufferTime              *string   `xml:"minBufferTime,attr"`
-	AvailabilityStartTime      *string   `xml:"availabilityStartTime,attr,omitempty"`
-	MinimumUpdatePeriod        *string   `xml:"minimumUpdatePeriod,attr"`
-	PublishTime                *string   `xml:"publishTime,attr"`
-	TimeShiftBufferDepth       *string   `xml:"timeShiftBufferDepth,attr"`
-	SuggestedPresentationDelay *Duration `xml:"suggestedPresentationDelay,attr,omitempty"`
-	BaseURL                    string    `xml:"BaseURL,omitempty"`
-	Location                   string    `xml:"Location,omitempty"`
+	XMLNs                      *string    `xml:"xmlns,attr"`
+	Scte35NS                   *Scte35NS  `xml:"scte35,attr,omitempty"`
+	XsiNS                      *XmlnsAttr `xml:"xsi,attr,omitempty"`
+	XsiSchemaLocation          *XsiSL     `xml:"schemaLocation,attr,omitempty"`
+	XsiCENC                    *XmlnsAttr `xml:"cenc,attr,omitempty"`
+	XsiMSPR                    *XmlnsAttr `xml:"mspr,attr,omitempty"`
+	Profiles                   *string    `xml:"profiles,attr"`
+	Type                       *string    `xml:"type,attr"`
+	MediaPresentationDuration  *string    `xml:"mediaPresentationDuration,attr"`
+	MinBufferTime              *string    `xml:"minBufferTime,attr"`
+	AvailabilityStartTime      *string    `xml:"availabilityStartTime,attr,omitempty"`
+	MinimumUpdatePeriod        *string    `xml:"minimumUpdatePeriod,attr"`
+	PublishTime                *string    `xml:"publishTime,attr"`
+	TimeShiftBufferDepth       *string    `xml:"timeShiftBufferDepth,attr"`
+	SuggestedPresentationDelay *Duration  `xml:"suggestedPresentationDelay,attr,omitempty"`
+	BaseURL                    string     `xml:"BaseURL,omitempty"`
+	Location                   string     `xml:"Location,omitempty"`
 	period                     *Period
 	Periods                    []*Period       `xml:"Period,omitempty"`
 	UTCTiming                  *DescriptorType `xml:"UTCTiming,omitempty"`
 	ID                         string          `xml:"id,attr,omitempty"`
 }
 
-type XsiNS struct {
+type XmlnsAttr struct {
 	XmlName xml.Name
 	Value   string
 }
 
-func (s *XsiNS) UnmarshalXMLAttr(attr xml.Attr) error {
+func (s *XmlnsAttr) UnmarshalXMLAttr(attr xml.Attr) error {
 	s.XmlName = attr.Name
 	s.Value = attr.Value
 	return nil
 }
 
-func (s *XsiNS) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
-	if strings.Contains(s.XmlName.Local, "xsi") {
-		return xml.Attr{Name: xml.Name{Local: "xmlns:xsi"}, Value: s.Value}, nil
-	}
-	return xml.Attr{}, nil
+func (s *XmlnsAttr) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
+	return xml.Attr{Name: xml.Name{Local: fmt.Sprintf("xmlns:%s", s.XmlName.Local)}, Value: s.Value}, nil
 }
 
 type XsiSL struct {

From 943559d062f6cead45f60618ff1fcef17fb44486 Mon Sep 17 00:00:00 2001
From: Brogan <broganross@gmail.com>
Date: Fri, 25 Aug 2023 15:39:30 -0700
Subject: [PATCH 17/32] Adds support for reading and writing a comment that
 comes after the xml prolog and before the root element of the XML.

---
 mpd/fixtures/comment.mpd   |  3 +++
 mpd/mpd.go                 |  1 +
 mpd/mpd_read_write.go      | 44 ++++++++++++++++++++++++++++++++------
 mpd/mpd_read_write_test.go | 17 +++++++++++++++
 4 files changed, 58 insertions(+), 7 deletions(-)
 create mode 100644 mpd/fixtures/comment.mpd

diff --git a/mpd/fixtures/comment.mpd b/mpd/fixtures/comment.mpd
new file mode 100644
index 0000000..d8b1c73
--- /dev/null
+++ b/mpd/fixtures/comment.mpd
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Generated with https://github.com/shaka-project/shaka-packager version 288eddc863-release-->
+<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic" availabilityStartTime="1970-01-01T00:00:00Z" minimumUpdatePeriod="PT5S" publishTime="1970-01-01T00:00:00Z"></MPD>
diff --git a/mpd/mpd.go b/mpd/mpd.go
index 5f00840..38827bf 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -88,6 +88,7 @@ type MPD struct {
 	Periods                    []*Period       `xml:"Period,omitempty"`
 	UTCTiming                  *DescriptorType `xml:"UTCTiming,omitempty"`
 	ID                         string          `xml:"id,attr,omitempty"`
+	Comment                    string          `xml:"-"`
 }
 
 type XsiNS struct {
diff --git a/mpd/mpd_read_write.go b/mpd/mpd_read_write.go
index 35d3f9f..dd9e41e 100644
--- a/mpd/mpd_read_write.go
+++ b/mpd/mpd_read_write.go
@@ -32,7 +32,24 @@ func ReadFromString(xmlStr string) (*MPD, error) {
 func Read(r io.Reader) (*MPD, error) {
 	var mpd MPD
 	d := xml.NewDecoder(r)
-	err := d.Decode(&mpd)
+	var start *xml.StartElement
+	for {
+		token, err := d.Token()
+		if err != nil {
+			return nil, err
+		}
+		switch token := token.(type) {
+		case xml.Comment:
+			mpd.Comment = string(token.Copy())
+		case xml.StartElement:
+			start = &token
+		default:
+		}
+		if start != nil {
+			break
+		}
+	}
+	err := d.DecodeElement(&mpd, start)
 	if err != nil {
 		return nil, err
 	}
@@ -75,13 +92,26 @@ func (m *MPD) WriteToString() (string, error) {
 // Writes an MPD object to an io.Writer interface
 // w - Must implement the io.Writer interface.
 func (m *MPD) Write(w io.Writer) error {
-	b, err := xml.MarshalIndent(m, "", "  ")
+	_, err := w.Write([]byte(xml.Header))
 	if err != nil {
 		return err
 	}
-
-	_, _ = w.Write([]byte(xml.Header))
-	_, _ = w.Write(b)
-	_, _ = w.Write([]byte("\n"))
-	return nil
+	e := xml.NewEncoder(w)
+	e.Indent("", "  ")
+	if string(m.Comment) != "" {
+		if err := e.EncodeToken(xml.Comment(m.Comment)); err != nil {
+			return err
+		}
+		if err := e.Flush(); err != nil {
+			return err
+		}
+		if _, err := w.Write([]byte("\n")); err != nil {
+			return err
+		}
+	}
+	if err := e.Encode(m); err != nil {
+		return err
+	}
+	_, err = w.Write([]byte("\n"))
+	return err
 }
diff --git a/mpd/mpd_read_write_test.go b/mpd/mpd_read_write_test.go
index 890905f..7effffb 100644
--- a/mpd/mpd_read_write_test.go
+++ b/mpd/mpd_read_write_test.go
@@ -489,3 +489,20 @@ func TestWriteToFileTruncate(t *testing.T) {
 	xmlStr = testfixtures.LoadFixture(out)
 	testfixtures.CompareFixture(t, "fixtures/truncate_short.mpd", xmlStr)
 }
+
+func TestReadComment(t *testing.T) {
+	m, err := ReadFromFile("fixtures/comment.mpd")
+	require.NoError(t, err)
+	require.EqualString(t, "Generated with https://github.com/shaka-project/shaka-packager version 288eddc863-release", string(m.Comment))
+}
+
+func TestWriteComment(t *testing.T) {
+	m := MPD{Comment: "Leading Comment"}
+	s, err := m.WriteToString()
+	require.NoError(t, err)
+	answer := `<?xml version="1.0" encoding="UTF-8"?>
+<!--Leading Comment-->
+<MPD></MPD>
+`
+	require.EqualString(t, answer, s)
+}

From 7bcf639d44582cc22407cf16c2a24a8a1d5d02e0 Mon Sep 17 00:00:00 2001
From: Brogan <broganross@gmail.com>
Date: Mon, 28 Aug 2023 09:58:02 -0700
Subject: [PATCH 18/32] add comments to more tests

---
 mpd/fixtures/segment_list.mpd | 1 +
 mpd/fixtures/truncate.mpd     | 1 +
 mpd/segment_list_test.go      | 3 ++-
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/mpd/fixtures/segment_list.mpd b/mpd/fixtures/segment_list.mpd
index 57aed4d..2fc7de9 100644
--- a/mpd/fixtures/segment_list.mpd
+++ b/mpd/fixtures/segment_list.mpd
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--Generated with https://github.com/shaka-project/shaka-packager version 288eddc863-release-->
 <MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" mediaPresentationDuration="PT30.016S" minBufferTime="PT2.000S">
   <Period>
     <BaseURL>http://localhost:8002/dash/</BaseURL>
diff --git a/mpd/fixtures/truncate.mpd b/mpd/fixtures/truncate.mpd
index 0b1be61..bf92528 100644
--- a/mpd/fixtures/truncate.mpd
+++ b/mpd/fixtures/truncate.mpd
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--Generated with https://github.com/shaka-project/shaka-packager version 288eddc863-release-->
 <MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic" minBufferTime="PT2S" availabilityStartTime="2019-12-03T20:57:14Z" minimumUpdatePeriod="PT5S" publishTime="2019-12-03T21:05:05Z" timeShiftBufferDepth="PT120S">
   <Period id="0">
     <AdaptationSet frameRate="90000/3000" id="0" segmentAlignment="true" maxWidth="720" contentType="video">
diff --git a/mpd/segment_list_test.go b/mpd/segment_list_test.go
index d8205be..237a759 100644
--- a/mpd/segment_list_test.go
+++ b/mpd/segment_list_test.go
@@ -22,7 +22,7 @@ func TestSegmentListDeserialization(t *testing.T) {
 	require.NoError(t, err)
 	if err == nil {
 		expected := getSegmentListMPD()
-
+		require.EqualString(t, m.Comment, "Generated with https://github.com/shaka-project/shaka-packager version 288eddc863-release")
 		require.EqualString(t, expected.Periods[0].BaseURL, m.Periods[0].BaseURL)
 
 		expectedAudioSegList := expected.Periods[0].AdaptationSets[0].Representations[0].SegmentList
@@ -59,6 +59,7 @@ func TestSegmentListDeserialization(t *testing.T) {
 
 func getSegmentListMPD() *MPD {
 	m := NewMPD(DASH_PROFILE_LIVE, "PT30.016S", "PT2.000S")
+	m.Comment = "Generated with https://github.com/shaka-project/shaka-packager version 288eddc863-release"
 	m.period.BaseURL = "http://localhost:8002/dash/"
 
 	aas, _ := m.AddNewAdaptationSetAudioWithID("1", "audio/mp4", true, 1, "English")

From 85e5a88b86f6edc225835968eb2b02b3cdda2815 Mon Sep 17 00:00:00 2001
From: bpogy <boris.pogrebitskiy@paramount.com>
Date: Fri, 8 Dec 2023 13:13:48 -0700
Subject: [PATCH 19/32] fix for duration format with precision sign char

---
 go.sum          | 210 ++++++++++++++++++++++++++++++++++++++++++++++++
 mpd/duration.go |  28 +++----
 2 files changed, 223 insertions(+), 15 deletions(-)
 create mode 100644 go.sum

diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..bd095dd
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,210 @@
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/go-chrono/chrono v0.0.0-20230818115516-ffa53a1a2b89 h1:16mXulbPd6gctcsEgt8LRM01heZVbRxvCyPqErtTxM8=
+github.com/go-chrono/chrono v0.0.0-20230818115516-ffa53a1a2b89/go.mod h1:uTWQdzrjtft2vWY+f+KQ9e3DXHsP0SzhE5SLIicFo08=
+github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
+github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
+github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
+github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
+github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0=
+github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
+github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
+github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo=
+github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc=
+github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk=
+github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
+github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
+github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
+github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0=
+github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
+github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
+github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
+github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
+github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
+github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
+github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
+github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
+github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
+github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw=
+github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
+github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
+github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4=
+github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
+github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rickb777/date v1.20.5 h1:Ybjz7J7ga9ui4VJizQpil0l330r6wkn6CicaoattIxQ=
+github.com/rickb777/date v1.20.5/go.mod h1:6BPrm3/aQI0I8jvlD1fAlm/86k5eSeTQ2mR5FEmTnSw=
+github.com/rickb777/plural v1.4.1 h1:5MMLcbIaapLFmvDGRT5iPk8877hpTPt8Y9cdSKRw9sU=
+github.com/rickb777/plural v1.4.1/go.mod h1:kdmXUpmKBJTS0FtG/TFumd//VBWsNTD7zOw7x4umxNw=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
+golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
+golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
+golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
+golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
+golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
+golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
+golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
+golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
+golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
+golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/mpd/duration.go b/mpd/duration.go
index 8ebc870..a2dbc34 100644
--- a/mpd/duration.go
+++ b/mpd/duration.go
@@ -54,27 +54,25 @@ func (d *Duration) String() string {
 	if u < uint64(time.Second) {
 		// Special case: if duration is smaller than a second,
 		// use smaller units, like 1.2ms
+		// BP. replaced nano ('n'), micro ('µ') and milliseconds ('m') chars with '0' that is correctly parsed.
 		var prec int
 		w--
 		buf[w] = 'S'
 		w--
-		if u == 0 {
+		switch {
+		case u == 0:
 			return "PT0S"
+		case u < uint64(time.Microsecond):
+			// print nanoseconds
+			prec = 0
+		case u < uint64(time.Millisecond):
+			// print microseconds
+			prec = 3
+		default:
+			// print milliseconds
+			prec = 6
 		}
-		/*
-			switch {
-			case u < uint64(Millisecond):
-				// print microseconds
-				prec = 3
-				// U+00B5 'µ' micro sign == 0xC2 0xB5
-				w-- // Need room for two bytes.
-				copy(buf[w:], "µ")
-			default:
-				// print milliseconds
-				prec = 6
-				buf[w] = 'm'
-			}
-		*/
+		buf[w] = '0'
 		w, u = fmtFrac(buf[:w], u, prec)
 		w = fmtInt(buf[:w], u)
 	} else {

From 0477c242ee396d1b80fad7d7ed25feee3260ca1d Mon Sep 17 00:00:00 2001
From: bpogy <boris.pogrebitskiy@paramount.com>
Date: Fri, 8 Dec 2023 13:23:23 -0700
Subject: [PATCH 20/32] fix for ISO 8601 duration format

---
 mpd/duration.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mpd/duration.go b/mpd/duration.go
index a2dbc34..898955d 100644
--- a/mpd/duration.go
+++ b/mpd/duration.go
@@ -54,7 +54,7 @@ func (d *Duration) String() string {
 	if u < uint64(time.Second) {
 		// Special case: if duration is smaller than a second,
 		// use smaller units, like 1.2ms
-		// BP. replaced nano ('n'), micro ('µ') and milliseconds ('m') chars with '0' that is correctly parsed.
+		// BP. replaced nano ('n'), micro ('µ') and milliseconds ('m') chars with '0' that fixes format.
 		var prec int
 		w--
 		buf[w] = 'S'

From b7a0c49803d512bdf5488e3c7fda0de5d2b143a8 Mon Sep 17 00:00:00 2001
From: bpogy <boris.pogrebitskiy@paramount.com>
Date: Fri, 8 Dec 2023 13:54:58 -0700
Subject: [PATCH 21/32] fix

---
 go.sum          | 210 ------------------------------------------------
 mpd/duration.go |   3 +-
 2 files changed, 2 insertions(+), 211 deletions(-)

diff --git a/go.sum b/go.sum
index bd095dd..e69de29 100644
--- a/go.sum
+++ b/go.sum
@@ -1,210 +0,0 @@
-github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
-github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
-github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/go-chrono/chrono v0.0.0-20230818115516-ffa53a1a2b89 h1:16mXulbPd6gctcsEgt8LRM01heZVbRxvCyPqErtTxM8=
-github.com/go-chrono/chrono v0.0.0-20230818115516-ffa53a1a2b89/go.mod h1:uTWQdzrjtft2vWY+f+KQ9e3DXHsP0SzhE5SLIicFo08=
-github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
-github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
-github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
-github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
-github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
-github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
-github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0=
-github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
-github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
-github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo=
-github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc=
-github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk=
-github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
-github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
-github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
-github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0=
-github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
-github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
-github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
-github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
-github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
-github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
-github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
-github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
-github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
-github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
-github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw=
-github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
-github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
-github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4=
-github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
-github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rickb777/date v1.20.5 h1:Ybjz7J7ga9ui4VJizQpil0l330r6wkn6CicaoattIxQ=
-github.com/rickb777/date v1.20.5/go.mod h1:6BPrm3/aQI0I8jvlD1fAlm/86k5eSeTQ2mR5FEmTnSw=
-github.com/rickb777/plural v1.4.1 h1:5MMLcbIaapLFmvDGRT5iPk8877hpTPt8Y9cdSKRw9sU=
-github.com/rickb777/plural v1.4.1/go.mod h1:kdmXUpmKBJTS0FtG/TFumd//VBWsNTD7zOw7x4umxNw=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
-golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
-golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
-golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
-golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
-golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
-golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
-golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
-golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
-golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
-golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
-golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
-golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
-golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
-golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/mpd/duration.go b/mpd/duration.go
index 898955d..3cb7fe8 100644
--- a/mpd/duration.go
+++ b/mpd/duration.go
@@ -54,7 +54,8 @@ func (d *Duration) String() string {
 	if u < uint64(time.Second) {
 		// Special case: if duration is smaller than a second,
 		// use smaller units, like 1.2ms
-		// BP. replaced nano ('n'), micro ('µ') and milliseconds ('m') chars with '0' that fixes format.
+		// time.Duration injects a nano ('n'), micro ('µ') or milliseconds ('m') char before 'S'
+		// Fix for "Duration must be in the format: P[nD][T[nH][nM][nS]]" error, is to insert '0' instead of a nil char.
 		var prec int
 		w--
 		buf[w] = 'S'

From 71b4879385213a13bd7f92021db6b3d3bdf43434 Mon Sep 17 00:00:00 2001
From: bpogy <boris.pogrebitskiy@paramount.com>
Date: Fri, 8 Dec 2023 13:56:39 -0700
Subject: [PATCH 22/32] cleanup

---
 go.sum | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 go.sum

diff --git a/go.sum b/go.sum
deleted file mode 100644
index e69de29..0000000

From 7c633daecaec9121a8d664dc6002d4465d6a213e Mon Sep 17 00:00:00 2001
From: bpogy <boris.pogrebitskiy@paramount.com>
Date: Mon, 18 Dec 2023 10:13:13 -0700
Subject: [PATCH 23/32] duration to string conversion fix

---
 go.mod               |  2 +-
 mpd/duration.go      | 28 ++++++++--------------------
 mpd/duration_test.go |  9 ++++++---
 3 files changed, 15 insertions(+), 24 deletions(-)

diff --git a/go.mod b/go.mod
index 68e1baf..9684294 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
 module github.com/zencoder/go-dash/v3
 
-go 1.16
+go 1.19
diff --git a/mpd/duration.go b/mpd/duration.go
index 3cb7fe8..9baacf3 100644
--- a/mpd/duration.go
+++ b/mpd/duration.go
@@ -54,28 +54,16 @@ func (d *Duration) String() string {
 	if u < uint64(time.Second) {
 		// Special case: if duration is smaller than a second,
 		// use smaller units, like 1.2ms
-		// time.Duration injects a nano ('n'), micro ('µ') or milliseconds ('m') char before 'S'
-		// Fix for "Duration must be in the format: P[nD][T[nH][nM][nS]]" error, is to insert '0' instead of a nil char.
-		var prec int
-		w--
-		buf[w] = 'S'
-		w--
-		switch {
-		case u == 0:
+		// time.Duration & zerocoder packages convert seconds to nano ('nS'), micro ('µS') or milliseconds ('mS') with corresponding designation
+		// Fix for "Duration must be in the format: P[nD][T[nH][nM][nS]]" error is to keep seconds.
+		if u == 0 {
 			return "PT0S"
-		case u < uint64(time.Microsecond):
-			// print nanoseconds
-			prec = 0
-		case u < uint64(time.Millisecond):
-			// print microseconds
-			prec = 3
-		default:
-			// print milliseconds
-			prec = 6
+		} else {
+			du := float64(u) / float64(time.Second)
+			s := fmt.Sprintf("%2f", du)
+			sf := strings.TrimRight(s, "0")
+			return fmt.Sprintf("PT%sS", sf)
 		}
-		buf[w] = '0'
-		w, u = fmtFrac(buf[:w], u, prec)
-		w = fmtInt(buf[:w], u)
 	} else {
 		w--
 		buf[w] = 'S'
diff --git a/mpd/duration_test.go b/mpd/duration_test.go
index edd29b6..640b14b 100644
--- a/mpd/duration_test.go
+++ b/mpd/duration_test.go
@@ -10,9 +10,12 @@ import (
 
 func TestDuration(t *testing.T) {
 	in := map[string]string{
-		"0s":    "PT0S",
-		"6m16s": "PT6M16S",
-		"1.97s": "PT1.97S",
+		"0s":            "PT0S",
+		"6m16s":         "PT6M16S",
+		"1.97s":         "PT1.97S",
+		"0.0021s":       "PT0.0021S",
+		"0.0000021s":    "PT0.000002S",
+		"0.021s":        "PT0.021S",
 	}
 	for ins, ex := range in {
 		timeDur, err := time.ParseDuration(ins)

From 4574847ee58c676b5fb772069af4d8c47b5d40d3 Mon Sep 17 00:00:00 2001
From: bpogy <boris.pogrebitskiy@paramount.com>
Date: Mon, 18 Dec 2023 10:19:11 -0700
Subject: [PATCH 24/32] go v change to 1.18

---
 go.mod | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/go.mod b/go.mod
index 9684294..ab49f91 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
 module github.com/zencoder/go-dash/v3
 
-go 1.19
+go 1.18
\ No newline at end of file

From 178c1304fe75e6efa4ebe1eb92b2213842297f51 Mon Sep 17 00:00:00 2001
From: bpogy <boris.pogrebitskiy@paramount.com>
Date: Mon, 18 Dec 2023 10:28:40 -0700
Subject: [PATCH 25/32] updates

---
 go.mod          | 2 +-
 mpd/duration.go | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/go.mod b/go.mod
index ab49f91..8b6b3f9 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
 module github.com/zencoder/go-dash/v3
 
-go 1.18
\ No newline at end of file
+go 1.16
\ No newline at end of file
diff --git a/mpd/duration.go b/mpd/duration.go
index 9baacf3..17fce28 100644
--- a/mpd/duration.go
+++ b/mpd/duration.go
@@ -51,7 +51,7 @@ func (d *Duration) String() string {
 		u = -u
 	}
 
-	if u < uint64(time.Second) {
+	if u <= uint64(time.Second) {
 		// Special case: if duration is smaller than a second,
 		// use smaller units, like 1.2ms
 		// time.Duration & zerocoder packages convert seconds to nano ('nS'), micro ('µS') or milliseconds ('mS') with corresponding designation

From 0f6798169852258aab58b0740a3ff660d01ea6e4 Mon Sep 17 00:00:00 2001
From: bpogy <boris.pogrebitskiy@paramount.com>
Date: Tue, 19 Dec 2023 07:33:44 -0700
Subject: [PATCH 26/32] clean up

---
 mpd/duration.go      |  2 +-
 mpd/duration_test.go | 13 +++++++------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/mpd/duration.go b/mpd/duration.go
index 17fce28..9baacf3 100644
--- a/mpd/duration.go
+++ b/mpd/duration.go
@@ -51,7 +51,7 @@ func (d *Duration) String() string {
 		u = -u
 	}
 
-	if u <= uint64(time.Second) {
+	if u < uint64(time.Second) {
 		// Special case: if duration is smaller than a second,
 		// use smaller units, like 1.2ms
 		// time.Duration & zerocoder packages convert seconds to nano ('nS'), micro ('µS') or milliseconds ('mS') with corresponding designation
diff --git a/mpd/duration_test.go b/mpd/duration_test.go
index 640b14b..3d2c612 100644
--- a/mpd/duration_test.go
+++ b/mpd/duration_test.go
@@ -10,12 +10,13 @@ import (
 
 func TestDuration(t *testing.T) {
 	in := map[string]string{
-		"0s":            "PT0S",
-		"6m16s":         "PT6M16S",
-		"1.97s":         "PT1.97S",
-		"0.0021s":       "PT0.0021S",
-		"0.0000021s":    "PT0.000002S",
-		"0.021s":        "PT0.021S",
+		"0s":         "PT0S",
+		"6m16s":      "PT6M16S",
+		"1.97s":      "PT1.97S",
+		"1.0s":       "PT1S",
+		"0.0021s":    "PT0.0021S",
+		"0.0000021s": "PT0.000002S",
+		"0.021s":     "PT0.021S",
 	}
 	for ins, ex := range in {
 		timeDur, err := time.ParseDuration(ins)

From 68a80e73bad237800827854af40aeba7fe367b95 Mon Sep 17 00:00:00 2001
From: Ron Lenk <rlenk@users.noreply.github.com>
Date: Wed, 17 Jan 2024 11:38:46 -0500
Subject: [PATCH 27/32] Rename package from `zencoder/go-dash` to
 `cbsinteractive/go-dash`

---
 examples/live.go                     | 2 +-
 examples/ondemand.go                 | 2 +-
 go.mod                               | 4 ++--
 helpers/testfixtures/testfixtures.go | 2 +-
 mpd/duration_test.go                 | 2 +-
 mpd/events_test.go                   | 6 +++---
 mpd/mpd.go                           | 2 +-
 mpd/mpd_read_write_test.go           | 6 +++---
 mpd/mpd_test.go                      | 6 +++---
 mpd/pssh_test.go                     | 2 +-
 mpd/segment_list_test.go             | 6 +++---
 mpd/segment_timeline_test.go         | 6 +++---
 12 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/examples/live.go b/examples/live.go
index dd955a6..f18ae1f 100644
--- a/examples/live.go
+++ b/examples/live.go
@@ -3,7 +3,7 @@ package main
 import (
 	"fmt"
 
-	"github.com/zencoder/go-dash/v3/mpd"
+	"github.com/cbsinteractive/go-dash/v3/mpd"
 )
 
 func main() {
diff --git a/examples/ondemand.go b/examples/ondemand.go
index 54463f2..cf95c04 100644
--- a/examples/ondemand.go
+++ b/examples/ondemand.go
@@ -3,7 +3,7 @@ package main
 import (
 	"fmt"
 
-	"github.com/zencoder/go-dash/v3/mpd"
+	"github.com/cbsinteractive/go-dash/v3/mpd"
 )
 
 func exampleOndemand() {
diff --git a/go.mod b/go.mod
index 8b6b3f9..d60a7c1 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
-module github.com/zencoder/go-dash/v3
+module github.com/cbsinteractive/go-dash/v3
 
-go 1.16
\ No newline at end of file
+go 1.16
diff --git a/helpers/testfixtures/testfixtures.go b/helpers/testfixtures/testfixtures.go
index b027358..d00a071 100644
--- a/helpers/testfixtures/testfixtures.go
+++ b/helpers/testfixtures/testfixtures.go
@@ -6,7 +6,7 @@ import (
 	"os"
 	"testing"
 
-	"github.com/zencoder/go-dash/v3/helpers/require"
+	"github.com/cbsinteractive/go-dash/v3/helpers/require"
 )
 
 // Load test fixture from path relative to fixtures directory
diff --git a/mpd/duration_test.go b/mpd/duration_test.go
index 3d2c612..15b7695 100644
--- a/mpd/duration_test.go
+++ b/mpd/duration_test.go
@@ -5,7 +5,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/zencoder/go-dash/v3/helpers/require"
+	"github.com/cbsinteractive/go-dash/v3/helpers/require"
 )
 
 func TestDuration(t *testing.T) {
diff --git a/mpd/events_test.go b/mpd/events_test.go
index fd204cf..6028e10 100644
--- a/mpd/events_test.go
+++ b/mpd/events_test.go
@@ -3,9 +3,9 @@ package mpd
 import (
 	"testing"
 
-	"github.com/zencoder/go-dash/v3/helpers/ptrs"
-	"github.com/zencoder/go-dash/v3/helpers/require"
-	"github.com/zencoder/go-dash/v3/helpers/testfixtures"
+	"github.com/cbsinteractive/go-dash/v3/helpers/ptrs"
+	"github.com/cbsinteractive/go-dash/v3/helpers/require"
+	"github.com/cbsinteractive/go-dash/v3/helpers/testfixtures"
 )
 
 const (
diff --git a/mpd/mpd.go b/mpd/mpd.go
index 5f3c08c..0eb36e7 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -9,7 +9,7 @@ import (
 	"strings"
 	"time"
 
-	. "github.com/zencoder/go-dash/v3/helpers/ptrs"
+	. "github.com/cbsinteractive/go-dash/v3/helpers/ptrs"
 )
 
 // Type definition for DASH profiles
diff --git a/mpd/mpd_read_write_test.go b/mpd/mpd_read_write_test.go
index b40a843..6934faf 100644
--- a/mpd/mpd_read_write_test.go
+++ b/mpd/mpd_read_write_test.go
@@ -5,9 +5,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/zencoder/go-dash/v3/helpers/ptrs"
-	"github.com/zencoder/go-dash/v3/helpers/require"
-	"github.com/zencoder/go-dash/v3/helpers/testfixtures"
+	"github.com/cbsinteractive/go-dash/v3/helpers/ptrs"
+	"github.com/cbsinteractive/go-dash/v3/helpers/require"
+	"github.com/cbsinteractive/go-dash/v3/helpers/testfixtures"
 )
 
 func TestReadingManifests(t *testing.T) {
diff --git a/mpd/mpd_test.go b/mpd/mpd_test.go
index e6c940d..39d4146 100644
--- a/mpd/mpd_test.go
+++ b/mpd/mpd_test.go
@@ -6,9 +6,9 @@ import (
 	"strconv"
 	"testing"
 
-	. "github.com/zencoder/go-dash/v3/helpers/ptrs"
-	"github.com/zencoder/go-dash/v3/helpers/require"
-	"github.com/zencoder/go-dash/v3/helpers/testfixtures"
+	. "github.com/cbsinteractive/go-dash/v3/helpers/ptrs"
+	"github.com/cbsinteractive/go-dash/v3/helpers/require"
+	"github.com/cbsinteractive/go-dash/v3/helpers/testfixtures"
 )
 
 const (
diff --git a/mpd/pssh_test.go b/mpd/pssh_test.go
index a681194..e531c1c 100644
--- a/mpd/pssh_test.go
+++ b/mpd/pssh_test.go
@@ -3,7 +3,7 @@ package mpd
 import (
 	"encoding/base64"
 	"encoding/hex"
-	"github.com/zencoder/go-dash/v3/helpers/require"
+	"github.com/cbsinteractive/go-dash/v3/helpers/require"
 	"testing"
 )
 
diff --git a/mpd/segment_list_test.go b/mpd/segment_list_test.go
index 483cd39..49f364d 100644
--- a/mpd/segment_list_test.go
+++ b/mpd/segment_list_test.go
@@ -3,9 +3,9 @@ package mpd
 import (
 	"testing"
 
-	"github.com/zencoder/go-dash/v3/helpers/ptrs"
-	"github.com/zencoder/go-dash/v3/helpers/require"
-	"github.com/zencoder/go-dash/v3/helpers/testfixtures"
+	"github.com/cbsinteractive/go-dash/v3/helpers/ptrs"
+	"github.com/cbsinteractive/go-dash/v3/helpers/require"
+	"github.com/cbsinteractive/go-dash/v3/helpers/testfixtures"
 )
 
 func TestSegmentListSerialization(t *testing.T) {
diff --git a/mpd/segment_timeline_test.go b/mpd/segment_timeline_test.go
index 1e9ee1d..29997e8 100644
--- a/mpd/segment_timeline_test.go
+++ b/mpd/segment_timeline_test.go
@@ -5,9 +5,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/zencoder/go-dash/v3/helpers/ptrs"
-	"github.com/zencoder/go-dash/v3/helpers/require"
-	"github.com/zencoder/go-dash/v3/helpers/testfixtures"
+	"github.com/cbsinteractive/go-dash/v3/helpers/ptrs"
+	"github.com/cbsinteractive/go-dash/v3/helpers/require"
+	"github.com/cbsinteractive/go-dash/v3/helpers/testfixtures"
 )
 
 func TestSegmentTimelineSerialization(t *testing.T) {

From 3ec8553f0b0eb47ec092601ec389586fcdb901e5 Mon Sep 17 00:00:00 2001
From: Vishal Shah <vishshah00@gmail.com>
Date: Thu, 8 Feb 2024 10:48:44 -0700
Subject: [PATCH 28/32] update tests

---
 mpd/fixtures/hbbtv_profile.mpd |  4 +--
 mpd/test-ondemand.mpd          | 50 ----------------------------------
 mpd/test_live.mpd              | 41 ----------------------------
 mpd/test_live_dynamic.mpd      | 42 ----------------------------
 4 files changed, 2 insertions(+), 135 deletions(-)
 delete mode 100644 mpd/test-ondemand.mpd
 delete mode 100644 mpd/test_live.mpd
 delete mode 100644 mpd/test_live_dynamic.mpd

diff --git a/mpd/fixtures/hbbtv_profile.mpd b/mpd/fixtures/hbbtv_profile.mpd
index 3f49956..f9d2994 100644
--- a/mpd/fixtures/hbbtv_profile.mpd
+++ b/mpd/fixtures/hbbtv_profile.mpd
@@ -34,10 +34,10 @@
       <Representation bandwidth="2780732" codecs="avc1.4d401f" frameRate="30000/1001" height="720" id="1500" width="1280"></Representation>
     </AdaptationSet>
     <AdaptationSet mimeType="text/vtt" id="7357" lang="en">
+      <Label>Subtitle (En)</Label>
       <Representation bandwidth="256" id="subtitle_en">
         <BaseURL>http://example.com/content/sintel/subtitles/subtitles_en.vtt</BaseURL>
-      </Representation>
-      <Label>Subtitle (En)</Label>
+      </Representation>      
     </AdaptationSet>
   </Period>
 </MPD>
diff --git a/mpd/test-ondemand.mpd b/mpd/test-ondemand.mpd
deleted file mode 100644
index adeb578..0000000
--- a/mpd/test-ondemand.mpd
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" mediaPresentationDuration="PT30S" minBufferTime="PT1.97S">
-  <Period>
-    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="und" selectionPriority="3">
-      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
-      </ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
-        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
-      </ContentProtection>
-      <Representation audioSamplingRate="44100" bandwidth="128558" codecs="mp4a.40.5" id="800k/audio-und">
-        <BaseURL>800k/output-audio-und.mp4</BaseURL>
-        <SegmentBase indexRange="629-756">
-          <Initialization range="0-628"></Initialization>
-        </SegmentBase>
-      </Representation>
-      <Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
-    </AdaptationSet>
-    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true">
-      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
-      </ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
-        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
-      </ContentProtection>
-      <Representation bandwidth="1100690" codecs="avc1.4d401e" frameRate="30000/1001" height="360" id="800k/video-1" width="640">
-        <BaseURL>800k/output-video-1.mp4</BaseURL>
-        <SegmentBase indexRange="686-813">
-          <Initialization range="0-685"></Initialization>
-        </SegmentBase>
-      </Representation>
-      <Representation bandwidth="1633516" codecs="avc1.4d401f" frameRate="30000/1001" height="540" id="1200k/video-1" width="960">
-        <BaseURL>1200k/output-video-1.mp4</BaseURL>
-        <SegmentBase indexRange="686-813">
-          <Initialization range="0-685"></Initialization>
-        </SegmentBase>
-      </Representation>
-    </AdaptationSet>
-    <AdaptationSet mimeType="text/vtt" id="7357" lang="en">
-      <Label>Subtitle (En)</Label>
-      <Representation bandwidth="256" id="subtitle_en">
-        <BaseURL>http://example.com/content/sintel/subtitles/subtitles_en.vtt</BaseURL>
-      </Representation>
-    </AdaptationSet>
-  </Period>
-</MPD>
diff --git a/mpd/test_live.mpd b/mpd/test_live.mpd
deleted file mode 100644
index 118c99e..0000000
--- a/mpd/test_live.mpd
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" mediaPresentationDuration="PT6M16S" minBufferTime="PT1.97S" availabilityStartTime="1970-01-01T00:00:00Z">
-  <Period>
-    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="en">
-      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
-      </ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
-        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
-      </ContentProtection>
-      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
-      <SegmentTemplate duration="1968" initialization="$RepresentationID$/audio/en/init.mp4" media="$RepresentationID$/audio/en/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
-      <Representation audioSamplingRate="44100" bandwidth="67095" codecs="mp4a.40.2" id="800"></Representation>
-      <Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
-    </AdaptationSet>
-    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true">
-      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
-      </ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
-        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
-      </ContentProtection>
-      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
-      <SegmentTemplate duration="1968" initialization="$RepresentationID$/video/1/init.mp4" media="$RepresentationID$/video/1/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
-      <Representation bandwidth="1518664" codecs="avc1.4d401f" frameRate="30000/1001" height="540" id="800" width="960"></Representation>
-      <Representation bandwidth="1911775" codecs="avc1.4d401f" frameRate="30000/1001" height="576" id="1000" width="1024"></Representation>
-      <Representation bandwidth="2295158" codecs="avc1.4d401f" frameRate="30000/1001" height="576" id="1200" width="1024"></Representation>
-      <Representation bandwidth="2780732" codecs="avc1.4d401f" frameRate="30000/1001" height="720" id="1500" width="1280"></Representation>
-    </AdaptationSet>
-    <AdaptationSet mimeType="text/vtt" id="7357" lang="en">
-      <Label>Subtitle (En)</Label>
-      <Representation bandwidth="256" id="subtitle_en">
-        <BaseURL>http://example.com/content/sintel/subtitles/subtitles_en.vtt</BaseURL>
-      </Representation>
-    </AdaptationSet>
-  </Period>
-</MPD>
diff --git a/mpd/test_live_dynamic.mpd b/mpd/test_live_dynamic.mpd
deleted file mode 100644
index 55ce628..0000000
--- a/mpd/test_live_dynamic.mpd
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic" mediaPresentationDuration="PT6M16S" minBufferTime="PT1.97S" availabilityStartTime="1970-01-01T00:00:00Z" minimumUpdatePeriod="PT5S">
-  <Period>
-    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="en">
-      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
-      </ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
-        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
-      </ContentProtection>
-      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
-      <SegmentTemplate duration="1968" initialization="$RepresentationID$/audio/en/init.mp4" media="$RepresentationID$/audio/en/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
-      <Representation audioSamplingRate="44100" bandwidth="67095" codecs="mp4a.40.2" id="800"></Representation>
-      <Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
-    </AdaptationSet>
-    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true">
-      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
-      </ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
-        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
-      </ContentProtection>
-      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
-      <SegmentTemplate duration="1968" initialization="$RepresentationID$/video/1/init.mp4" media="$RepresentationID$/video/1/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
-      <Representation bandwidth="1518664" codecs="avc1.4d401f" frameRate="30000/1001" height="540" id="800" width="960"></Representation>
-      <Representation bandwidth="1911775" codecs="avc1.4d401f" frameRate="30000/1001" height="576" id="1000" width="1024"></Representation>
-      <Representation bandwidth="2295158" codecs="avc1.4d401f" frameRate="30000/1001" height="576" id="1200" width="1024"></Representation>
-      <Representation bandwidth="2780732" codecs="avc1.4d401f" frameRate="30000/1001" height="720" id="1500" width="1280"></Representation>
-    </AdaptationSet>
-    <AdaptationSet mimeType="text/vtt" id="7357" lang="en">
-      <Label>Subtitle (En)</Label>
-      <Representation bandwidth="256" id="subtitle_en">
-        <BaseURL>http://example.com/content/sintel/subtitles/subtitles_en.vtt</BaseURL>
-      </Representation>
-    </AdaptationSet>
-  </Period>
-  <UTCTiming></UTCTiming>
-</MPD>

From 001621929b440a7d04acf416343c195f63a11f20 Mon Sep 17 00:00:00 2001
From: Vishal Shah <vishshah00@gmail.com>
Date: Thu, 8 Feb 2024 11:05:43 -0700
Subject: [PATCH 29/32] test updates

---
 mpd/fixtures/hbbtv_profile.mpd |  2 +-
 mpd/test_hbbtv.mpd             | 43 ----------------------------------
 2 files changed, 1 insertion(+), 44 deletions(-)
 delete mode 100644 mpd/test_hbbtv.mpd

diff --git a/mpd/fixtures/hbbtv_profile.mpd b/mpd/fixtures/hbbtv_profile.mpd
index f9d2994..5a87626 100644
--- a/mpd/fixtures/hbbtv_profile.mpd
+++ b/mpd/fixtures/hbbtv_profile.mpd
@@ -37,7 +37,7 @@
       <Label>Subtitle (En)</Label>
       <Representation bandwidth="256" id="subtitle_en">
         <BaseURL>http://example.com/content/sintel/subtitles/subtitles_en.vtt</BaseURL>
-      </Representation>      
+      </Representation>
     </AdaptationSet>
   </Period>
 </MPD>
diff --git a/mpd/test_hbbtv.mpd b/mpd/test_hbbtv.mpd
deleted file mode 100644
index 5a87626..0000000
--- a/mpd/test_hbbtv.mpd
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:hbbtv:dash:profile:isoff-live:2012,urn:mpeg:dash:profile:isoff-live:2011" type="static" mediaPresentationDuration="PT6M16S" minBufferTime="PT1.97S">
-  <Period>
-    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="7357" segmentAlignment="true" lang="en">
-      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
-      </ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
-        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
-      </ContentProtection>
-      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
-      <SegmentTemplate duration="1968" initialization="$RepresentationID$/audio/en/init.mp4" media="$RepresentationID$/audio/en/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
-      <Representation audioSamplingRate="44100" bandwidth="67095" codecs="mp4a.40.2" id="800">
-        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"></AudioChannelConfiguration>
-      </Representation>
-      <Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
-    </AdaptationSet>
-    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="7357" segmentAlignment="true">
-      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
-      </ContentProtection>
-      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
-        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
-        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
-      </ContentProtection>
-      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
-      <SegmentTemplate duration="1968" initialization="$RepresentationID$/video/1/init.mp4" media="$RepresentationID$/video/1/seg-$Number$.m4f" startNumber="0" timescale="1000"></SegmentTemplate>
-      <Representation bandwidth="1518664" codecs="avc1.4d401f" frameRate="30000/1001" height="540" id="800" width="960"></Representation>
-      <Representation bandwidth="1911775" codecs="avc1.4d401f" frameRate="30000/1001" height="576" id="1000" width="1024"></Representation>
-      <Representation bandwidth="2295158" codecs="avc1.4d401f" frameRate="30000/1001" height="576" id="1200" width="1024"></Representation>
-      <Representation bandwidth="2780732" codecs="avc1.4d401f" frameRate="30000/1001" height="720" id="1500" width="1280"></Representation>
-    </AdaptationSet>
-    <AdaptationSet mimeType="text/vtt" id="7357" lang="en">
-      <Label>Subtitle (En)</Label>
-      <Representation bandwidth="256" id="subtitle_en">
-        <BaseURL>http://example.com/content/sintel/subtitles/subtitles_en.vtt</BaseURL>
-      </Representation>
-    </AdaptationSet>
-  </Period>
-</MPD>

From 600f7f19c8b268930edc7572c2354cacb60a6409 Mon Sep 17 00:00:00 2001
From: Jack Dunham <jack.dunham@gmail.com>
Date: Wed, 28 Feb 2024 10:21:51 -0800
Subject: [PATCH 30/32] Add MessageData field to Event element (required for
 DAI)

---
 mpd/events.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mpd/events.go b/mpd/events.go
index 95735f4..e937c56 100644
--- a/mpd/events.go
+++ b/mpd/events.go
@@ -16,4 +16,5 @@ type Event struct {
 	SpliceInfoSection *Scte35SpliceInfoSection `xml:"SpliceInfoSection,omitempty"`
 	PresentationTime  *int64                   `xml:"presentationTime,attr,omitempty"`
 	Duration          *int64                   `xml:"duration,attr,omitempty"`
+	MessageData       *string                  `xml:"messageData,attr,omitempty"`
 }

From 2d8665c31b9700d9012d2e18c7034fde632c16ad Mon Sep 17 00:00:00 2001
From: Vishal Shah <vishshah00@gmail.com>
Date: Mon, 1 Apr 2024 10:48:41 -0600
Subject: [PATCH 31/32] feat: Dovi8.1 profile support

---
 go.mod                               |   2 +-
 helpers/testfixtures/testfixtures.go |   7 +-
 mpd/fixtures/ondemand_withdolby.mpd  |  95 +++++++++++++++++++++++
 mpd/mpd.go                           |  49 +++++++++---
 mpd/mpd_read_write_test.go           | 108 +++++++++++++++++++++++++++
 mpd/mpd_test.go                      |  26 +++++++
 6 files changed, 271 insertions(+), 16 deletions(-)
 create mode 100644 mpd/fixtures/ondemand_withdolby.mpd

diff --git a/go.mod b/go.mod
index d60a7c1..0d06d1f 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
 module github.com/cbsinteractive/go-dash/v3
 
-go 1.16
+go 1.22
diff --git a/helpers/testfixtures/testfixtures.go b/helpers/testfixtures/testfixtures.go
index d00a071..d0368d3 100644
--- a/helpers/testfixtures/testfixtures.go
+++ b/helpers/testfixtures/testfixtures.go
@@ -2,7 +2,6 @@ package testfixtures
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"testing"
 
@@ -11,7 +10,7 @@ import (
 
 // Load test fixture from path relative to fixtures directory
 func LoadFixture(path string) (js string) {
-	f, err := ioutil.ReadFile(path)
+	f, err := os.ReadFile(path)
 	if err != nil {
 		panic(fmt.Sprintf("LoadFixture Error. ioutil.ReadFile. path = %s, Err = %s", path, err.Error()))
 	}
@@ -22,8 +21,8 @@ func CompareFixture(t *testing.T, fixturePath string, actualContent string) {
 	t.Helper()
 	expectedContent := LoadFixture(fixturePath)
 	if os.Getenv("GENERATE_FIXTURES") != "" {
-		_ = ioutil.WriteFile(fixturePath, []byte(actualContent), os.ModePerm)
-		fmt.Println("Wrote fixture: " + fixturePath)
+		_ = os.WriteFile(fixturePath, []byte(actualContent), os.ModePerm)
+		fmt.Println("GEN FIXTURES - Wrote fixture: " + fixturePath)
 		return
 	}
 	require.EqualString(t, expectedContent, actualContent)
diff --git a/mpd/fixtures/ondemand_withdolby.mpd b/mpd/fixtures/ondemand_withdolby.mpd
new file mode 100644
index 0000000..7497836
--- /dev/null
+++ b/mpd/fixtures/ondemand_withdolby.mpd
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:dolby="http://www.dolby.com/ns/online/DASH" xmlns:scte214="urn:scte:dash:scte214-extensions" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" mediaPresentationDuration="PT30S" minBufferTime="PT1.97S">
+  <Period>
+    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="1" segmentAlignment="true" lang="en-US">
+      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+      </ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
+        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+      </ContentProtection>
+      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
+      <Representation audioSamplingRate="44100" bandwidth="128558" codecs="mp4a.40.5" id="800k/audio-en-US">
+        <BaseURL>800k/output-audio-en-US.mp4</BaseURL>
+        <SegmentBase indexRange="629-756">
+          <Initialization range="0-628"></Initialization>
+        </SegmentBase>
+      </Representation>
+      <Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
+    </AdaptationSet>
+    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="2" segmentAlignment="true" lang="en-US">
+      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+      </ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
+        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+      </ContentProtection>
+      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="description"></Role>
+      <Representation audioSamplingRate="44100" bandwidth="128558" codecs="mp4a.40.5" id="800k/audio-AD-en-US">
+        <BaseURL>800k/output-audio-AD-en-US.mp4</BaseURL>
+        <SegmentBase indexRange="629-756">
+          <Initialization range="0-628"></Initialization>
+        </SegmentBase>
+      </Representation>
+      <Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
+      <Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
+    </AdaptationSet>
+    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="3" segmentAlignment="true">
+      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+      </ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
+        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+      </ContentProtection>
+      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
+      <Representation bandwidth="1100690" codecs="avc1.4d401e" frameRate="30000/1001" height="360" id="800k/video-1" width="640">
+        <BaseURL>800k/output-video-1.mp4</BaseURL>
+        <SegmentBase indexRange="686-813">
+          <Initialization range="0-685"></Initialization>
+        </SegmentBase>
+      </Representation>
+      <Representation bandwidth="1633516" codecs="avc1.4d401f" frameRate="30000/1001" height="540" id="1200k/video-1" width="960">
+        <BaseURL>1200k/output-video-1.mp4</BaseURL>
+        <SegmentBase indexRange="686-813">
+          <Initialization range="0-685"></Initialization>
+        </SegmentBase>
+      </Representation>
+    </AdaptationSet>
+    <AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="4" segmentAlignment="true">
+      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
+      </ContentProtection>
+      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
+        <mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
+        <cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
+      </ContentProtection>
+      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
+      <Representation bandwidth="1100690" codecs="hev1.2.4.L63.90" scte214:supplementalCodecs="dvhe.08.07" scte214:supplementalProfiles="db1p" frameRate="30000/1001" height="360" id="800k/video-1" width="640">
+        <BaseURL>800k/output-video-1.mp4</BaseURL>
+        <SegmentBase indexRange="686-813">
+          <Initialization range="0-685"></Initialization>
+        </SegmentBase>
+      </Representation>
+      <Representation bandwidth="1633516" codecs="hev1.2.4.L93.90" scte214:supplementalCodecs="dvhe.08.07" scte214:supplementalProfiles="db4h" frameRate="30000/1001" height="540" id="1200k/video-1" width="960">
+        <BaseURL>1200k/output-video-1.mp4</BaseURL>
+        <SegmentBase indexRange="686-813">
+          <Initialization range="0-685"></Initialization>
+        </SegmentBase>
+      </Representation>
+    </AdaptationSet>
+    <AdaptationSet mimeType="text/vtt" id="5" lang="en">
+      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"></Role>
+      <Label>Subtitle (En)</Label>
+      <Representation bandwidth="256" id="subtitle_en">
+        <BaseURL>http://example.com/content/sintel/subtitles/subtitles_en.vtt</BaseURL>
+      </Representation>
+    </AdaptationSet>
+  </Period>
+</MPD>
diff --git a/mpd/mpd.go b/mpd/mpd.go
index ccea914..67d41e6 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -73,6 +73,7 @@ var (
 type MPD struct {
 	XMLNs                      *string    `xml:"xmlns,attr"`
 	XMLNsDolby                 *string    `xml:"xmlns:dolby,attr"`
+	XMLNsSCTE214               *string    `xml:"xmlns:scte214,attr"`
 	Scte35NS                   *Scte35NS  `xml:"scte35,attr,omitempty"`
 	XsiNS                      *XmlnsAttr `xml:"xsi,attr,omitempty"`
 	XsiSchemaLocation          *XsiSL     `xml:"schemaLocation,attr,omitempty"`
@@ -246,9 +247,17 @@ func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
 		return err
 	}
 	*as = AdaptationSet(n.wrappedAdaptationSet)
+
+	if as.Roles != nil {
+		as.Roles = n.Roles
+	}
+
 	as.ContentProtection = make([]ContentProtectioner, len(n.ContentProtection))
-	for i := range n.ContentProtection {
-		as.ContentProtection[i] = n.ContentProtection[i]
+	copy(as.ContentProtection, n.ContentProtection)
+
+	for i := range as.Representations {
+		as.Representations[i].SupplementalCodecs = n.Representations[i].SupplementalCodecs
+		as.Representations[i].SupplementalProfiles = n.Representations[i].SupplementalProfiles
 	}
 	return nil
 }
@@ -434,15 +443,17 @@ type Representation struct {
 	CommonAttributesAndElements
 	AdaptationSet             *AdaptationSet             `xml:"-"`
 	AudioChannelConfiguration *AudioChannelConfiguration `xml:"AudioChannelConfiguration,omitempty"`
-	AudioSamplingRate         *int64                     `xml:"audioSamplingRate,attr"`   // Audio
-	Bandwidth                 *int64                     `xml:"bandwidth,attr"`           // Audio + Video
-	Codecs                    *string                    `xml:"codecs,attr"`              // Audio + Video
-	FrameRate                 *string                    `xml:"frameRate,attr,omitempty"` // Video
-	Height                    *int64                     `xml:"height,attr"`              // Video
-	ID                        *string                    `xml:"id,attr"`                  // Audio + Video
-	Width                     *int64                     `xml:"width,attr"`               // Video
-	BaseURL                   []string                   `xml:"BaseURL,omitempty"`        // On-Demand Profile
-	SegmentBase               *SegmentBase               `xml:"SegmentBase,omitempty"`    // On-Demand Profile
+	AudioSamplingRate         *int64                     `xml:"audioSamplingRate,attr"`                      // Audio
+	Bandwidth                 *int64                     `xml:"bandwidth,attr"`                              // Audio + Video
+	Codecs                    *string                    `xml:"codecs,attr"`                                 // Audio + Video
+	SupplementalCodecs        *string                    `xml:"scte214:supplementalCodecs,attr,omitempty"`   // Video
+	SupplementalProfiles      *string                    `xml:"scte214:supplementalProfiles,attr,omitempty"` // Video
+	FrameRate                 *string                    `xml:"frameRate,attr,omitempty"`                    // Video
+	Height                    *int64                     `xml:"height,attr"`                                 // Video
+	ID                        *string                    `xml:"id,attr"`                                     // Audio + Video
+	Width                     *int64                     `xml:"width,attr"`                                  // Video
+	BaseURL                   []string                   `xml:"BaseURL,omitempty"`                           // On-Demand Profile
+	SegmentBase               *SegmentBase               `xml:"SegmentBase,omitempty"`                       // On-Demand Profile
 	SegmentList               *SegmentList               `xml:"SegmentList,omitempty"`
 	SegmentTemplate           *SegmentTemplate           `xml:"SegmentTemplate,omitempty"`
 }
@@ -463,6 +474,10 @@ func (m *MPD) SetDolbyXMLNs() {
 	m.XMLNsDolby = Strptr("http://www.dolby.com/ns/online/DASH")
 }
 
+func (m *MPD) SetScte214XMLNs() {
+	m.XMLNsSCTE214 = Strptr("urn:scte:dash:scte214-extensions")
+}
+
 // Creates a new static MPD object.
 // profile - DASH Profile (Live or OnDemand).
 // mediaPresentationDuration - Media Presentation Duration (i.e. PT6M16S).
@@ -1114,6 +1129,18 @@ func (as *AdaptationSet) AddNewRepresentationVideo(bandwidth int64, codecs strin
 	return r, nil
 }
 
+// Adds supplementalCodecs and supplementalProfiles to a Representation
+// supplementalCodecs - scte214:supplementalCodecs attribute for Dovi 8.1 signaling (optional).
+// supplementalProfiles - scte214:supplementalProfiles attribute for Dovi 8.1 signaling (optional).
+func (r *Representation) AddScte214VideoCodecProperties(supplementalCodecs string, supplementalProfiles string) (*Representation, error) {
+	// For Dovi 8.1 signaling both supplementalCodecs and supplementalProfiles should be added
+	if len(supplementalCodecs) > 0 && len(supplementalProfiles) > 0 {
+		r.SupplementalCodecs = Strptr(supplementalCodecs)
+		r.SupplementalProfiles = Strptr(supplementalProfiles)
+	}
+	return r, nil
+}
+
 // Adds a new Subtitle representation to an AdaptationSet.
 // bandwidth - in Bits/s (i.e. 256).
 // id - ID for this representation, will get used as $RepresentationID$ in template strings.
diff --git a/mpd/mpd_read_write_test.go b/mpd/mpd_read_write_test.go
index 6934faf..92d3a17 100644
--- a/mpd/mpd_read_write_test.go
+++ b/mpd/mpd_read_write_test.go
@@ -123,6 +123,21 @@ func TestNewMPDOnDemandWriteToString(t *testing.T) {
 	require.EqualString(t, expectedXML, xmlStr)
 }
 
+func TestNewMPDOnDemandwithDolbyWriteToString(t *testing.T) {
+	m := NewMPD(DASH_PROFILE_ONDEMAND, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
+	m.SetDolbyXMLNs()
+	m.SetScte214XMLNs()
+
+	xmlStr, err := m.WriteToString()
+	require.NoError(t, err)
+	expectedXML := `<?xml version="1.0" encoding="UTF-8"?>
+<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:dolby="http://www.dolby.com/ns/online/DASH" xmlns:scte214="urn:scte:dash:scte214-extensions" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" mediaPresentationDuration="PT6M16S" minBufferTime="PT1.97S">
+  <Period></Period>
+</MPD>
+`
+	require.EqualString(t, expectedXML, xmlStr)
+}
+
 func TestAddNewAdaptationSetAudioWriteToString(t *testing.T) {
 	m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
 
@@ -519,3 +534,96 @@ func TestWriteComment(t *testing.T) {
 `
 	require.EqualString(t, answer, s)
 }
+
+func OnDemandProfileWithDolby() *MPD {
+	m := NewMPD(DASH_PROFILE_ONDEMAND, "PT30S", VALID_MIN_BUFFER_TIME)
+	m.SetDolbyXMLNs()
+	m.SetScte214XMLNs()
+
+	// Main audio adaptation set
+	audioAS, _ := m.AddNewAdaptationSetAudioWithID("1", DASH_MIME_TYPE_AUDIO_MP4, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP, "en-US")
+	_, _ = audioAS.AddNewRole("urn:mpeg:dash:role:2011", "main")
+
+	_, _ = audioAS.AddNewContentProtectionRoot("08e367028f33436ca5dd60ffe5571e60")
+	_, _ = audioAS.AddNewContentProtectionSchemeWidevineWithPSSH(getValidWVHeaderBytes())
+	_, _ = audioAS.AddNewContentProtectionSchemePlayreadyWithPSSH(VALID_PLAYREADY_PRO)
+	_, _ = audioAS.AddNewAccessibilityElement(ACCESSIBILITY_ELEMENT_SCHEME_DESCRIPTIVE_AUDIO, "1")
+
+	audioRep, _ := audioAS.AddNewRepresentationAudio(44100, 128558, "mp4a.40.5", "800k/audio-en-US")
+	_ = audioRep.SetNewBaseURL("800k/output-audio-en-US.mp4")
+	_, _ = audioRep.AddNewSegmentBase("629-756", "0-628")
+
+	// audio description adaptation set
+	audioAD, _ := m.AddNewAdaptationSetAudioWithID("2", DASH_MIME_TYPE_AUDIO_MP4, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP, "en-US")
+	_, _ = audioAD.AddNewRole("urn:mpeg:dash:role:2011", "description")
+	_, _ = audioAD.AddNewAccessibilityElement(ACCESSIBILITY_ELEMENT_SCHEME_DESCRIPTIVE_AUDIO, "1")
+
+	_, _ = audioAD.AddNewContentProtectionRoot("08e367028f33436ca5dd60ffe5571e60")
+	_, _ = audioAD.AddNewContentProtectionSchemeWidevineWithPSSH(getValidWVHeaderBytes())
+	_, _ = audioAD.AddNewContentProtectionSchemePlayreadyWithPSSH(VALID_PLAYREADY_PRO)
+	_, _ = audioAD.AddNewAccessibilityElement(ACCESSIBILITY_ELEMENT_SCHEME_DESCRIPTIVE_AUDIO, "1")
+
+	audioADRep, _ := audioAD.AddNewRepresentationAudio(44100, 128558, "mp4a.40.5", "800k/audio-AD-en-US")
+	_ = audioADRep.SetNewBaseURL("800k/output-audio-AD-en-US.mp4")
+	_, _ = audioADRep.AddNewSegmentBase("629-756", "0-628")
+
+	// video avc adaptation set
+	videoAS, _ := m.AddNewAdaptationSetVideoWithID("3", DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)
+	_, _ = videoAS.AddNewRole("urn:mpeg:dash:role:2011", "main")
+
+	_, _ = videoAS.AddNewContentProtectionRoot("08e367028f33436ca5dd60ffe5571e60")
+	_, _ = videoAS.AddNewContentProtectionSchemeWidevineWithPSSH(getValidWVHeaderBytes())
+	_, _ = videoAS.AddNewContentProtectionSchemePlayreadyWithPSSH(VALID_PLAYREADY_PRO)
+
+	videoRep1, _ := videoAS.AddNewRepresentationVideo(1100690, "avc1.4d401e", "800k/video-1", "30000/1001", 640, 360)
+	_ = videoRep1.SetNewBaseURL("800k/output-video-1.mp4")
+	_, _ = videoRep1.AddNewSegmentBase("686-813", "0-685")
+
+	videoRep2, _ := videoAS.AddNewRepresentationVideo(1633516, "avc1.4d401f", "1200k/video-1", "30000/1001", 960, 540)
+	_ = videoRep2.SetNewBaseURL("1200k/output-video-1.mp4")
+	_, _ = videoRep2.AddNewSegmentBase("686-813", "0-685")
+
+	// video hevc adaptation set with Dolby Vision signaling
+	videoAS1, _ := m.AddNewAdaptationSetVideoWithID("4", DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)
+	_, _ = videoAS1.AddNewRole("urn:mpeg:dash:role:2011", "main")
+
+	_, _ = videoAS1.AddNewContentProtectionRoot("08e367028f33436ca5dd60ffe5571e60")
+	_, _ = videoAS1.AddNewContentProtectionSchemeWidevineWithPSSH(getValidWVHeaderBytes())
+	_, _ = videoAS1.AddNewContentProtectionSchemePlayreadyWithPSSH(VALID_PLAYREADY_PRO)
+
+	videoRep3, _ := videoAS1.AddNewRepresentationVideo(1100690, "hev1.2.4.L63.90", "800k/video-1", "30000/1001", 640, 360)
+	_, _ = videoRep3.AddScte214VideoCodecProperties("dvhe.08.07", "db1p")
+	_ = videoRep3.SetNewBaseURL("800k/output-video-1.mp4")
+	_, _ = videoRep3.AddNewSegmentBase("686-813", "0-685")
+
+	videoRep4, _ := videoAS1.AddNewRepresentationVideo(1633516, "hev1.2.4.L93.90", "1200k/video-1", "30000/1001", 960, 540)
+	_, _ = videoRep4.AddScte214VideoCodecProperties("dvhe.08.07", "db4h")
+	_ = videoRep4.SetNewBaseURL("1200k/output-video-1.mp4")
+	_, _ = videoRep4.AddNewSegmentBase("686-813", "0-685")
+
+	// subtitle adaptation set
+	subtitleAS, _ := m.AddNewAdaptationSetSubtitleWithID("5", DASH_MIME_TYPE_SUBTITLE_VTT, VALID_LANG, VALID_SUBTITLE_LABEL)
+	_, _ = subtitleAS.AddNewRole("urn:mpeg:dash:role:2011", "subtitle")
+	subtitleRep, _ := subtitleAS.AddNewRepresentationSubtitle(VALID_SUBTITLE_BANDWIDTH, VALID_SUBTITLE_ID)
+	_ = subtitleRep.SetNewBaseURL(VALID_SUBTITLE_URL)
+
+	return m
+}
+
+func TestOnDemandProfileWithDolbyWriteToString(t *testing.T) {
+	m := OnDemandProfileWithDolby()
+	require.NotNil(t, m)
+	xmlStr, err := m.WriteToString()
+	require.NoError(t, err)
+	testfixtures.CompareFixture(t, "fixtures/ondemand_withdolby.mpd", xmlStr)
+}
+
+func TestOnDemandProfileWithDolbyWriteToFile(t *testing.T) {
+	m := OnDemandProfileWithDolby()
+	require.NotNil(t, m)
+	err := m.WriteToFile("test-withdolby-ondemand.mpd")
+	xmlStr := testfixtures.LoadFixture("test-withdolby-ondemand.mpd")
+	testfixtures.CompareFixture(t, "fixtures/ondemand_withdolby.mpd", xmlStr)
+	defer os.Remove("test-withdolby-ondemand.mpd")
+	require.NoError(t, err)
+}
diff --git a/mpd/mpd_test.go b/mpd/mpd_test.go
index 39d4146..06815c6 100644
--- a/mpd/mpd_test.go
+++ b/mpd/mpd_test.go
@@ -243,6 +243,32 @@ func TestNewMPDOnDemand(t *testing.T) {
 	require.EqualString(t, expectedString, actualString)
 }
 
+func TestNewMPDOnDemandWithDolby(t *testing.T) {
+	m := NewMPD(DASH_PROFILE_ONDEMAND, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
+	m.SetDolbyXMLNs()
+	m.SetScte214XMLNs()
+
+	require.NotNil(t, m)
+	expectedMPD := &MPD{
+		XMLNs:                     Strptr("urn:mpeg:dash:schema:mpd:2011"),
+		XMLNsDolby:                Strptr("http://www.dolby.com/ns/online/DASH"),
+		XMLNsSCTE214:              Strptr("urn:scte:dash:scte214-extensions"),
+		Profiles:                  Strptr((string)(DASH_PROFILE_ONDEMAND)),
+		Type:                      Strptr("static"),
+		MediaPresentationDuration: Strptr(VALID_MEDIA_PRESENTATION_DURATION),
+		MinBufferTime:             Strptr(VALID_MIN_BUFFER_TIME),
+		period:                    &Period{},
+		Periods:                   []*Period{{}},
+	}
+
+	expectedString, err := expectedMPD.WriteToString()
+	require.NoError(t, err)
+	actualString, err := m.WriteToString()
+	require.NoError(t, err)
+
+	require.EqualString(t, expectedString, actualString)
+}
+
 func TestAddAdaptationSetErrorNil(t *testing.T) {
 	m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
 

From ebe10ac0aa7dbf3eb2e4d04470ba47937bbc6e07 Mon Sep 17 00:00:00 2001
From: Vishal Shah <vishshah00@gmail.com>
Date: Mon, 1 Apr 2024 13:03:49 -0600
Subject: [PATCH 32/32] update xmlns parsing for scte214

---
 mpd/mpd.go      | 70 +++++++++++++++++++++++++++++++++++++------------
 mpd/mpd_test.go | 13 ++++++---
 2 files changed, 63 insertions(+), 20 deletions(-)

diff --git a/mpd/mpd.go b/mpd/mpd.go
index 67d41e6..2efb925 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -72,8 +72,8 @@ var (
 
 type MPD struct {
 	XMLNs                      *string    `xml:"xmlns,attr"`
-	XMLNsDolby                 *string    `xml:"xmlns:dolby,attr"`
-	XMLNsSCTE214               *string    `xml:"xmlns:scte214,attr"`
+	XMLNsDolby                 *XmlnsAttr `xml:"dolby,attr"`
+	XMLNsSCTE214               *XmlnsAttr `xml:"scte214,attr"`
 	Scte35NS                   *Scte35NS  `xml:"scte35,attr,omitempty"`
 	XsiNS                      *XmlnsAttr `xml:"xsi,attr,omitempty"`
 	XsiSchemaLocation          *XsiSL     `xml:"schemaLocation,attr,omitempty"`
@@ -109,9 +109,27 @@ func (s *XmlnsAttr) UnmarshalXMLAttr(attr xml.Attr) error {
 }
 
 func (s *XmlnsAttr) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
+	if s == nil {
+		return xml.Attr{}, nil
+	}
 	return xml.Attr{Name: xml.Name{Local: fmt.Sprintf("xmlns:%s", s.XmlName.Local)}, Value: s.Value}, nil
 }
 
+type Scte214Attr struct {
+	XmlName xml.Name
+	Value   string
+}
+
+func (s *Scte214Attr) UnmarshalXMLAttr(attr xml.Attr) error {
+	s.XmlName = attr.Name
+	s.Value = attr.Value
+	return nil
+}
+
+func (s *Scte214Attr) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
+	return xml.Attr{Name: xml.Name{Local: fmt.Sprintf("scte214:%s", s.XmlName.Local)}, Value: s.Value}, nil
+}
+
 type XsiSL struct {
 	XmlName xml.Name
 	Value   string
@@ -443,17 +461,17 @@ type Representation struct {
 	CommonAttributesAndElements
 	AdaptationSet             *AdaptationSet             `xml:"-"`
 	AudioChannelConfiguration *AudioChannelConfiguration `xml:"AudioChannelConfiguration,omitempty"`
-	AudioSamplingRate         *int64                     `xml:"audioSamplingRate,attr"`                      // Audio
-	Bandwidth                 *int64                     `xml:"bandwidth,attr"`                              // Audio + Video
-	Codecs                    *string                    `xml:"codecs,attr"`                                 // Audio + Video
-	SupplementalCodecs        *string                    `xml:"scte214:supplementalCodecs,attr,omitempty"`   // Video
-	SupplementalProfiles      *string                    `xml:"scte214:supplementalProfiles,attr,omitempty"` // Video
-	FrameRate                 *string                    `xml:"frameRate,attr,omitempty"`                    // Video
-	Height                    *int64                     `xml:"height,attr"`                                 // Video
-	ID                        *string                    `xml:"id,attr"`                                     // Audio + Video
-	Width                     *int64                     `xml:"width,attr"`                                  // Video
-	BaseURL                   []string                   `xml:"BaseURL,omitempty"`                           // On-Demand Profile
-	SegmentBase               *SegmentBase               `xml:"SegmentBase,omitempty"`                       // On-Demand Profile
+	AudioSamplingRate         *int64                     `xml:"audioSamplingRate,attr"`              // Audio
+	Bandwidth                 *int64                     `xml:"bandwidth,attr"`                      // Audio + Video
+	Codecs                    *string                    `xml:"codecs,attr"`                         // Audio + Video
+	SupplementalCodecs        *Scte214Attr               `xml:"supplementalCodecs,attr,omitempty"`   // Video
+	SupplementalProfiles      *Scte214Attr               `xml:"supplementalProfiles,attr,omitempty"` // Video
+	FrameRate                 *string                    `xml:"frameRate,attr,omitempty"`            // Video
+	Height                    *int64                     `xml:"height,attr"`                         // Video
+	ID                        *string                    `xml:"id,attr"`                             // Audio + Video
+	Width                     *int64                     `xml:"width,attr"`                          // Video
+	BaseURL                   []string                   `xml:"BaseURL,omitempty"`                   // On-Demand Profile
+	SegmentBase               *SegmentBase               `xml:"SegmentBase,omitempty"`               // On-Demand Profile
 	SegmentList               *SegmentList               `xml:"SegmentList,omitempty"`
 	SegmentTemplate           *SegmentTemplate           `xml:"SegmentTemplate,omitempty"`
 }
@@ -471,11 +489,17 @@ type AudioChannelConfiguration struct {
 }
 
 func (m *MPD) SetDolbyXMLNs() {
-	m.XMLNsDolby = Strptr("http://www.dolby.com/ns/online/DASH")
+	m.XMLNsDolby = &XmlnsAttr{
+		XmlName: xml.Name{Space: "xmlns", Local: "dolby"},
+		Value:   "http://www.dolby.com/ns/online/DASH",
+	}
 }
 
 func (m *MPD) SetScte214XMLNs() {
-	m.XMLNsSCTE214 = Strptr("urn:scte:dash:scte214-extensions")
+	m.XMLNsSCTE214 = &XmlnsAttr{
+		XmlName: xml.Name{Space: "xmlns", Local: "scte214"},
+		Value:   "urn:scte:dash:scte214-extensions",
+	}
 }
 
 // Creates a new static MPD object.
@@ -1135,8 +1159,20 @@ func (as *AdaptationSet) AddNewRepresentationVideo(bandwidth int64, codecs strin
 func (r *Representation) AddScte214VideoCodecProperties(supplementalCodecs string, supplementalProfiles string) (*Representation, error) {
 	// For Dovi 8.1 signaling both supplementalCodecs and supplementalProfiles should be added
 	if len(supplementalCodecs) > 0 && len(supplementalProfiles) > 0 {
-		r.SupplementalCodecs = Strptr(supplementalCodecs)
-		r.SupplementalProfiles = Strptr(supplementalProfiles)
+		r.SupplementalCodecs = &Scte214Attr{
+			XmlName: xml.Name{
+				Space: "scte214",
+				Local: "supplementalCodecs",
+			},
+			Value: supplementalCodecs,
+		}
+		r.SupplementalProfiles = &Scte214Attr{
+			XmlName: xml.Name{
+				Space: "scte214",
+				Local: "supplementalProfiles",
+			},
+			Value: supplementalProfiles,
+		}
 	}
 	return r, nil
 }
diff --git a/mpd/mpd_test.go b/mpd/mpd_test.go
index 06815c6..9343cfa 100644
--- a/mpd/mpd_test.go
+++ b/mpd/mpd_test.go
@@ -2,6 +2,7 @@ package mpd
 
 import (
 	"encoding/base64"
+	"encoding/xml"
 	"path/filepath"
 	"strconv"
 	"testing"
@@ -250,9 +251,15 @@ func TestNewMPDOnDemandWithDolby(t *testing.T) {
 
 	require.NotNil(t, m)
 	expectedMPD := &MPD{
-		XMLNs:                     Strptr("urn:mpeg:dash:schema:mpd:2011"),
-		XMLNsDolby:                Strptr("http://www.dolby.com/ns/online/DASH"),
-		XMLNsSCTE214:              Strptr("urn:scte:dash:scte214-extensions"),
+		XMLNs: Strptr("urn:mpeg:dash:schema:mpd:2011"),
+		XMLNsDolby: &XmlnsAttr{
+			XmlName: xml.Name{Space: "xmlns", Local: "dolby"},
+			Value:   "http://www.dolby.com/ns/online/DASH",
+		},
+		XMLNsSCTE214: &XmlnsAttr{
+			XmlName: xml.Name{Space: "xmlns", Local: "scte214"},
+			Value:   "urn:scte:dash:scte214-extensions",
+		},
 		Profiles:                  Strptr((string)(DASH_PROFILE_ONDEMAND)),
 		Type:                      Strptr("static"),
 		MediaPresentationDuration: Strptr(VALID_MEDIA_PRESENTATION_DURATION),
