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/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/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 da472a9..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.13
+go 1.16
diff --git a/helpers/require/require.go b/helpers/require/require.go
index 58c5fbc..b32c62f 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 754f80d..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
@@ -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/duration.go b/mpd/duration.go
index 8ebc870..9baacf3 100644
--- a/mpd/duration.go
+++ b/mpd/duration.go
@@ -54,29 +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
- var prec int
- w--
- buf[w] = 'S'
- w--
+ // 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"
+ } else {
+ du := float64(u) / float64(time.Second)
+ s := fmt.Sprintf("%2f", du)
+ sf := strings.TrimRight(s, "0")
+ return fmt.Sprintf("PT%sS", sf)
}
- /*
- 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'
- }
- */
- 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..15b7695 100644
--- a/mpd/duration_test.go
+++ b/mpd/duration_test.go
@@ -5,14 +5,18 @@ import (
"testing"
"time"
- "github.com/zencoder/go-dash/v3/helpers/require"
+ "github.com/cbsinteractive/go-dash/v3/helpers/require"
)
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",
+ "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)
diff --git a/mpd/events.go b/mpd/events.go
index 0962918..e937c56 100644
--- a/mpd/events.go
+++ b/mpd/events.go
@@ -6,13 +6,15 @@ type EventStream struct {
XMLName xml.Name `xml:"EventStream"`
SchemeIDURI *string `xml:"schemeIdUri,attr"`
Value *string `xml:"value,attr,omitempty"`
- Timescale *uint `xml:"timescale,attr"`
+ Timescale *uint64 `xml:"timescale,attr"`
Events []Event `xml:"Event,omitempty"`
}
type Event struct {
- XMLName xml.Name `xml:"Event"`
- ID *string `xml:"id,attr,omitempty"`
- PresentationTime *uint64 `xml:"presentationTime,attr,omitempty"`
- Duration *uint64 `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"`
+ MessageData *string `xml:"messageData,attr,omitempty"`
}
diff --git a/mpd/events_test.go b/mpd/events_test.go
index 4aa230b..6028e10 100644
--- a/mpd/events_test.go
+++ b/mpd/events_test.go
@@ -3,15 +3,15 @@ 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 (
- VALID_EVENT_STREAM_SCHEME_ID_URI = "urn:example:eventstream"
- VALID_EVENT_STREAM_VALUE = "eventstream"
- VALID_EVENT_STREAM_TIMESCALE uint = 10
+ VALID_EVENT_STREAM_SCHEME_ID_URI = "urn:example:eventstream"
+ VALID_EVENT_STREAM_VALUE = "eventstream"
+ VALID_EVENT_STREAM_TIMESCALE uint64 = 10
)
func newEventStreamMPD() *MPD {
@@ -25,19 +25,19 @@ func newEventStreamMPD() *MPD {
es := EventStream{
SchemeIDURI: ptrs.Strptr(VALID_EVENT_STREAM_SCHEME_ID_URI),
Value: ptrs.Strptr(VALID_EVENT_STREAM_VALUE),
- Timescale: ptrs.Uintptr(VALID_EVENT_STREAM_TIMESCALE),
+ Timescale: ptrs.Uint64ptr(VALID_EVENT_STREAM_TIMESCALE),
}
e0 := Event{
ID: ptrs.Strptr("event-0"),
- PresentationTime: ptrs.Uint64ptr(100),
- Duration: ptrs.Uint64ptr(50),
+ PresentationTime: ptrs.Int64ptr(100),
+ Duration: ptrs.Int64ptr(50),
}
e1 := Event{
ID: ptrs.Strptr("event-1"),
- PresentationTime: ptrs.Uint64ptr(200),
- Duration: ptrs.Uint64ptr(50),
+ PresentationTime: ptrs.Int64ptr(200),
+ Duration: ptrs.Int64ptr(50),
}
es.Events = append(es.Events, e0, e1)
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 @@
+
+
+
diff --git a/mpd/fixtures/hbbtv_profile.mpd b/mpd/fixtures/hbbtv_profile.mpd
index cc67050..5a87626 100644
--- a/mpd/fixtures/hbbtv_profile.mpd
+++ b/mpd/fixtures/hbbtv_profile.mpd
@@ -4,11 +4,11 @@
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
@@ -20,11 +20,11 @@
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
@@ -34,10 +34,10 @@
+
http://example.com/content/sintel/subtitles/subtitles_en.vtt
-
diff --git a/mpd/fixtures/live_profile.mpd b/mpd/fixtures/live_profile.mpd
index 9a5d844..118c99e 100644
--- a/mpd/fixtures/live_profile.mpd
+++ b/mpd/fixtures/live_profile.mpd
@@ -4,11 +4,11 @@
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
@@ -18,11 +18,11 @@
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
@@ -32,10 +32,10 @@
+
http://example.com/content/sintel/subtitles/subtitles_en.vtt
-
diff --git a/mpd/fixtures/live_profile_dynamic.mpd b/mpd/fixtures/live_profile_dynamic.mpd
index ee34d17..55ce628 100644
--- a/mpd/fixtures/live_profile_dynamic.mpd
+++ b/mpd/fixtures/live_profile_dynamic.mpd
@@ -4,11 +4,11 @@
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
@@ -18,11 +18,11 @@
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
@@ -32,10 +32,10 @@
+
http://example.com/content/sintel/subtitles/subtitles_en.vtt
-
diff --git a/mpd/fixtures/live_profile_multi_base_url.mpd b/mpd/fixtures/live_profile_multi_base_url.mpd
index 6c85d13..a8fda87 100644
--- a/mpd/fixtures/live_profile_multi_base_url.mpd
+++ b/mpd/fixtures/live_profile_multi_base_url.mpd
@@ -7,11 +7,11 @@
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
@@ -21,11 +21,11 @@
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
@@ -35,10 +35,10 @@
+
http://example.com/content/sintel/subtitles/subtitles_en.vtt
-
diff --git a/mpd/fixtures/ondemand_profile.mpd b/mpd/fixtures/ondemand_profile.mpd
index 58415f7..adeb578 100644
--- a/mpd/fixtures/ondemand_profile.mpd
+++ b/mpd/fixtures/ondemand_profile.mpd
@@ -1,14 +1,14 @@
-
+
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
800k/output-audio-und.mp4
@@ -21,11 +21,11 @@
- AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
+ AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==
BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
- AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
800k/output-video-1.mp4
@@ -41,10 +41,10 @@
+
http://example.com/content/sintel/subtitles/subtitles_en.vtt
-
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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
http://localhost:8002/dash/
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 @@
+
diff --git a/mpd/mpd.go b/mpd/mpd.go
index 9972443..b9c1bcf 100644
--- a/mpd/mpd.go
+++ b/mpd/mpd.go
@@ -5,10 +5,11 @@ import (
"encoding/hex"
"encoding/xml"
"errors"
+ "fmt"
"strings"
"time"
- . "github.com/zencoder/go-dash/v3/helpers/ptrs"
+ . "github.com/cbsinteractive/go-dash/v3/helpers/ptrs"
)
// Type definition for DASH profiles
@@ -70,34 +71,77 @@ var (
)
type MPD struct {
- XMLNs *string `xml:"xmlns,attr"`
- XMLNsDolby *string `xml:"xmlns:dolby,attr"`
- 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"`
+ XMLNsDolby *string `xml:"xmlns:dolby,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"`
+ Comment string `xml:"-"`
+}
+
+type XmlnsAttr struct {
+ XmlName xml.Name
+ Value string
+}
+
+func (s *XmlnsAttr) UnmarshalXMLAttr(attr xml.Attr) error {
+ s.XmlName = attr.Name
+ s.Value = attr.Value
+ return 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 {
+ 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"`
+ XlinkHref string `xml:"xlink:href,attr,omitempty"`
+ XlinkActuate string `xml:"xlink:actuate,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 {
@@ -108,25 +152,26 @@ 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,omitempty"`
+ 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"`
+ SubsegmentStartsWithSAP *int64 `xml:"subsegmentStartsWithSAP,attr,omitempty"`
+ 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,omitempty"`
}
type contentProtections []ContentProtectioner
@@ -171,27 +216,30 @@ 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"`
- 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"`
- Labels []string `xml:"Label,omitempty"`
- BaseURL []string `xml:"BaseURL,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
+ Labels []string `xml:"Label,omitempty"`
+ Representations []*Representation `xml:"Representation,omitempty"`
+ AccessibilityElems []*Accessibility `xml:"Accessibility,omitempty"`
+ BaseURL []string `xml:"BaseURL,omitempty"`
}
func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
@@ -239,16 +287,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 {
@@ -265,16 +318,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() {}
@@ -322,8 +388,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
}
@@ -339,7 +406,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
@@ -358,7 +425,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"`
@@ -801,7 +868,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
}
@@ -873,7 +940,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 {
@@ -905,7 +972,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 {
@@ -930,9 +997,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),
@@ -961,9 +1028,9 @@ func (as *AdaptationSet) setSegmentTemplate(st *SegmentTemplate) 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) SetNewSegmentTemplateThumbnails(duration int64, media string, startNumber int64, timescale int64) (*SegmentTemplate, error) {
+func (as *AdaptationSet) SetNewSegmentTemplateThumbnails(duration float64, media string, startNumber int64, timescale int64) (*SegmentTemplate, error) {
st := &SegmentTemplate{
- Duration: Int64ptr(duration),
+ Duration: Float64ptr(duration),
Media: Strptr(media),
StartNumber: Int64ptr(startNumber),
Timescale: Int64ptr(timescale),
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 80981b3..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) {
@@ -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 := `
-
+
`
@@ -426,6 +427,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")
@@ -500,3 +502,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 := `
+
+
+`
+ require.EqualString(t, answer, s)
+}
diff --git a/mpd/mpd_test.go b/mpd/mpd_test.go
index 19ab6c1..39d4146 100644
--- a/mpd/mpd_test.go
+++ b/mpd/mpd_test.go
@@ -6,48 +6,48 @@ 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 (
- VALID_MEDIA_PRESENTATION_DURATION string = "PT6M16S"
- VALID_MIN_BUFFER_TIME string = "PT1.97S"
- VALID_AVAILABILITY_START_TIME string = "1970-01-01T00:00:00Z"
- VALID_PUBLISH_TIME string = "2020-03-12T10:39:45Z"
- 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_LABEL 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_SCHEME_ID_URI string = "https://aomedia.org/emsg/ID3"
+ 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"
+ VALID_PUBLISH_TIME string = "2020-03-12T10:39:45Z"
+ VALID_SUBTITLE_LABEL string = "Subtitle (En)"
+ VALID_SCHEME_ID_URI string = "https://aomedia.org/emsg/ID3"
)
func TestNewMPDLive(t *testing.T) {
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/scte35.go b/mpd/scte35.go
new file mode 100644
index 0000000..defbb2f
--- /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,
+ })
+}
diff --git a/mpd/segment_list_test.go b/mpd/segment_list_test.go
index 40cf500..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) {
@@ -23,6 +23,7 @@ func TestSegmentListDeserialization(t *testing.T) {
if err == nil {
expected := getSegmentListMPD()
+ require.EqualString(t, m.Comment, "Generated with https://github.com/shaka-project/shaka-packager version 288eddc863-release")
require.EqualStringSlice(t, expected.Periods[0].BaseURL, m.Periods[0].BaseURL)
expectedAudioSegList := expected.Periods[0].AdaptationSets[0].Representations[0].SegmentList
@@ -60,6 +61,7 @@ func TestSegmentListDeserialization(t *testing.T) {
func getSegmentListMPD() *MPD {
m := NewMPD(DASH_PROFILE_LIVE, "PT30.016S", "PT2.000S")
m.period.BaseURL = []string{"http://localhost:8002/dash/"}
+ m.Comment = "Generated with https://github.com/shaka-project/shaka-packager version 288eddc863-release"
aas, _ := m.AddNewAdaptationSetAudioWithID("1", "audio/mp4", true, 1, "English")
ra, _ := aas.AddNewRepresentationAudio(48000, 255000, "mp4a.40.2", "audio_1")
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) {