Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
95218076
authored
Jul 07, 2022
by
Rohit Singh
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge pull request #10260 from sr1990:clearkey_parse_licenseurl
PiperOrigin-RevId: 459215225
parents
77d353b5
c659fe94
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
100 additions
and
1 deletions
library/common/src/main/java/com/google/android/exoplayer2/drm/DrmInitData.java
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java
library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java
testdata/src/test/assets/media/mpd/sample_mpd_clear_key_license_url
library/common/src/main/java/com/google/android/exoplayer2/drm/DrmInitData.java
View file @
95218076
...
...
@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.drm;
import
android.os.Parcel
;
import
android.os.Parcelable
;
import
android.text.TextUtils
;
import
androidx.annotation.CheckResult
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.drm.DrmInitData.SchemeData
;
...
...
@@ -156,6 +157,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
* @param schemeType A protection scheme type. May be null.
* @return A copy with the specified protection scheme type.
*/
@CheckResult
public
DrmInitData
copyWithSchemeType
(
@Nullable
String
schemeType
)
{
if
(
Util
.
areEqual
(
this
.
schemeType
,
schemeType
))
{
return
this
;
...
...
@@ -332,6 +334,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
* @param data The data to include in the copy.
* @return The new instance.
*/
@CheckResult
public
SchemeData
copyWithData
(
@Nullable
byte
[]
data
)
{
return
new
SchemeData
(
uuid
,
licenseServerUrl
,
mimeType
,
data
);
}
...
...
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java
View file @
95218076
...
...
@@ -597,6 +597,9 @@ public class DashManifestParser extends DefaultHandler
case
"urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
:
uuid
=
C
.
WIDEVINE_UUID
;
break
;
case
"urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e"
:
uuid
=
C
.
CLEARKEY_UUID
;
break
;
default
:
break
;
}
...
...
@@ -604,7 +607,9 @@ public class DashManifestParser extends DefaultHandler
do
{
xpp
.
next
();
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"ms:laurl"
))
{
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"clearkey:Laurl"
)
&&
xpp
.
next
()
==
XmlPullParser
.
TEXT
)
{
licenseServerUrl
=
xpp
.
getText
();
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"ms:laurl"
))
{
licenseServerUrl
=
xpp
.
getAttributeValue
(
null
,
"licenseUrl"
);
}
else
if
(
data
==
null
&&
XmlPullParserUtil
.
isStartTagIgnorePrefix
(
xpp
,
"pssh"
)
...
...
@@ -851,6 +856,7 @@ public class DashManifestParser extends DefaultHandler
ArrayList
<
SchemeData
>
drmSchemeDatas
=
representationInfo
.
drmSchemeDatas
;
drmSchemeDatas
.
addAll
(
extraDrmSchemeDatas
);
if
(!
drmSchemeDatas
.
isEmpty
())
{
fillInClearKeyInformation
(
drmSchemeDatas
);
filterRedundantIncompleteSchemeDatas
(
drmSchemeDatas
);
formatBuilder
.
setDrmInitData
(
new
DrmInitData
(
drmSchemeType
,
drmSchemeDatas
));
}
...
...
@@ -1658,6 +1664,32 @@ public class DashManifestParser extends DefaultHandler
}
}
private
static
void
fillInClearKeyInformation
(
ArrayList
<
SchemeData
>
schemeDatas
)
{
// Find and remove ClearKey information.
@Nullable
String
clearKeyLicenseServerUrl
=
null
;
for
(
int
i
=
0
;
i
<
schemeDatas
.
size
();
i
++)
{
SchemeData
schemeData
=
schemeDatas
.
get
(
i
);
if
(
C
.
CLEARKEY_UUID
.
equals
(
schemeData
.
uuid
)
&&
schemeData
.
licenseServerUrl
!=
null
)
{
clearKeyLicenseServerUrl
=
schemeData
.
licenseServerUrl
;
schemeDatas
.
remove
(
i
);
break
;
}
}
if
(
clearKeyLicenseServerUrl
==
null
)
{
return
;
}
// Fill in the ClearKey information into the existing PSSH schema data if applicable.
for
(
int
i
=
0
;
i
<
schemeDatas
.
size
();
i
++)
{
SchemeData
schemeData
=
schemeDatas
.
get
(
i
);
if
(
C
.
COMMON_PSSH_UUID
.
equals
(
schemeData
.
uuid
)
&&
schemeData
.
licenseServerUrl
==
null
)
{
schemeDatas
.
set
(
i
,
new
SchemeData
(
C
.
CLEARKEY_UUID
,
clearKeyLicenseServerUrl
,
schemeData
.
mimeType
,
schemeData
.
data
));
}
}
}
/**
* Derives a sample mimeType from a container mimeType and codecs attribute.
*
...
...
library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java
View file @
95218076
...
...
@@ -23,6 +23,7 @@ import androidx.test.core.app.ApplicationProvider;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.drm.DrmInitData
;
import
com.google.android.exoplayer2.metadata.emsg.EventMessage
;
import
com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation
;
import
com.google.android.exoplayer2.source.dash.manifest.Representation.SingleSegmentRepresentation
;
...
...
@@ -79,6 +80,8 @@ public class DashManifestParserTest {
"media/mpd/sample_mpd_service_description_low_latency_only_playback_rates"
;
private
static
final
String
SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY_ONLY_TARGET_LATENCY
=
"media/mpd/sample_mpd_service_description_low_latency_only_target_latency"
;
private
static
final
String
SAMPLE_MPD_CLEAR_KEY_LICENSE_URL
=
"media/mpd/sample_mpd_clear_key_license_url"
;
private
static
final
String
NEXT_TAG_NAME
=
"Next"
;
private
static
final
String
NEXT_TAG
=
"<"
+
NEXT_TAG_NAME
+
"/>"
;
...
...
@@ -880,6 +883,37 @@ public class DashManifestParserTest {
assertThat
(
manifest
.
serviceDescription
).
isNull
();
}
@Test
public
void
contentProtections_withClearKeyLicenseUrl
()
throws
IOException
{
DashManifestParser
parser
=
new
DashManifestParser
();
DashManifest
manifest
=
parser
.
parse
(
Uri
.
parse
(
"https://example.com/test.mpd"
),
TestUtil
.
getInputStream
(
ApplicationProvider
.
getApplicationContext
(),
SAMPLE_MPD_CLEAR_KEY_LICENSE_URL
));
assertThat
(
manifest
.
getPeriodCount
()).
isEqualTo
(
1
);
Period
period
=
manifest
.
getPeriod
(
0
);
assertThat
(
period
.
adaptationSets
).
hasSize
(
2
);
AdaptationSet
adaptationSet0
=
period
.
adaptationSets
.
get
(
0
);
AdaptationSet
adaptationSet1
=
period
.
adaptationSets
.
get
(
1
);
assertThat
(
adaptationSet0
.
representations
).
hasSize
(
1
);
assertThat
(
adaptationSet1
.
representations
).
hasSize
(
1
);
Representation
representation0
=
adaptationSet0
.
representations
.
get
(
0
);
Representation
representation1
=
adaptationSet1
.
representations
.
get
(
0
);
assertThat
(
representation0
.
format
.
drmInitData
.
schemeType
).
isEqualTo
(
"cenc"
);
assertThat
(
representation1
.
format
.
drmInitData
.
schemeType
).
isEqualTo
(
"cenc"
);
assertThat
(
representation0
.
format
.
drmInitData
.
schemeDataCount
).
isEqualTo
(
1
);
assertThat
(
representation1
.
format
.
drmInitData
.
schemeDataCount
).
isEqualTo
(
1
);
DrmInitData
.
SchemeData
schemeData0
=
representation0
.
format
.
drmInitData
.
get
(
0
);
DrmInitData
.
SchemeData
schemeData1
=
representation1
.
format
.
drmInitData
.
get
(
0
);
assertThat
(
schemeData0
.
uuid
).
isEqualTo
(
C
.
CLEARKEY_UUID
);
assertThat
(
schemeData1
.
uuid
).
isEqualTo
(
C
.
CLEARKEY_UUID
);
assertThat
(
schemeData0
.
licenseServerUrl
).
isEqualTo
(
"https://testserver1.test/AcquireLicense"
);
assertThat
(
schemeData1
.
licenseServerUrl
).
isEqualTo
(
"https://testserver2.test/AcquireLicense"
);
}
private
static
List
<
Descriptor
>
buildCea608AccessibilityDescriptors
(
String
value
)
{
return
Collections
.
singletonList
(
new
Descriptor
(
"urn:scte:dash:cc:cea-608:2015"
,
value
,
null
));
}
...
...
testdata/src/test/assets/media/mpd/sample_mpd_clear_key_license_url
0 → 100644
View file @
95218076
<?xml version="1.0" encoding="UTF-8"?>
<!--
Includes ContentProtection elements with additional ClearKey license URLs.
Covers all possible locations (in AdaptationSet and Representation) and possible orders of these
ContentProtection elements (CENC first or ClearKey first).
-->
<MPD
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns=
"urn:mpeg:DASH:schema:MPD:2011"
xsi:schemaLocation=
"urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd"
minBufferTime=
"PT1.500S"
profiles=
"urn:mpeg:dash:profile:isoff-main:2011"
type=
"static"
availabilityStartTime=
"2016-10-14T17:00:17"
xmlns:cenc=
"urn:mpeg:cenc:2013"
xmlns:clearkey=
"http://dashif.org/guidelines/clearKey"
>
<Period
start=
"PT0.000S"
duration=
"PT0H5M50S"
>
<SegmentTemplate
startNumber=
"0"
timescale=
"1000"
media=
"sq/$Number$"
>
<SegmentTimeline>
<S
d=
"2002"
t=
"6009"
r=
"2"
/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet
id=
"0"
mimeType=
"audio/mp4"
subsegmentAlignment=
"true"
>
<Representation
id=
"140"
codecs=
"mp4a.40.2"
audioSamplingRate=
"48000"
startWithSAP=
"1"
bandwidth=
"144000"
>
<ContentProtection
schemeIdUri=
"urn:mpeg:dash:mp4protection:2011"
value=
"cenc"
cenc:default_KID=
"9eb4050d-e44b-4802-932e-27d75083e266"
/>
<ContentProtection
value=
"ClearKey1.0"
schemeIdUri=
"urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e"
>
<clearkey:Laurl
Lic_type=
"EME-1.0"
>
https://testserver1.test/AcquireLicense
</clearkey:Laurl>
</ContentProtection>
</Representation>
</AdaptationSet>
<AdaptationSet
id=
"1"
mimeType=
"video/mp4"
subsegmentAlignment=
"true"
>
<ContentProtection
value=
"ClearKey1.0"
schemeIdUri=
"urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e"
>
<clearkey:Laurl
Lic_type=
"EME-1.0"
>
https://testserver2.test/AcquireLicense
</clearkey:Laurl>
</ContentProtection>
<ContentProtection
schemeIdUri=
"urn:mpeg:dash:mp4protection:2011"
value=
"cenc"
cenc:default_KID=
"9eb4050d-e44b-4802-932e-27d75083e266"
/>
<Representation
id=
"133"
codecs=
"avc1.4d4015"
width=
"426"
height=
"240"
startWithSAP=
"1"
bandwidth=
"258000"
frameRate=
"30"
/>
</AdaptationSet>
</Period>
</MPD>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment