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
12ed18c7
authored
Feb 14, 2019
by
aquilescanta
Committed by
Andrew Lewis
Feb 18, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add encryption information to initialization segments
PiperOrigin-RevId: 233953493
parent
1c38b226
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
90 additions
and
14 deletions
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylist.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylistParserTest.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylist.java
View file @
12ed18c7
...
@@ -88,8 +88,15 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
...
@@ -88,8 +88,15 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
* @param uri See {@link #url}.
* @param uri See {@link #url}.
* @param byterangeOffset See {@link #byterangeOffset}.
* @param byterangeOffset See {@link #byterangeOffset}.
* @param byterangeLength See {@link #byterangeLength}.
* @param byterangeLength See {@link #byterangeLength}.
* @param fullSegmentEncryptionKeyUri See {@link #fullSegmentEncryptionKeyUri}.
* @param encryptionIV See {@link #encryptionIV}.
*/
*/
public
Segment
(
String
uri
,
long
byterangeOffset
,
long
byterangeLength
)
{
public
Segment
(
String
uri
,
long
byterangeOffset
,
long
byterangeLength
,
String
fullSegmentEncryptionKeyUri
,
String
encryptionIV
)
{
this
(
this
(
uri
,
uri
,
/* initializationSegment= */
null
,
/* initializationSegment= */
null
,
...
@@ -98,8 +105,8 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
...
@@ -98,8 +105,8 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
/* relativeDiscontinuitySequence= */
-
1
,
/* relativeDiscontinuitySequence= */
-
1
,
/* relativeStartTimeUs= */
C
.
TIME_UNSET
,
/* relativeStartTimeUs= */
C
.
TIME_UNSET
,
/* drmInitData= */
null
,
/* drmInitData= */
null
,
/* fullSegmentEncryptionKeyUri= */
null
,
fullSegmentEncryptionKeyUri
,
/* encryptionIV= */
null
,
encryptionIV
,
byterangeOffset
,
byterangeOffset
,
byterangeLength
,
byterangeLength
,
/* hasGapTag= */
false
);
/* hasGapTag= */
false
);
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java
View file @
12ed18c7
...
@@ -455,8 +455,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
...
@@ -455,8 +455,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
boolean
hasGapTag
=
false
;
boolean
hasGapTag
=
false
;
DrmInitData
playlistProtectionSchemes
=
null
;
DrmInitData
playlistProtectionSchemes
=
null
;
String
e
ncryptionKeyUri
=
null
;
String
fullSegmentE
ncryptionKeyUri
=
null
;
String
e
ncryptionIV
=
null
;
String
fullSegmentE
ncryptionIV
=
null
;
TreeMap
<
String
,
SchemeData
>
currentSchemeDatas
=
new
TreeMap
<>();
TreeMap
<
String
,
SchemeData
>
currentSchemeDatas
=
new
TreeMap
<>();
String
encryptionScheme
=
null
;
String
encryptionScheme
=
null
;
DrmInitData
cachedDrmInitData
=
null
;
DrmInitData
cachedDrmInitData
=
null
;
...
@@ -489,7 +489,19 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
...
@@ -489,7 +489,19 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
segmentByteRangeOffset
=
Long
.
parseLong
(
splitByteRange
[
1
]);
segmentByteRangeOffset
=
Long
.
parseLong
(
splitByteRange
[
1
]);
}
}
}
}
initializationSegment
=
new
Segment
(
uri
,
segmentByteRangeOffset
,
segmentByteRangeLength
);
if
(
fullSegmentEncryptionKeyUri
!=
null
&&
fullSegmentEncryptionIV
==
null
)
{
// See RFC 8216, Section 4.3.2.5.
throw
new
ParserException
(
"The encryption IV attribute must be present when an initialization segment is "
+
"encrypted with METHOD=AES-128."
);
}
initializationSegment
=
new
Segment
(
uri
,
segmentByteRangeOffset
,
segmentByteRangeLength
,
fullSegmentEncryptionKeyUri
,
fullSegmentEncryptionIV
);
segmentByteRangeOffset
=
0
;
segmentByteRangeOffset
=
0
;
segmentByteRangeLength
=
C
.
LENGTH_UNSET
;
segmentByteRangeLength
=
C
.
LENGTH_UNSET
;
}
else
if
(
line
.
startsWith
(
TAG_TARGET_DURATION
))
{
}
else
if
(
line
.
startsWith
(
TAG_TARGET_DURATION
))
{
...
@@ -521,17 +533,17 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
...
@@ -521,17 +533,17 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
String
method
=
parseStringAttr
(
line
,
REGEX_METHOD
,
variableDefinitions
);
String
method
=
parseStringAttr
(
line
,
REGEX_METHOD
,
variableDefinitions
);
String
keyFormat
=
String
keyFormat
=
parseOptionalStringAttr
(
line
,
REGEX_KEYFORMAT
,
KEYFORMAT_IDENTITY
,
variableDefinitions
);
parseOptionalStringAttr
(
line
,
REGEX_KEYFORMAT
,
KEYFORMAT_IDENTITY
,
variableDefinitions
);
e
ncryptionKeyUri
=
null
;
fullSegmentE
ncryptionKeyUri
=
null
;
e
ncryptionIV
=
null
;
fullSegmentE
ncryptionIV
=
null
;
if
(
METHOD_NONE
.
equals
(
method
))
{
if
(
METHOD_NONE
.
equals
(
method
))
{
currentSchemeDatas
.
clear
();
currentSchemeDatas
.
clear
();
cachedDrmInitData
=
null
;
cachedDrmInitData
=
null
;
}
else
/* !METHOD_NONE.equals(method) */
{
}
else
/* !METHOD_NONE.equals(method) */
{
e
ncryptionIV
=
parseOptionalStringAttr
(
line
,
REGEX_IV
,
variableDefinitions
);
fullSegmentE
ncryptionIV
=
parseOptionalStringAttr
(
line
,
REGEX_IV
,
variableDefinitions
);
if
(
KEYFORMAT_IDENTITY
.
equals
(
keyFormat
))
{
if
(
KEYFORMAT_IDENTITY
.
equals
(
keyFormat
))
{
if
(
METHOD_AES_128
.
equals
(
method
))
{
if
(
METHOD_AES_128
.
equals
(
method
))
{
// The segment is fully encrypted using an identity key.
// The segment is fully encrypted using an identity key.
e
ncryptionKeyUri
=
parseStringAttr
(
line
,
REGEX_URI
,
variableDefinitions
);
fullSegmentE
ncryptionKeyUri
=
parseStringAttr
(
line
,
REGEX_URI
,
variableDefinitions
);
}
else
{
}
else
{
// Do nothing. Samples are encrypted using an identity key, but this is not supported.
// Do nothing. Samples are encrypted using an identity key, but this is not supported.
// Hopefully, a traditional DRM alternative is also provided.
// Hopefully, a traditional DRM alternative is also provided.
...
@@ -581,10 +593,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
...
@@ -581,10 +593,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
hasEndTag
=
true
;
hasEndTag
=
true
;
}
else
if
(!
line
.
startsWith
(
"#"
))
{
}
else
if
(!
line
.
startsWith
(
"#"
))
{
String
segmentEncryptionIV
;
String
segmentEncryptionIV
;
if
(
e
ncryptionKeyUri
==
null
)
{
if
(
fullSegmentE
ncryptionKeyUri
==
null
)
{
segmentEncryptionIV
=
null
;
segmentEncryptionIV
=
null
;
}
else
if
(
e
ncryptionIV
!=
null
)
{
}
else
if
(
fullSegmentE
ncryptionIV
!=
null
)
{
segmentEncryptionIV
=
e
ncryptionIV
;
segmentEncryptionIV
=
fullSegmentE
ncryptionIV
;
}
else
{
}
else
{
segmentEncryptionIV
=
Long
.
toHexString
(
segmentMediaSequence
);
segmentEncryptionIV
=
Long
.
toHexString
(
segmentMediaSequence
);
}
}
...
@@ -615,7 +627,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
...
@@ -615,7 +627,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
relativeDiscontinuitySequence
,
relativeDiscontinuitySequence
,
segmentStartTimeUs
,
segmentStartTimeUs
,
cachedDrmInitData
,
cachedDrmInitData
,
e
ncryptionKeyUri
,
fullSegmentE
ncryptionKeyUri
,
segmentEncryptionIV
,
segmentEncryptionIV
,
segmentByteRangeOffset
,
segmentByteRangeOffset
,
segmentByteRangeLength
,
segmentByteRangeLength
,
...
...
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylistParserTest.java
View file @
12ed18c7
...
@@ -16,9 +16,11 @@
...
@@ -16,9 +16,11 @@
package
com
.
google
.
android
.
exoplayer2
.
source
.
hls
.
playlist
;
package
com
.
google
.
android
.
exoplayer2
.
source
.
hls
.
playlist
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
org
.
junit
.
Assert
.
fail
;
import
android.net.Uri
;
import
android.net.Uri
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.ParserException
;
import
com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment
;
import
com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment
;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.android.exoplayer2.util.Util
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayInputStream
;
...
@@ -366,6 +368,61 @@ public class HlsMediaPlaylistParserTest {
...
@@ -366,6 +368,61 @@ public class HlsMediaPlaylistParserTest {
}
}
@Test
@Test
public
void
testEncryptedMapTag
()
throws
IOException
{
Uri
playlistUri
=
Uri
.
parse
(
"https://example.com/test3.m3u8"
);
String
playlistString
=
"#EXTM3U\n"
+
"#EXT-X-VERSION:3\n"
+
"#EXT-X-TARGETDURATION:5\n"
+
"#EXT-X-MEDIA-SEQUENCE:10\n"
+
"#EXT-X-KEY:METHOD=AES-128,"
+
"URI=\"https://priv.example.com/key.php?r=2680\",IV=0x1566B\n"
+
"#EXT-X-MAP:URI=\"init1.ts\""
+
"#EXTINF:5.005,\n"
+
"02/00/32.ts\n"
+
"#EXT-X-KEY:METHOD=NONE\n"
+
"#EXT-X-MAP:URI=\"init2.ts\""
+
"#EXTINF:5.005,\n"
+
"02/00/47.ts\n"
;
InputStream
inputStream
=
new
ByteArrayInputStream
(
Util
.
getUtf8Bytes
(
playlistString
));
HlsMediaPlaylist
playlist
=
(
HlsMediaPlaylist
)
new
HlsPlaylistParser
().
parse
(
playlistUri
,
inputStream
);
List
<
Segment
>
segments
=
playlist
.
segments
;
Segment
initSegment1
=
segments
.
get
(
0
).
initializationSegment
;
assertThat
(
initSegment1
.
fullSegmentEncryptionKeyUri
)
.
isEqualTo
(
"https://priv.example.com/key.php?r=2680"
);
assertThat
(
initSegment1
.
encryptionIV
).
isEqualTo
(
"0x1566B"
);
Segment
initSegment2
=
segments
.
get
(
1
).
initializationSegment
;
assertThat
(
initSegment2
.
fullSegmentEncryptionKeyUri
).
isNull
();
assertThat
(
initSegment2
.
encryptionIV
).
isNull
();
}
@Test
public
void
testEncryptedMapTagWithNoIvFails
()
throws
IOException
{
Uri
playlistUri
=
Uri
.
parse
(
"https://example.com/test3.m3u8"
);
String
playlistString
=
"#EXTM3U\n"
+
"#EXT-X-VERSION:3\n"
+
"#EXT-X-TARGETDURATION:5\n"
+
"#EXT-X-MEDIA-SEQUENCE:10\n"
+
"#EXT-X-KEY:METHOD=AES-128,"
+
"URI=\"https://priv.example.com/key.php?r=2680\"\n"
+
"#EXT-X-MAP:URI=\"init1.ts\""
+
"#EXTINF:5.005,\n"
+
"02/00/32.ts\n"
;
InputStream
inputStream
=
new
ByteArrayInputStream
(
Util
.
getUtf8Bytes
(
playlistString
));
try
{
new
HlsPlaylistParser
().
parse
(
playlistUri
,
inputStream
);
fail
();
}
catch
(
ParserException
e
)
{
// Expected because the initialization segment does not have a defined initialization vector,
// although it is affected by an EXT-X-KEY tag.
}
}
@Test
public
void
testMasterPlaylistAttributeInheritance
()
throws
IOException
{
public
void
testMasterPlaylistAttributeInheritance
()
throws
IOException
{
Uri
playlistUri
=
Uri
.
parse
(
"https://example.com/test3.m3u8"
);
Uri
playlistUri
=
Uri
.
parse
(
"https://example.com/test3.m3u8"
);
String
playlistString
=
String
playlistString
=
...
...
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