Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support Dolby Vision 8.1 DASH tags #19

Merged
merged 2 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading