Skip to content

Commit

Permalink
Merge pull request #19 from cbsinteractive/Dovi81
Browse files Browse the repository at this point in the history
feat: Support Dolby Vision 8.1 DASH tags
  • Loading branch information
vish91 authored Jul 11, 2024
2 parents c20d8d5 + ebe10ac commit 8bfff11
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 18 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/cbsinteractive/go-dash/v3

go 1.16
go 1.22
7 changes: 3 additions & 4 deletions helpers/testfixtures/testfixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package testfixtures

import (
"fmt"
"io/ioutil"
"os"
"testing"

Expand All @@ -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()))
}
Expand All @@ -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)
Expand Down
95 changes: 95 additions & 0 deletions mpd/fixtures/ondemand_withdolby.mpd
Original file line number Diff line number Diff line change
@@ -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>
89 changes: 76 additions & 13 deletions mpd/mpd.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ var (

type MPD struct {
XMLNs *string `xml:"xmlns,attr"`
XMLNsDolby *string `xml:"xmlns:dolby,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"`
Expand Down Expand Up @@ -108,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
Expand Down Expand Up @@ -246,9 +265,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
}
Expand Down Expand Up @@ -434,15 +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
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"`
}
Expand All @@ -460,7 +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 = &XmlnsAttr{
XmlName: xml.Name{Space: "xmlns", Local: "scte214"},
Value: "urn:scte:dash:scte214-extensions",
}
}

// Creates a new static MPD object.
Expand Down Expand Up @@ -1114,6 +1153,30 @@ 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 = &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
}

// 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.
Expand Down
Loading

0 comments on commit 8bfff11

Please sign in to comment.