Skip to content

Commit 29fffaa

Browse files
adding playready 10 for go-dash
1 parent 487c680 commit 29fffaa

File tree

2 files changed

+105
-12
lines changed

2 files changed

+105
-12
lines changed

mpd/mpd.go

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,16 @@ type AdaptationSet struct {
9393

9494
// Constants for DRM / ContentProtection
9595
const (
96-
CONTENT_PROTECTION_ROOT_SCHEME_ID_URI = "urn:mpeg:dash:mp4protection:2011"
97-
CONTENT_PROTECTION_ROOT_VALUE = "cenc"
98-
CENC_XMLNS = "urn:mpeg:cenc:2013"
99-
CONTENT_PROTECTION_WIDEVINE_SCHEME_ID = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
100-
CONTENT_PROTECTION_WIDEVINE_SCHEME_HEX = "edef8ba979d64acea3c827dcd51d21ed"
101-
CONTENT_PROTECTION_PLAYREADY_SCHEME_ID = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"
102-
CONTENT_PROTECTION_PLAYREADY_SCHEME_HEX = "9a04f07998404286ab92e65be0885f95"
103-
CONTENT_PROTECTION_PLAYREADY_XMLNS = "urn:microsoft:playready"
96+
CONTENT_PROTECTION_ROOT_SCHEME_ID_URI = "urn:mpeg:dash:mp4protection:2011"
97+
CONTENT_PROTECTION_ROOT_VALUE = "cenc"
98+
CENC_XMLNS = "urn:mpeg:cenc:2013"
99+
CONTENT_PROTECTION_WIDEVINE_SCHEME_ID = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
100+
CONTENT_PROTECTION_WIDEVINE_SCHEME_HEX = "edef8ba979d64acea3c827dcd51d21ed"
101+
CONTENT_PROTECTION_PLAYREADY_SCHEME_ID = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"
102+
CONTENT_PROTECTION_PLAYREADY_SCHEME_HEX = "9a04f07998404286ab92e65be0885f95"
103+
CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID = "urn:uuid:79f0049a-4098-8642-ab92-e65be0885f95"
104+
CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_HEX = "79f0049a40988642ab92e65be0885f95"
105+
CONTENT_PROTECTION_PLAYREADY_XMLNS = "urn:microsoft:playready"
104106
)
105107

106108
type ContentProtectioner interface {
@@ -332,7 +334,7 @@ func NewWidevineContentProtection(wvHeader []byte) (*WidevineContentProtection,
332334
// AddNewContentProtectionSchemePlayready adds a new content protection scheme for PlayReady DRM.
333335
// pro - PlayReady Object Header, as a Base64 encoded string.
334336
func (as *AdaptationSet) AddNewContentProtectionSchemePlayready(pro string) (*PlayreadyContentProtection, error) {
335-
cp, err := newPlayreadyContentProtection(pro)
337+
cp, err := newPlayreadyContentProtection(pro, CONTENT_PROTECTION_PLAYREADY_SCHEME_ID)
336338
if err != nil {
337339
return nil, err
338340
}
@@ -344,7 +346,22 @@ func (as *AdaptationSet) AddNewContentProtectionSchemePlayready(pro string) (*Pl
344346
return cp, nil
345347
}
346348

347-
func newPlayreadyContentProtection(pro string) (*PlayreadyContentProtection, error) {
349+
// AddNewContentProtectionSchemePlayreadyV10 adds a new content protection scheme for PlayReady v1.0 DRM.
350+
// pro - PlayReady Object Header, as a Base64 encoded string.
351+
func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyV10(pro string) (*PlayreadyContentProtection, error) {
352+
cp, err := newPlayreadyContentProtection(pro, CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID)
353+
if err != nil {
354+
return nil, err
355+
}
356+
357+
err = as.AddContentProtection(cp)
358+
if err != nil {
359+
return nil, err
360+
}
361+
return cp, nil
362+
}
363+
364+
func newPlayreadyContentProtection(pro string, schemeIDURI string) (*PlayreadyContentProtection, error) {
348365
if pro == "" {
349366
return nil, ErrPROEmpty
350367
}
@@ -353,7 +370,7 @@ func newPlayreadyContentProtection(pro string) (*PlayreadyContentProtection, err
353370
PlayreadyXMLNS: Strptr(CONTENT_PROTECTION_PLAYREADY_XMLNS),
354371
PRO: Strptr(pro),
355372
}
356-
cp.SchemeIDURI = Strptr(CONTENT_PROTECTION_PLAYREADY_SCHEME_ID)
373+
cp.SchemeIDURI = Strptr(schemeIDURI)
357374

358375
return cp, nil
359376
}
@@ -362,7 +379,7 @@ func newPlayreadyContentProtection(pro string) (*PlayreadyContentProtection, err
362379
// will include both ms:pro and cenc:pssh subelements
363380
// pro - PlayReady Object Header, as a Base64 encoded string.
364381
func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyWithPSSH(pro string) (*PlayreadyContentProtection, error) {
365-
cp, err := newPlayreadyContentProtection(pro)
382+
cp, err := newPlayreadyContentProtection(pro, CONTENT_PROTECTION_PLAYREADY_SCHEME_ID)
366383
if err != nil {
367384
return nil, err
368385
}
@@ -390,6 +407,38 @@ func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyWithPSSH(pro stri
390407
return cp, nil
391408
}
392409

410+
// AddNewContentProtectionSchemePlayreadyV10WithPSSH adds a new content protection scheme for PlayReady v1.0 DRM. The scheme
411+
// will include both ms:pro and cenc:pssh subelements
412+
// pro - PlayReady Object Header, as a Base64 encoded string.
413+
func (as *AdaptationSet) AddNewContentProtectionSchemePlayreadyV10WithPSSH(pro string) (*PlayreadyContentProtection, error) {
414+
cp, err := newPlayreadyContentProtection(pro, CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID)
415+
if err != nil {
416+
return nil, err
417+
}
418+
cp.XMLNS = Strptr(CENC_XMLNS)
419+
prSystemID, err := hex.DecodeString(CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_HEX)
420+
if err != nil {
421+
panic(err.Error())
422+
}
423+
424+
proBin, err := base64.StdEncoding.DecodeString(pro)
425+
if err != nil {
426+
return nil, err
427+
}
428+
429+
psshBox, err := makePSSHBox(prSystemID, proBin)
430+
if err != nil {
431+
return nil, err
432+
}
433+
cp.PSSH = Strptr(base64.StdEncoding.EncodeToString(psshBox))
434+
435+
err = as.AddContentProtection(cp)
436+
if err != nil {
437+
return nil, err
438+
}
439+
return cp, nil
440+
}
441+
393442
// Internal helper method for adding a ContentProtection to an AdaptationSet.
394443
func (as *AdaptationSet) AddContentProtection(cp ContentProtectioner) error {
395444
if cp == nil {

mpd/mpd_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,32 @@ func (s *MPDSuite) TestAddNewContentProtectionSchemePlayready() {
330330
assert.Equal(s.T(), expectedCP, cp)
331331
}
332332

333+
func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyV10ErrorEmptyPRO() {
334+
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
335+
as, _ := m.AddNewAdaptationSetVideo(DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)
336+
337+
cp, err := as.AddNewContentProtectionSchemePlayreadyV10("")
338+
assert.NotNil(s.T(), err)
339+
assert.Equal(s.T(), ErrPROEmpty, err)
340+
assert.Nil(s.T(), cp)
341+
}
342+
343+
func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyV10() {
344+
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
345+
as, _ := m.AddNewAdaptationSetVideo(DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)
346+
347+
cp, err := as.AddNewContentProtectionSchemePlayreadyV10(VALID_PLAYREADY_PRO)
348+
assert.Nil(s.T(), err)
349+
assert.NotNil(s.T(), cp)
350+
expectedCP := &PlayreadyContentProtection{
351+
PlayreadyXMLNS: Strptr(VALID_PLAYREADY_XMLNS),
352+
PRO: Strptr(VALID_PLAYREADY_PRO),
353+
}
354+
expectedCP.SchemeIDURI = Strptr(CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID)
355+
356+
assert.Equal(s.T(), expectedCP, cp)
357+
}
358+
333359
func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyWithPSSH() {
334360
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
335361
as, _ := m.AddNewAdaptationSetVideo(DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)
@@ -348,6 +374,24 @@ func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyWithPSSH() {
348374
assert.Equal(s.T(), expectedCP, cp)
349375
}
350376

377+
func (s *MPDSuite) TestAddNewContentProtectionSchemePlayreadyV10WithPSSH() {
378+
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
379+
as, _ := m.AddNewAdaptationSetVideo(DASH_MIME_TYPE_VIDEO_MP4, VALID_SCAN_TYPE, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP)
380+
381+
cp, err := as.AddNewContentProtectionSchemePlayreadyV10WithPSSH(VALID_PLAYREADY_PRO)
382+
assert.Nil(s.T(), err)
383+
assert.NotNil(s.T(), cp)
384+
expectedCP := &PlayreadyContentProtection{
385+
PlayreadyXMLNS: Strptr(VALID_PLAYREADY_XMLNS),
386+
PRO: Strptr(VALID_PLAYREADY_PRO),
387+
}
388+
expectedCP.SchemeIDURI = Strptr(CONTENT_PROTECTION_PLAYREADY_SCHEME_V10_ID)
389+
expectedCP.XMLNS = Strptr(CENC_XMLNS)
390+
expectedCP.PSSH = Strptr("AAACJnBzc2gAAAAAefAEmkCYhkKrkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBMADkAVwA5AFcAawBwAFYASwBrACsANAAwAEcASAAzAFkAVQBKAFIAVgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AEkASwB6AFkAMgBIAFoATABBAGwASQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==")
391+
392+
assert.Equal(s.T(), expectedCP, cp)
393+
}
394+
351395
func (s *MPDSuite) TestSetNewSegmentTemplate() {
352396
m := NewMPD(DASH_PROFILE_LIVE, VALID_MEDIA_PRESENTATION_DURATION, VALID_MIN_BUFFER_TIME)
353397
audioAS, _ := m.AddNewAdaptationSetAudio(DASH_MIME_TYPE_AUDIO_MP4, VALID_SEGMENT_ALIGNMENT, VALID_START_WITH_SAP, VALID_LANG)

0 commit comments

Comments
 (0)