Skip to content

Commit

Permalink
adding playready 10 for go-dash (#32)
Browse files Browse the repository at this point in the history
Add playready 1.0 support to go-dash
  • Loading branch information
jyehbrightcove authored and philcluff committed Sep 18, 2016
1 parent 487c680 commit d312eef
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 12 deletions.
73 changes: 61 additions & 12 deletions mpd/mpd.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,16 @@ type AdaptationSet struct {

// Constants for DRM / ContentProtection
const (
CONTENT_PROTECTION_ROOT_SCHEME_ID_URI = "urn:mpeg:dash:mp4protection:2011"
CONTENT_PROTECTION_ROOT_VALUE = "cenc"
CENC_XMLNS = "urn:mpeg:cenc:2013"
CONTENT_PROTECTION_WIDEVINE_SCHEME_ID = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
CONTENT_PROTECTION_WIDEVINE_SCHEME_HEX = "edef8ba979d64acea3c827dcd51d21ed"
CONTENT_PROTECTION_PLAYREADY_SCHEME_ID = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"
CONTENT_PROTECTION_PLAYREADY_SCHEME_HEX = "9a04f07998404286ab92e65be0885f95"
CONTENT_PROTECTION_PLAYREADY_XMLNS = "urn:microsoft:playready"
CONTENT_PROTECTION_ROOT_SCHEME_ID_URI = "urn:mpeg:dash:mp4protection:2011"
CONTENT_PROTECTION_ROOT_VALUE = "cenc"
CENC_XMLNS = "urn:mpeg:cenc:2013"
CONTENT_PROTECTION_WIDEVINE_SCHEME_ID = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
CONTENT_PROTECTION_WIDEVINE_SCHEME_HEX = "edef8ba979d64acea3c827dcd51d21ed"
CONTENT_PROTECTION_PLAYREADY_SCHEME_ID = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"
CONTENT_PROTECTION_PLAYREADY_SCHEME_HEX = "9a04f07998404286ab92e65be0885f95"
CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID = "urn:uuid:79f0049a-4098-8642-ab92-e65be0885f95"
CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_HEX = "79f0049a40988642ab92e65be0885f95"
CONTENT_PROTECTION_PLAYREADY_XMLNS = "urn:microsoft:playready"
)

type ContentProtectioner interface {
Expand Down Expand Up @@ -332,7 +334,7 @@ func NewWidevineContentProtection(wvHeader []byte) (*WidevineContentProtection,
// AddNewContentProtectionSchemePlayready adds a new content protection scheme for PlayReady DRM.
// pro - PlayReady Object Header, as a Base64 encoded string.
func (as *AdaptationSet) AddNewContentProtectionSchemePlayready(pro string) (*PlayreadyContentProtection, error) {
cp, err := newPlayreadyContentProtection(pro)
cp, err := newPlayreadyContentProtection(pro, CONTENT_PROTECTION_PLAYREADY_SCHEME_ID)
if err != nil {
return nil, err
}
Expand All @@ -344,7 +346,22 @@ func (as *AdaptationSet) AddNewContentProtectionSchemePlayready(pro string) (*Pl
return cp, nil
}

func newPlayreadyContentProtection(pro string) (*PlayreadyContentProtection, error) {
// AddNewContentProtectionSchemePlayreadyV10 adds a new content protection scheme for PlayReady v1.0 DRM.
// pro - PlayReady Object Header, as a Base64 encoded string.
func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyV10(pro string) (*PlayreadyContentProtection, error) {
cp, err := newPlayreadyContentProtection(pro, CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID)
if err != nil {
return nil, err
}

err = as.AddContentProtection(cp)
if err != nil {
return nil, err
}
return cp, nil
}

func newPlayreadyContentProtection(pro string, schemeIDURI string) (*PlayreadyContentProtection, error) {
if pro == "" {
return nil, ErrPROEmpty
}
Expand All @@ -353,7 +370,7 @@ func newPlayreadyContentProtection(pro string) (*PlayreadyContentProtection, err
PlayreadyXMLNS: Strptr(CONTENT_PROTECTION_PLAYREADY_XMLNS),
PRO: Strptr(pro),
}
cp.SchemeIDURI = Strptr(CONTENT_PROTECTION_PLAYREADY_SCHEME_ID)
cp.SchemeIDURI = Strptr(schemeIDURI)

return cp, nil
}
Expand All @@ -362,7 +379,7 @@ func newPlayreadyContentProtection(pro string) (*PlayreadyContentProtection, err
// will include both ms:pro and cenc:pssh subelements
// pro - PlayReady Object Header, as a Base64 encoded string.
func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyWithPSSH(pro string) (*PlayreadyContentProtection, error) {
cp, err := newPlayreadyContentProtection(pro)
cp, err := newPlayreadyContentProtection(pro, CONTENT_PROTECTION_PLAYREADY_SCHEME_ID)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -390,6 +407,38 @@ func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyWithPSSH(pro stri
return cp, nil
}

// AddNewContentProtectionSchemePlayreadyV10WithPSSH adds a new content protection scheme for PlayReady v1.0 DRM. The scheme
// will include both ms:pro and cenc:pssh subelements
// pro - PlayReady Object Header, as a Base64 encoded string.
func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyV10WithPSSH(pro string) (*PlayreadyContentProtection, error) {
cp, err := newPlayreadyContentProtection(pro, CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID)
if err != nil {
return nil, err
}
cp.XMLNS = Strptr(CENC_XMLNS)
prSystemID, err := hex.DecodeString(CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_HEX)
if err != nil {
panic(err.Error())
}

proBin, err := base64.StdEncoding.DecodeString(pro)
if err != nil {
return nil, err
}

psshBox, err := makePSSHBox(prSystemID, proBin)
if err != nil {
return nil, err
}
cp.PSSH = Strptr(base64.StdEncoding.EncodeToString(psshBox))

err = as.AddContentProtection(cp)
if err != nil {
return nil, err
}
return cp, nil
}

// Internal helper method for adding a ContentProtection to an AdaptationSet.
func (as *AdaptationSet) AddContentProtection(cp ContentProtectioner) error {
if cp == nil {
Expand Down
44 changes: 44 additions & 0 deletions mpd/mpd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,32 @@ func (s *MPDSuite) TestAddNewContentProtectionSchemePlayready() {
assert.Equal(s.T(), expectedCP, cp)
}

func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyV10ErrorEmptyPRO() {
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
as, _ := m.AddNewAdaptationSetVideo(DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)

cp, err := as.AddNewContentProtectionSchemePlayreadyV10("")
assert.NotNil(s.T(), err)
assert.Equal(s.T(), ErrPROEmpty, err)
assert.Nil(s.T(), cp)
}

func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyV10() {
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
as, _ := m.AddNewAdaptationSetVideo(DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)

cp, err := as.AddNewContentProtectionSchemePlayreadyV10(VALID_PLAYREADY_PRO)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), cp)
expectedCP := &PlayreadyContentProtection{
PlayreadyXMLNS: Strptr(VALID_PLAYREADY_XMLNS),
PRO: Strptr(VALID_PLAYREADY_PRO),
}
expectedCP.SchemeIDURI = Strptr(CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID)

assert.Equal(s.T(), expectedCP, cp)
}

func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyWithPSSH() {
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
as, _ := m.AddNewAdaptationSetVideo(DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)
Expand All @@ -348,6 +374,24 @@ func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyWithPSSH() {
assert.Equal(s.T(), expectedCP, cp)
}

func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyV10WithPSSH() {
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
as, _ := m.AddNewAdaptationSetVideo(DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)

cp, err := as.AddNewContentProtectionSchemePlayreadyV10WithPSSH(VALID_PLAYREADY_PRO)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), cp)
expectedCP := &PlayreadyContentProtection{
PlayreadyXMLNS: Strptr(VALID_PLAYREADY_XMLNS),
PRO: Strptr(VALID_PLAYREADY_PRO),
}
expectedCP.SchemeIDURI = Strptr(CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID)
expectedCP.XMLNS = Strptr(CENC_XMLNS)
expectedCP.PSSH = Strptr("AAACJnBzc2gAAAAAefAEmkCYhkKrkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==")

assert.Equal(s.T(), expectedCP, cp)
}

func (s *MPDSuite) TestSetNewSegmentTemplate() {
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
audioAS, _ := m.AddNewAdaptationSetAudio(DASH_MIME_TYPE_AUDIO_MP4, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP, VALID_LANG)
Expand Down

0 comments on commit d312eef

Please sign in to comment.