Skip to content

Commit 8bfff11

Browse files
authored
Merge pull request #19 from cbsinteractive/Dovi81
feat: Support Dolby Vision 8.1 DASH tags
2 parents c20d8d5 + ebe10ac commit 8bfff11

File tree

6 files changed

+316
-18
lines changed

6 files changed

+316
-18
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/cbsinteractive/go-dash/v3
22

3-
go 1.16
3+
go 1.22

helpers/testfixtures/testfixtures.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package testfixtures
22

33
import (
44
"fmt"
5-
"io/ioutil"
65
"os"
76
"testing"
87

@@ -11,7 +10,7 @@ import (
1110

1211
// Load test fixture from path relative to fixtures directory
1312
func LoadFixture(path string) (js string) {
14-
f, err := ioutil.ReadFile(path)
13+
f, err := os.ReadFile(path)
1514
if err != nil {
1615
panic(fmt.Sprintf("LoadFixture Error. ioutil.ReadFile. path = %s, Err = %s", path, err.Error()))
1716
}
@@ -22,8 +21,8 @@ func CompareFixture(t *testing.T, fixturePath string, actualContent string) {
2221
t.Helper()
2322
expectedContent := LoadFixture(fixturePath)
2423
if os.Getenv("GENERATE_FIXTURES") != "" {
25-
_ = ioutil.WriteFile(fixturePath, []byte(actualContent), os.ModePerm)
26-
fmt.Println("Wrote fixture: " + fixturePath)
24+
_ = os.WriteFile(fixturePath, []byte(actualContent), os.ModePerm)
25+
fmt.Println("GEN FIXTURES - Wrote fixture: " + fixturePath)
2726
return
2827
}
2928
require.EqualString(t, expectedContent, actualContent)
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<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">
3+
<Period>
4+
<AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="1" segmentAlignment="true" lang="en-US">
5+
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
6+
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
7+
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
8+
</ContentProtection>
9+
<ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
10+
<mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
11+
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
12+
</ContentProtection>
13+
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
14+
<Representation audioSamplingRate="44100" bandwidth="128558" codecs="mp4a.40.5" id="800k/audio-en-US">
15+
<BaseURL>800k/output-audio-en-US.mp4</BaseURL>
16+
<SegmentBase indexRange="629-756">
17+
<Initialization range="0-628"></Initialization>
18+
</SegmentBase>
19+
</Representation>
20+
<Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
21+
</AdaptationSet>
22+
<AdaptationSet mimeType="audio/mp4" startWithSAP="1" id="2" segmentAlignment="true" lang="en-US">
23+
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
24+
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
25+
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
26+
</ContentProtection>
27+
<ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
28+
<mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
29+
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
30+
</ContentProtection>
31+
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="description"></Role>
32+
<Representation audioSamplingRate="44100" bandwidth="128558" codecs="mp4a.40.5" id="800k/audio-AD-en-US">
33+
<BaseURL>800k/output-audio-AD-en-US.mp4</BaseURL>
34+
<SegmentBase indexRange="629-756">
35+
<Initialization range="0-628"></Initialization>
36+
</SegmentBase>
37+
</Representation>
38+
<Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
39+
<Accessibility schemeIdUri="urn:tva:metadata:cs:AudioPurposeCS:2007" value="1"></Accessibility>
40+
</AdaptationSet>
41+
<AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="3" segmentAlignment="true">
42+
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
43+
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
44+
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
45+
</ContentProtection>
46+
<ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
47+
<mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
48+
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
49+
</ContentProtection>
50+
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
51+
<Representation bandwidth="1100690" codecs="avc1.4d401e" frameRate="30000/1001" height="360" id="800k/video-1" width="640">
52+
<BaseURL>800k/output-video-1.mp4</BaseURL>
53+
<SegmentBase indexRange="686-813">
54+
<Initialization range="0-685"></Initialization>
55+
</SegmentBase>
56+
</Representation>
57+
<Representation bandwidth="1633516" codecs="avc1.4d401f" frameRate="30000/1001" height="540" id="1200k/video-1" width="960">
58+
<BaseURL>1200k/output-video-1.mp4</BaseURL>
59+
<SegmentBase indexRange="686-813">
60+
<Initialization range="0-685"></Initialization>
61+
</SegmentBase>
62+
</Representation>
63+
</AdaptationSet>
64+
<AdaptationSet mimeType="video/mp4" startWithSAP="1" scanType="progressive" id="4" segmentAlignment="true">
65+
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" xmlns:cenc="urn:mpeg:cenc:2013" cenc:default_KID="08e36702-8f33-436c-a5dd-60ffe5571e60" value="cenc"></ContentProtection>
66+
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" xmlns:cenc="urn:mpeg:cenc:2013">
67+
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAAAYXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEEIARIQWr3VL1VKTyq40GH3YUJRVRoIY2FzdGxhYnMiGFdyM1ZMMVZLVHlxNDBHSDNZVUpSVlE9PTIHZGVmYXVsdA==</cenc:pssh>
68+
</ContentProtection>
69+
<ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready">
70+
<mspr:pro>BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATAA5AFcAOQBXAGsAcABWAEsAawArADQAMABHAEgAMwBZAFUASgBSAFYAUQA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEsAegBZADIASABaAEwAQQBsAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=</mspr:pro>
71+
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</cenc:pssh>
72+
</ContentProtection>
73+
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
74+
<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">
75+
<BaseURL>800k/output-video-1.mp4</BaseURL>
76+
<SegmentBase indexRange="686-813">
77+
<Initialization range="0-685"></Initialization>
78+
</SegmentBase>
79+
</Representation>
80+
<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">
81+
<BaseURL>1200k/output-video-1.mp4</BaseURL>
82+
<SegmentBase indexRange="686-813">
83+
<Initialization range="0-685"></Initialization>
84+
</SegmentBase>
85+
</Representation>
86+
</AdaptationSet>
87+
<AdaptationSet mimeType="text/vtt" id="5" lang="en">
88+
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"></Role>
89+
<Label>Subtitle (En)</Label>
90+
<Representation bandwidth="256" id="subtitle_en">
91+
<BaseURL>http://example.com/content/sintel/subtitles/subtitles_en.vtt</BaseURL>
92+
</Representation>
93+
</AdaptationSet>
94+
</Period>
95+
</MPD>

mpd/mpd.go

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ var (
7272

7373
type MPD struct {
7474
XMLNs *string `xml:"xmlns,attr"`
75-
XMLNsDolby *string `xml:"xmlns:dolby,attr"`
75+
XMLNsDolby *XmlnsAttr `xml:"dolby,attr"`
76+
XMLNsSCTE214 *XmlnsAttr `xml:"scte214,attr"`
7677
Scte35NS *Scte35NS `xml:"scte35,attr,omitempty"`
7778
XsiNS *XmlnsAttr `xml:"xsi,attr,omitempty"`
7879
XsiSchemaLocation *XsiSL `xml:"schemaLocation,attr,omitempty"`
@@ -108,9 +109,27 @@ func (s *XmlnsAttr) UnmarshalXMLAttr(attr xml.Attr) error {
108109
}
109110

110111
func (s *XmlnsAttr) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
112+
if s == nil {
113+
return xml.Attr{}, nil
114+
}
111115
return xml.Attr{Name: xml.Name{Local: fmt.Sprintf("xmlns:%s", s.XmlName.Local)}, Value: s.Value}, nil
112116
}
113117

118+
type Scte214Attr struct {
119+
XmlName xml.Name
120+
Value string
121+
}
122+
123+
func (s *Scte214Attr) UnmarshalXMLAttr(attr xml.Attr) error {
124+
s.XmlName = attr.Name
125+
s.Value = attr.Value
126+
return nil
127+
}
128+
129+
func (s *Scte214Attr) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
130+
return xml.Attr{Name: xml.Name{Local: fmt.Sprintf("scte214:%s", s.XmlName.Local)}, Value: s.Value}, nil
131+
}
132+
114133
type XsiSL struct {
115134
XmlName xml.Name
116135
Value string
@@ -246,9 +265,17 @@ func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
246265
return err
247266
}
248267
*as = AdaptationSet(n.wrappedAdaptationSet)
268+
269+
if as.Roles != nil {
270+
as.Roles = n.Roles
271+
}
272+
249273
as.ContentProtection = make([]ContentProtectioner, len(n.ContentProtection))
250-
for i := range n.ContentProtection {
251-
as.ContentProtection[i] = n.ContentProtection[i]
274+
copy(as.ContentProtection, n.ContentProtection)
275+
276+
for i := range as.Representations {
277+
as.Representations[i].SupplementalCodecs = n.Representations[i].SupplementalCodecs
278+
as.Representations[i].SupplementalProfiles = n.Representations[i].SupplementalProfiles
252279
}
253280
return nil
254281
}
@@ -434,15 +461,17 @@ type Representation struct {
434461
CommonAttributesAndElements
435462
AdaptationSet *AdaptationSet `xml:"-"`
436463
AudioChannelConfiguration *AudioChannelConfiguration `xml:"AudioChannelConfiguration,omitempty"`
437-
AudioSamplingRate *int64 `xml:"audioSamplingRate,attr"` // Audio
438-
Bandwidth *int64 `xml:"bandwidth,attr"` // Audio + Video
439-
Codecs *string `xml:"codecs,attr"` // Audio + Video
440-
FrameRate *string `xml:"frameRate,attr,omitempty"` // Video
441-
Height *int64 `xml:"height,attr"` // Video
442-
ID *string `xml:"id,attr"` // Audio + Video
443-
Width *int64 `xml:"width,attr"` // Video
444-
BaseURL []string `xml:"BaseURL,omitempty"` // On-Demand Profile
445-
SegmentBase *SegmentBase `xml:"SegmentBase,omitempty"` // On-Demand Profile
464+
AudioSamplingRate *int64 `xml:"audioSamplingRate,attr"` // Audio
465+
Bandwidth *int64 `xml:"bandwidth,attr"` // Audio + Video
466+
Codecs *string `xml:"codecs,attr"` // Audio + Video
467+
SupplementalCodecs *Scte214Attr `xml:"supplementalCodecs,attr,omitempty"` // Video
468+
SupplementalProfiles *Scte214Attr `xml:"supplementalProfiles,attr,omitempty"` // Video
469+
FrameRate *string `xml:"frameRate,attr,omitempty"` // Video
470+
Height *int64 `xml:"height,attr"` // Video
471+
ID *string `xml:"id,attr"` // Audio + Video
472+
Width *int64 `xml:"width,attr"` // Video
473+
BaseURL []string `xml:"BaseURL,omitempty"` // On-Demand Profile
474+
SegmentBase *SegmentBase `xml:"SegmentBase,omitempty"` // On-Demand Profile
446475
SegmentList *SegmentList `xml:"SegmentList,omitempty"`
447476
SegmentTemplate *SegmentTemplate `xml:"SegmentTemplate,omitempty"`
448477
}
@@ -460,7 +489,17 @@ type AudioChannelConfiguration struct {
460489
}
461490

462491
func (m *MPD) SetDolbyXMLNs() {
463-
m.XMLNsDolby = Strptr("http://www.dolby.com/ns/online/DASH")
492+
m.XMLNsDolby = &XmlnsAttr{
493+
XmlName: xml.Name{Space: "xmlns", Local: "dolby"},
494+
Value: "http://www.dolby.com/ns/online/DASH",
495+
}
496+
}
497+
498+
func (m *MPD) SetScte214XMLNs() {
499+
m.XMLNsSCTE214 = &XmlnsAttr{
500+
XmlName: xml.Name{Space: "xmlns", Local: "scte214"},
501+
Value: "urn:scte:dash:scte214-extensions",
502+
}
464503
}
465504

466505
// Creates a new static MPD object.
@@ -1114,6 +1153,30 @@ func (as *AdaptationSet) AddNewRepresentationVideo(bandwidth int64, codecs strin
11141153
return r, nil
11151154
}
11161155

1156+
// Adds supplementalCodecs and supplementalProfiles to a Representation
1157+
// supplementalCodecs - scte214:supplementalCodecs attribute for Dovi 8.1 signaling (optional).
1158+
// supplementalProfiles - scte214:supplementalProfiles attribute for Dovi 8.1 signaling (optional).
1159+
func (r *Representation) AddScte214VideoCodecProperties(supplementalCodecs string, supplementalProfiles string) (*Representation, error) {
1160+
// For Dovi 8.1 signaling both supplementalCodecs and supplementalProfiles should be added
1161+
if len(supplementalCodecs) > 0 && len(supplementalProfiles) > 0 {
1162+
r.SupplementalCodecs = &Scte214Attr{
1163+
XmlName: xml.Name{
1164+
Space: "scte214",
1165+
Local: "supplementalCodecs",
1166+
},
1167+
Value: supplementalCodecs,
1168+
}
1169+
r.SupplementalProfiles = &Scte214Attr{
1170+
XmlName: xml.Name{
1171+
Space: "scte214",
1172+
Local: "supplementalProfiles",
1173+
},
1174+
Value: supplementalProfiles,
1175+
}
1176+
}
1177+
return r, nil
1178+
}
1179+
11171180
// Adds a new Subtitle representation to an AdaptationSet.
11181181
// bandwidth - in Bits/s (i.e. 256).
11191182
// id - ID for this representation, will get used as $RepresentationID$ in template strings.

0 commit comments

Comments
 (0)