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
a76addba
authored
Nov 04, 2014
by
Andrey Udovenko
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add AES-128 encryption support for HLS #69 and parsing logic for CODECS and RESOLUTION attributes.
parent
a21c9ebc
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
267 additions
and
15 deletions
demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java
demo/src/main/java/com/google/android/exoplayer/demo/simple/HlsRendererBuilder.java
library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java
library/src/main/java/com/google/android/exoplayer/hls/HlsMasterPlaylist.java
library/src/main/java/com/google/android/exoplayer/hls/HlsMasterPlaylistParser.java
library/src/main/java/com/google/android/exoplayer/hls/HlsMediaPlaylist.java
library/src/main/java/com/google/android/exoplayer/hls/HlsMediaPlaylistParser.java
library/src/main/java/com/google/android/exoplayer/hls/HlsParserUtil.java
library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java
library/src/main/java/com/google/android/exoplayer/upstream/Aes128DataSource.java
demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java
View file @
a76addba
...
...
@@ -111,7 +111,7 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls
private
HlsMasterPlaylist
newSimpleMasterPlaylist
(
String
mediaPlaylistUrl
)
{
return
new
HlsMasterPlaylist
(
Uri
.
parse
(
""
),
Collections
.
singletonList
(
new
Variant
(
mediaPlaylistUrl
,
0
)));
Collections
.
singletonList
(
new
Variant
(
mediaPlaylistUrl
,
0
,
null
,
-
1
,
-
1
)));
}
}
demo/src/main/java/com/google/android/exoplayer/demo/simple/HlsRendererBuilder.java
View file @
a76addba
...
...
@@ -109,7 +109,7 @@ import java.util.Collections;
private
HlsMasterPlaylist
newSimpleMasterPlaylist
(
String
mediaPlaylistUrl
)
{
return
new
HlsMasterPlaylist
(
Uri
.
parse
(
""
),
Collections
.
singletonList
(
new
Variant
(
mediaPlaylistUrl
,
0
)));
Collections
.
singletonList
(
new
Variant
(
mediaPlaylistUrl
,
0
,
null
,
-
1
,
-
1
)));
}
}
library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java
View file @
a76addba
...
...
@@ -18,6 +18,7 @@ package com.google.android.exoplayer.hls;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.MediaFormat
;
import
com.google.android.exoplayer.TrackRenderer
;
import
com.google.android.exoplayer.upstream.Aes128DataSource
;
import
com.google.android.exoplayer.upstream.DataSource
;
import
com.google.android.exoplayer.upstream.DataSpec
;
import
com.google.android.exoplayer.upstream.NonBlockingInputStream
;
...
...
@@ -28,7 +29,9 @@ import android.os.SystemClock;
import
java.io.ByteArrayInputStream
;
import
java.io.IOException
;
import
java.math.BigInteger
;
import
java.util.List
;
import
java.util.Locale
;
/**
* A temporary test source of HLS chunks.
...
...
@@ -38,7 +41,7 @@ import java.util.List;
*/
public
class
HlsChunkSource
{
private
final
DataSource
d
ataSource
;
private
final
DataSource
upstreamD
ataSource
;
private
final
HlsMasterPlaylist
masterPlaylist
;
private
final
HlsMediaPlaylistParser
mediaPlaylistParser
;
...
...
@@ -47,9 +50,12 @@ public class HlsChunkSource {
/* package */
boolean
mediaPlaylistWasLive
;
/* package */
long
lastMediaPlaylistLoadTimeMs
;
private
DataSource
encryptedDataSource
;
private
String
encryptionKeyUri
;
// TODO: Once proper m3u8 parsing is in place, actually use the url!
public
HlsChunkSource
(
DataSource
dataSource
,
HlsMasterPlaylist
masterPlaylist
)
{
this
.
d
ataSource
=
dataSource
;
this
.
upstreamD
ataSource
=
dataSource
;
this
.
masterPlaylist
=
masterPlaylist
;
mediaPlaylistParser
=
new
HlsMediaPlaylistParser
();
}
...
...
@@ -144,8 +150,22 @@ public class HlsChunkSource {
}
HlsMediaPlaylist
.
Segment
segment
=
mediaPlaylist
.
segments
.
get
(
chunkIndex
);
Uri
chunkUri
=
Util
.
getMergedUri
(
mediaPlaylist
.
baseUri
,
segment
.
url
);
// Check if encryption is specified.
if
(
HlsMediaPlaylist
.
ENCRYPTION_METHOD_AES_128
.
equals
(
segment
.
encryptionMethod
))
{
if
(!
segment
.
encryptionKeyUri
.
equals
(
encryptionKeyUri
))
{
// Encryption is specified and the key has changed.
Uri
keyUri
=
Util
.
getMergedUri
(
mediaPlaylist
.
baseUri
,
segment
.
encryptionKeyUri
);
out
.
chunk
=
newEncryptionKeyChunk
(
keyUri
,
segment
.
encryptionIV
);
encryptionKeyUri
=
segment
.
encryptionKeyUri
;
return
;
}
}
else
{
encryptedDataSource
=
null
;
encryptionKeyUri
=
null
;
}
DataSpec
dataSpec
=
new
DataSpec
(
chunkUri
,
0
,
C
.
LENGTH_UNBOUNDED
,
null
);
long
startTimeUs
=
segment
.
startTimeUs
;
...
...
@@ -168,8 +188,15 @@ public class HlsChunkSource {
}
}
out
.
chunk
=
new
TsChunk
(
dataSource
,
dataSpec
,
0
,
startTimeUs
,
endTimeUs
,
nextChunkMediaSequence
,
segment
.
discontinuity
);
DataSource
dataSource
;
if
(
encryptedDataSource
!=
null
)
{
dataSource
=
encryptedDataSource
;
}
else
{
dataSource
=
upstreamDataSource
;
}
out
.
chunk
=
new
TsChunk
(
dataSource
,
dataSpec
,
0
,
startTimeUs
,
endTimeUs
,
nextChunkMediaSequence
,
segment
.
discontinuity
);
}
private
boolean
shouldRerequestMediaPlaylist
()
{
...
...
@@ -190,7 +217,12 @@ public class HlsChunkSource {
masterPlaylist
.
variants
.
get
(
0
).
url
);
DataSpec
dataSpec
=
new
DataSpec
(
mediaPlaylistUri
,
0
,
C
.
LENGTH_UNBOUNDED
,
null
);
Uri
mediaPlaylistBaseUri
=
Util
.
parseBaseUri
(
mediaPlaylistUri
.
toString
());
return
new
MediaPlaylistChunk
(
dataSource
,
dataSpec
,
0
,
mediaPlaylistBaseUri
);
return
new
MediaPlaylistChunk
(
upstreamDataSource
,
dataSpec
,
0
,
mediaPlaylistBaseUri
);
}
private
EncryptionKeyChunk
newEncryptionKeyChunk
(
Uri
keyUri
,
String
iv
)
{
DataSpec
dataSpec
=
new
DataSpec
(
keyUri
,
0
,
C
.
LENGTH_UNBOUNDED
,
null
);
return
new
EncryptionKeyChunk
(
upstreamDataSource
,
dataSpec
,
0
,
iv
);
}
private
class
MediaPlaylistChunk
extends
HlsChunk
{
...
...
@@ -214,4 +246,35 @@ public class HlsChunkSource {
}
private
class
EncryptionKeyChunk
extends
HlsChunk
{
private
final
String
iv
;
public
EncryptionKeyChunk
(
DataSource
dataSource
,
DataSpec
dataSpec
,
int
trigger
,
String
iv
)
{
super
(
dataSource
,
dataSpec
,
trigger
);
if
(
iv
.
toLowerCase
(
Locale
.
getDefault
()).
startsWith
(
"0x"
))
{
this
.
iv
=
iv
.
substring
(
2
);
}
else
{
this
.
iv
=
iv
;
}
}
@Override
protected
void
consumeStream
(
NonBlockingInputStream
stream
)
throws
IOException
{
byte
[]
keyData
=
new
byte
[(
int
)
stream
.
getAvailableByteCount
()];
stream
.
read
(
keyData
,
0
,
keyData
.
length
);
int
ivParsed
=
Integer
.
parseInt
(
iv
,
16
);
String
iv
=
String
.
format
(
"%032X"
,
ivParsed
);
byte
[]
ivData
=
new
BigInteger
(
iv
,
16
).
toByteArray
();
byte
[]
ivDataWithPadding
=
new
byte
[
iv
.
length
()
/
2
];
System
.
arraycopy
(
ivData
,
0
,
ivDataWithPadding
,
ivDataWithPadding
.
length
-
ivData
.
length
,
ivData
.
length
);
encryptedDataSource
=
new
Aes128DataSource
(
keyData
,
ivDataWithPadding
,
upstreamDataSource
);
}
}
}
library/src/main/java/com/google/android/exoplayer/hls/HlsMasterPlaylist.java
View file @
a76addba
...
...
@@ -30,10 +30,16 @@ public final class HlsMasterPlaylist {
public
static
final
class
Variant
{
public
final
int
bandwidth
;
public
final
String
url
;
public
final
String
[]
codecs
;
public
final
int
width
;
public
final
int
height
;
public
Variant
(
String
url
,
int
bandwidth
)
{
public
Variant
(
String
url
,
int
bandwidth
,
String
[]
codecs
,
int
width
,
int
height
)
{
this
.
bandwidth
=
bandwidth
;
this
.
url
=
url
;
this
.
codecs
=
codecs
;
this
.
width
=
width
;
this
.
height
=
height
;
}
}
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsMasterPlaylistParser.java
View file @
a76addba
...
...
@@ -36,9 +36,15 @@ public final class HlsMasterPlaylistParser implements ManifestParser<HlsMasterPl
private
static
final
String
STREAM_INF_TAG
=
"#EXT-X-STREAM-INF"
;
private
static
final
String
BANDWIDTH_ATTR
=
"BANDWIDTH"
;
private
static
final
String
CODECS_ATTR
=
"CODECS"
;
private
static
final
String
RESOLUTION_ATTR
=
"RESOLUTION"
;
private
static
final
Pattern
BANDWIDTH_ATTR_REGEX
=
Pattern
.
compile
(
BANDWIDTH_ATTR
+
"=(\\d+)\\b"
);
private
static
final
Pattern
CODECS_ATTR_REGEX
=
Pattern
.
compile
(
CODECS_ATTR
+
"=\"(.+)\""
);
private
static
final
Pattern
RESOLUTION_ATTR_REGEX
=
Pattern
.
compile
(
RESOLUTION_ATTR
+
"=(\\d+x\\d+)"
);
@Override
public
HlsMasterPlaylist
parse
(
InputStream
inputStream
,
String
inputEncoding
,
...
...
@@ -52,6 +58,10 @@ public final class HlsMasterPlaylistParser implements ManifestParser<HlsMasterPl
?
new
InputStreamReader
(
inputStream
)
:
new
InputStreamReader
(
inputStream
,
inputEncoding
));
List
<
Variant
>
variants
=
new
ArrayList
<
Variant
>();
int
bandwidth
=
0
;
String
[]
codecs
=
null
;
int
width
=
-
1
;
int
height
=
-
1
;
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
line
=
line
.
trim
();
...
...
@@ -60,9 +70,29 @@ public final class HlsMasterPlaylistParser implements ManifestParser<HlsMasterPl
}
if
(
line
.
startsWith
(
STREAM_INF_TAG
))
{
bandwidth
=
HlsParserUtil
.
parseIntAttr
(
line
,
BANDWIDTH_ATTR_REGEX
,
BANDWIDTH_ATTR
);
String
codecsString
=
HlsParserUtil
.
parseOptionalStringAttr
(
line
,
CODECS_ATTR_REGEX
,
CODECS_ATTR
);
if
(
codecsString
!=
null
)
{
codecs
=
codecsString
.
split
(
","
);
}
else
{
codecs
=
null
;
}
String
resolutionString
=
HlsParserUtil
.
parseOptionalStringAttr
(
line
,
RESOLUTION_ATTR_REGEX
,
RESOLUTION_ATTR
);
if
(
resolutionString
!=
null
)
{
String
[]
widthAndHeight
=
resolutionString
.
split
(
"x"
);
width
=
Integer
.
parseInt
(
widthAndHeight
[
0
]);
height
=
Integer
.
parseInt
(
widthAndHeight
[
1
]);
}
else
{
width
=
-
1
;
height
=
-
1
;
}
}
else
if
(!
line
.
startsWith
(
"#"
))
{
variants
.
add
(
new
Variant
(
line
,
bandwidth
));
variants
.
add
(
new
Variant
(
line
,
bandwidth
,
codecs
,
width
,
height
));
bandwidth
=
0
;
codecs
=
null
;
width
=
-
1
;
height
=
-
1
;
}
}
return
new
HlsMasterPlaylist
(
baseUri
,
Collections
.
unmodifiableList
(
variants
));
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsMediaPlaylist.java
View file @
a76addba
...
...
@@ -32,12 +32,19 @@ public final class HlsMediaPlaylist {
public
final
double
durationSecs
;
public
final
String
url
;
public
final
long
startTimeUs
;
public
final
String
encryptionMethod
;
public
final
String
encryptionKeyUri
;
public
final
String
encryptionIV
;
public
Segment
(
String
uri
,
double
durationSecs
,
boolean
discontinuity
,
long
startTimeUs
)
{
public
Segment
(
String
uri
,
double
durationSecs
,
boolean
discontinuity
,
long
startTimeUs
,
String
encryptionMethod
,
String
encryptionKeyUri
,
String
encryptionIV
)
{
this
.
url
=
uri
;
this
.
durationSecs
=
durationSecs
;
this
.
discontinuity
=
discontinuity
;
this
.
startTimeUs
=
startTimeUs
;
this
.
encryptionMethod
=
encryptionMethod
;
this
.
encryptionKeyUri
=
encryptionKeyUri
;
this
.
encryptionIV
=
encryptionIV
;
}
@Override
...
...
@@ -46,6 +53,9 @@ public final class HlsMediaPlaylist {
}
}
public
static
final
String
ENCRYPTION_METHOD_NONE
=
"NONE"
;
public
static
final
String
ENCRYPTION_METHOD_AES_128
=
"AES-128"
;
public
final
Uri
baseUri
;
public
final
int
mediaSequence
;
public
final
int
targetDurationSecs
;
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsMediaPlaylistParser.java
View file @
a76addba
...
...
@@ -40,6 +40,11 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
private
static
final
String
TARGET_DURATION_TAG
=
"#EXT-X-TARGETDURATION"
;
private
static
final
String
VERSION_TAG
=
"#EXT-X-VERSION"
;
private
static
final
String
ENDLIST_TAG
=
"#EXT-X-ENDLIST"
;
private
static
final
String
KEY_TAG
=
"#EXT-X-KEY"
;
private
static
final
String
METHOD_ATTR
=
"METHOD"
;
private
static
final
String
URI_ATTR
=
"URI"
;
private
static
final
String
IV_ATTR
=
"IV"
;
private
static
final
Pattern
MEDIA_DURATION_REGEX
=
Pattern
.
compile
(
MEDIA_DURATION_TAG
+
":([\\d.]+),"
);
...
...
@@ -50,6 +55,13 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
private
static
final
Pattern
VERSION_REGEX
=
Pattern
.
compile
(
VERSION_TAG
+
":(\\d+)\\b"
);
private
static
final
Pattern
METHOD_ATTR_REGEX
=
Pattern
.
compile
(
METHOD_ATTR
+
"=([^,.*]+)"
);
private
static
final
Pattern
URI_ATTR_REGEX
=
Pattern
.
compile
(
URI_ATTR
+
"=\"(.+)\""
);
private
static
final
Pattern
IV_ATTR_REGEX
=
Pattern
.
compile
(
IV_ATTR
+
"=([^,.*]+)"
);
@Override
public
HlsMediaPlaylist
parse
(
InputStream
inputStream
,
String
inputEncoding
,
String
contentId
,
Uri
baseUri
)
throws
IOException
{
...
...
@@ -70,6 +82,11 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
double
segmentDurationSecs
=
0.0
;
boolean
segmentDiscontinuity
=
false
;
long
segmentStartTimeUs
=
0
;
String
segmentEncryptionMethod
=
null
;
String
segmentEncryptionKeyUri
=
null
;
String
segmentEncryptionIV
=
null
;
int
segmentMediaSequence
=
0
;
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
...
...
@@ -82,16 +99,34 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
TARGET_DURATION_TAG
);
}
else
if
(
line
.
startsWith
(
MEDIA_SEQUENCE_TAG
))
{
mediaSequence
=
HlsParserUtil
.
parseIntAttr
(
line
,
MEDIA_SEQUENCE_REGEX
,
MEDIA_SEQUENCE_TAG
);
segmentMediaSequence
=
mediaSequence
;
}
else
if
(
line
.
startsWith
(
VERSION_TAG
))
{
version
=
HlsParserUtil
.
parseIntAttr
(
line
,
VERSION_REGEX
,
VERSION_TAG
);
}
else
if
(
line
.
startsWith
(
MEDIA_DURATION_TAG
))
{
segmentDurationSecs
=
HlsParserUtil
.
parseDoubleAttr
(
line
,
MEDIA_DURATION_REGEX
,
MEDIA_DURATION_TAG
);
}
else
if
(
line
.
startsWith
(
KEY_TAG
))
{
segmentEncryptionMethod
=
HlsParserUtil
.
parseStringAttr
(
line
,
METHOD_ATTR_REGEX
,
METHOD_ATTR
);
if
(
segmentEncryptionMethod
.
equals
(
HlsMediaPlaylist
.
ENCRYPTION_METHOD_NONE
))
{
segmentEncryptionKeyUri
=
null
;
segmentEncryptionIV
=
null
;
}
else
{
segmentEncryptionKeyUri
=
HlsParserUtil
.
parseStringAttr
(
line
,
URI_ATTR_REGEX
,
URI_ATTR
);
segmentEncryptionIV
=
HlsParserUtil
.
parseOptionalStringAttr
(
line
,
IV_ATTR_REGEX
,
IV_ATTR
);
if
(
segmentEncryptionIV
==
null
)
{
segmentEncryptionIV
=
Integer
.
toHexString
(
segmentMediaSequence
);
}
}
}
else
if
(
line
.
equals
(
DISCONTINUITY_TAG
))
{
segmentDiscontinuity
=
true
;
}
else
if
(!
line
.
startsWith
(
"#"
))
{
segmentMediaSequence
++;
segments
.
add
(
new
Segment
(
line
,
segmentDurationSecs
,
segmentDiscontinuity
,
segmentStartTimeUs
));
segmentStartTimeUs
,
segmentEncryptionMethod
,
segmentEncryptionKeyUri
,
segmentEncryptionIV
));
segmentStartTimeUs
+=
(
long
)
(
segmentDurationSecs
*
1000000
);
segmentDiscontinuity
=
false
;
segmentDurationSecs
=
0.0
;
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsParserUtil.java
View file @
a76addba
...
...
@@ -36,6 +36,14 @@ import java.util.regex.Pattern;
throw
new
ParserException
(
String
.
format
(
"Couldn't match %s tag in %s"
,
tag
,
line
));
}
public
static
String
parseOptionalStringAttr
(
String
line
,
Pattern
pattern
,
String
tag
)
{
Matcher
matcher
=
pattern
.
matcher
(
line
);
if
(
matcher
.
find
()
&&
matcher
.
groupCount
()
==
1
)
{
return
matcher
.
group
(
1
);
}
return
null
;
}
public
static
int
parseIntAttr
(
String
line
,
Pattern
pattern
,
String
tag
)
throws
ParserException
{
return
Integer
.
parseInt
(
parseStringAttr
(
line
,
pattern
,
tag
));
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java
View file @
a76addba
...
...
@@ -184,10 +184,14 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
haveSufficientSamples
=
true
;
}
else
{
extractor
.
reset
(
mediaChunk
.
startTimeUs
);
for
(
int
i
=
0
;
i
<
pendingDiscontinuities
.
length
;
i
++)
{
pendingDiscontinuities
[
i
]
=
true
;
}
mediaChunk
.
clearPendingDiscontinuity
();
if
(
pendingDiscontinuities
==
null
)
{
// We're not prepared yet.
}
else
{
for
(
int
i
=
0
;
i
<
pendingDiscontinuities
.
length
;
i
++)
{
pendingDiscontinuities
[
i
]
=
true
;
}
}
}
}
...
...
library/src/main/java/com/google/android/exoplayer/upstream/Aes128DataSource.java
0 → 100644
View file @
a76addba
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer
.
upstream
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.util.Assertions
;
import
java.io.IOException
;
import
java.security.InvalidAlgorithmParameterException
;
import
java.security.InvalidKeyException
;
import
java.security.Key
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.spec.AlgorithmParameterSpec
;
import
javax.crypto.Cipher
;
import
javax.crypto.CipherInputStream
;
import
javax.crypto.NoSuchPaddingException
;
import
javax.crypto.spec.IvParameterSpec
;
import
javax.crypto.spec.SecretKeySpec
;
/**
* A {@link DataSource} that decrypts the data read from an upstream source, encrypted with AES-128
* with a 128-bit key and PKCS7 padding.
*
*/
public
class
Aes128DataSource
implements
DataSource
{
private
final
DataSource
upstream
;
private
final
byte
[]
secretKey
;
private
final
byte
[]
iv
;
private
Cipher
cipher
;
private
CipherInputStream
cipherInputStream
;
public
Aes128DataSource
(
byte
[]
secretKey
,
byte
[]
iv
,
DataSource
upstream
)
{
this
.
upstream
=
upstream
;
this
.
secretKey
=
secretKey
;
this
.
iv
=
iv
;
}
@Override
public
long
open
(
DataSpec
dataSpec
)
throws
IOException
{
try
{
cipher
=
Cipher
.
getInstance
(
"AES/CBC/PKCS7Padding"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
throw
new
RuntimeException
(
e
);
}
catch
(
NoSuchPaddingException
e
)
{
throw
new
RuntimeException
(
e
);
}
Key
cipherKey
=
new
SecretKeySpec
(
secretKey
,
"AES"
);
AlgorithmParameterSpec
cipherIV
=
new
IvParameterSpec
(
iv
);
try
{
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
cipherKey
,
cipherIV
);
}
catch
(
InvalidKeyException
e
)
{
throw
new
RuntimeException
(
e
);
}
catch
(
InvalidAlgorithmParameterException
e
)
{
throw
new
RuntimeException
(
e
);
}
cipherInputStream
=
new
CipherInputStream
(
new
DataSourceInputStream
(
upstream
,
dataSpec
),
cipher
);
return
C
.
LENGTH_UNBOUNDED
;
}
@Override
public
void
close
()
throws
IOException
{
upstream
.
close
();
}
@Override
public
int
read
(
byte
[]
buffer
,
int
offset
,
int
readLength
)
throws
IOException
{
Assertions
.
checkState
(
cipherInputStream
!=
null
);
int
bytesRead
=
cipherInputStream
.
read
(
buffer
,
offset
,
readLength
);
if
(
bytesRead
<
0
)
{
return
-
1
;
}
return
bytesRead
;
}
}
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