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
69c75fb5
authored
Sep 08, 2021
by
bachinger
Committed by
Christos Tsilopoulos
Sep 16, 2021
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Use identical cache keys for downloading and playing DASH segments
Issue: #9370 PiperOrigin-RevId: 395429794
parent
ee2ef1c3
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
89 additions
and
30 deletions
RELEASENOTES.md
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java
library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java
RELEASENOTES.md
View file @
69c75fb5
...
...
@@ -23,6 +23,9 @@
thrown from
`Requirements.isInternetConnectivityValidated`
on devices
running Android 11
(
[
#9002
](
https://github.com/google/ExoPlayer/issues/9002
)
).
*
DASH:
*
Use identical cache keys for downloading and playing DASH segments
(
[
#9370
](
https://github.com/google/ExoPlayer/issues/9370
)
).
*
RTSP:
*
Handle when additional spaces are in SDP's RTPMAP atrribute
(
[
#9379
](
https://github.com/google/ExoPlayer/issues/9379
)
).
...
...
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java
View file @
69c75fb5
...
...
@@ -46,20 +46,20 @@ public final class DashUtil {
/**
* Builds a {@link DataSpec} for a given {@link RangedUri} belonging to {@link Representation}.
*
* @param representation The {@link Representation} to which the request belongs.
* @param baseUrl The base url with which to resolve the request URI.
* @param requestUri The {@link RangedUri} of the data to request.
* @param cacheKey An optional cache key.
* @param flags Flags to be set on the returned {@link DataSpec}. See {@link
* DataSpec.Builder#setFlags(int)}.
* @return The {@link DataSpec}.
*/
public
static
DataSpec
buildDataSpec
(
String
baseUrl
,
RangedUri
requestUri
,
@Nullable
String
cacheKey
,
int
flags
)
{
Representation
representation
,
String
baseUrl
,
RangedUri
requestUri
,
int
flags
)
{
return
new
DataSpec
.
Builder
()
.
setUri
(
requestUri
.
resolveUri
(
baseUrl
))
.
setPosition
(
requestUri
.
start
)
.
setLength
(
requestUri
.
length
)
.
setKey
(
cacheKey
)
.
setKey
(
resolveCacheKey
(
representation
,
requestUri
)
)
.
setFlags
(
flags
)
.
build
();
}
...
...
@@ -77,8 +77,7 @@ public final class DashUtil {
*/
public
static
DataSpec
buildDataSpec
(
Representation
representation
,
RangedUri
requestUri
,
int
flags
)
{
return
buildDataSpec
(
representation
.
baseUrls
.
get
(
0
).
url
,
requestUri
,
representation
.
getCacheKey
(),
flags
);
return
buildDataSpec
(
representation
,
representation
.
baseUrls
.
get
(
0
).
url
,
requestUri
,
flags
);
}
/**
...
...
@@ -289,9 +288,9 @@ public final class DashUtil {
throws
IOException
{
DataSpec
dataSpec
=
DashUtil
.
buildDataSpec
(
representation
,
representation
.
baseUrls
.
get
(
baseUrlIndex
).
url
,
requestUri
,
representation
.
getCacheKey
(),
/* flags= */
0
);
InitializationChunk
initializationChunk
=
new
InitializationChunk
(
...
...
@@ -304,6 +303,21 @@ public final class DashUtil {
initializationChunk
.
load
();
}
/**
* Resolves the cache key to be used when requesting the given ranged URI for the given {@link
* Representation}.
*
* @param representation The {@link Representation} to which the URI belongs to.
* @param rangedUri The URI for which to resolve the cache key.
* @return The cache key.
*/
public
static
String
resolveCacheKey
(
Representation
representation
,
RangedUri
rangedUri
)
{
@Nullable
String
cacheKey
=
representation
.
getCacheKey
();
return
cacheKey
!=
null
?
cacheKey
:
rangedUri
.
resolveUri
(
representation
.
baseUrls
.
get
(
0
).
url
).
toString
();
}
private
static
ChunkExtractor
newChunkExtractor
(
int
trackType
,
Format
format
)
{
String
mimeType
=
format
.
containerMimeType
;
boolean
isWebm
=
...
...
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java
View file @
69c75fb5
...
...
@@ -628,10 +628,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
}
DataSpec
dataSpec
=
DashUtil
.
buildDataSpec
(
representationHolder
.
selectedBaseUrl
.
url
,
requestUri
,
representation
.
getCacheKey
(),
/* flags= */
0
);
representation
,
representationHolder
.
selectedBaseUrl
.
url
,
requestUri
,
/* flags= */
0
);
return
new
InitializationChunk
(
dataSource
,
dataSpec
,
...
...
@@ -664,10 +661,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
:
DataSpec
.
FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED
;
DataSpec
dataSpec
=
DashUtil
.
buildDataSpec
(
representationHolder
.
selectedBaseUrl
.
url
,
segmentUri
,
representation
.
getCacheKey
(),
flags
);
representation
,
representationHolder
.
selectedBaseUrl
.
url
,
segmentUri
,
flags
);
return
new
SingleSampleMediaChunk
(
dataSource
,
dataSpec
,
...
...
@@ -706,10 +700,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
:
DataSpec
.
FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED
;
DataSpec
dataSpec
=
DashUtil
.
buildDataSpec
(
representationHolder
.
selectedBaseUrl
.
url
,
segmentUri
,
representation
.
getCacheKey
(),
flags
);
representation
,
representationHolder
.
selectedBaseUrl
.
url
,
segmentUri
,
flags
);
long
sampleOffsetUs
=
-
representation
.
presentationTimeOffsetUs
;
return
new
ContainerMediaChunk
(
dataSource
,
...
...
@@ -765,9 +756,9 @@ public class DefaultDashChunkSource implements DashChunkSource {
?
0
:
DataSpec
.
FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED
;
return
DashUtil
.
buildDataSpec
(
representationHolder
.
representation
,
representationHolder
.
selectedBaseUrl
.
url
,
segmentUri
,
representationHolder
.
representation
.
getCacheKey
(),
flags
);
}
...
...
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java
View file @
69c75fb5
...
...
@@ -15,12 +15,15 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
source
.
dash
.
offline
;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Util
.
castNonNull
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.extractor.ChunkIndex
;
import
com.google.android.exoplayer2.offline.DownloadException
;
import
com.google.android.exoplayer2.offline.SegmentDownloader
;
import
com.google.android.exoplayer2.source.dash.BaseUrlExclusionList
;
import
com.google.android.exoplayer2.source.dash.DashSegmentIndex
;
import
com.google.android.exoplayer2.source.dash.DashUtil
;
import
com.google.android.exoplayer2.source.dash.DashWrappingSegmentIndex
;
...
...
@@ -70,6 +73,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
*/
public
final
class
DashDownloader
extends
SegmentDownloader
<
DashManifest
>
{
private
final
BaseUrlExclusionList
baseUrlExclusionList
;
/**
* Creates a new instance.
*
...
...
@@ -113,6 +118,7 @@ public final class DashDownloader extends SegmentDownloader<DashManifest> {
CacheDataSource
.
Factory
cacheDataSourceFactory
,
Executor
executor
)
{
super
(
mediaItem
,
manifestParser
,
cacheDataSourceFactory
,
executor
);
baseUrlExclusionList
=
new
BaseUrlExclusionList
();
}
@Override
...
...
@@ -163,28 +169,32 @@ public final class DashDownloader extends SegmentDownloader<DashManifest> {
throw
new
DownloadException
(
"Unbounded segment index"
);
}
String
baseUrl
=
representation
.
baseUrls
.
get
(
0
).
url
;
RangedUri
initializationUri
=
representation
.
getInitializationUri
();
String
baseUrl
=
castNonNull
(
baseUrlExclusionList
.
selectBaseUrl
(
representation
.
baseUrls
)
).
url
;
@Nullable
RangedUri
initializationUri
=
representation
.
getInitializationUri
();
if
(
initializationUri
!=
null
)
{
addSegment
(
periodStartUs
,
baseUrl
,
initializationUri
,
out
);
out
.
add
(
createSegment
(
representation
,
baseUrl
,
periodStartUs
,
initializationUri
)
);
}
RangedUri
indexUri
=
representation
.
getIndexUri
();
@Nullable
RangedUri
indexUri
=
representation
.
getIndexUri
();
if
(
indexUri
!=
null
)
{
addSegment
(
periodStartUs
,
baseUrl
,
indexUri
,
out
);
out
.
add
(
createSegment
(
representation
,
baseUrl
,
periodStartUs
,
indexUri
)
);
}
long
firstSegmentNum
=
index
.
getFirstSegmentNum
();
long
lastSegmentNum
=
firstSegmentNum
+
segmentCount
-
1
;
for
(
long
j
=
firstSegmentNum
;
j
<=
lastSegmentNum
;
j
++)
{
addSegment
(
periodStartUs
+
index
.
getTimeUs
(
j
),
baseUrl
,
index
.
getSegmentUrl
(
j
),
out
);
out
.
add
(
createSegment
(
representation
,
baseUrl
,
periodStartUs
+
index
.
getTimeUs
(
j
),
index
.
getSegmentUrl
(
j
)));
}
}
}
private
static
void
addSegment
(
long
startTimeUs
,
String
baseUrl
,
RangedUri
rangedUri
,
ArrayList
<
Segment
>
out
)
{
DataSpec
dataSpec
=
new
DataSpec
(
rangedUri
.
resolveUri
(
baseUrl
),
rangedUri
.
start
,
rangedUri
.
length
);
out
.
add
(
new
Segment
(
startTimeUs
,
dataSpec
));
private
Segment
createSegment
(
Representation
representation
,
String
baseUrl
,
long
startTimeUs
,
RangedUri
rangedUri
)
{
DataSpec
dataSpec
=
DashUtil
.
buildDataSpec
(
representation
,
baseUrl
,
rangedUri
,
/* flags= */
0
);
return
new
Segment
(
startTimeUs
,
dataSpec
);
}
@Nullable
...
...
library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java
View file @
69c75fb5
...
...
@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import
com.google.android.exoplayer2.source.dash.manifest.AdaptationSet
;
import
com.google.android.exoplayer2.source.dash.manifest.BaseUrl
;
import
com.google.android.exoplayer2.source.dash.manifest.Period
;
import
com.google.android.exoplayer2.source.dash.manifest.RangedUri
;
import
com.google.android.exoplayer2.source.dash.manifest.Representation
;
import
com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase
;
import
com.google.android.exoplayer2.upstream.DummyDataSource
;
...
...
@@ -69,6 +70,46 @@ public final class DashUtilTest {
assertThat
(
format
).
isNull
();
}
@Test
public
void
resolveCacheKey_representationCacheKeyIsNull_resolvesRangedUriWithFirstBaseUrl
()
{
ImmutableList
<
BaseUrl
>
baseUrls
=
ImmutableList
.
of
(
new
BaseUrl
(
"http://www.google.com"
),
new
BaseUrl
(
"http://www.foo.com"
));
Representation
.
SingleSegmentRepresentation
representation
=
new
Representation
.
SingleSegmentRepresentation
(
/* revisionId= */
1L
,
new
Format
.
Builder
().
build
(),
baseUrls
,
new
SingleSegmentBase
(),
/* inbandEventStreams= */
null
,
/* cacheKey= */
null
,
/* contentLength= */
1
);
RangedUri
rangedUri
=
new
RangedUri
(
"path/to/resource"
,
/* start= */
0
,
/* length= */
1
);
String
cacheKey
=
DashUtil
.
resolveCacheKey
(
representation
,
rangedUri
);
assertThat
(
cacheKey
).
isEqualTo
(
"http://www.google.com/path/to/resource"
);
}
@Test
public
void
resolveCacheKey_representationCacheKeyDefined_usesRepresentationCacheKey
()
{
ImmutableList
<
BaseUrl
>
baseUrls
=
ImmutableList
.
of
(
new
BaseUrl
(
"http://www.google.com"
),
new
BaseUrl
(
"http://www.foo.com"
));
Representation
.
SingleSegmentRepresentation
representation
=
new
Representation
.
SingleSegmentRepresentation
(
/* revisionId= */
1L
,
new
Format
.
Builder
().
build
(),
baseUrls
,
new
SingleSegmentBase
(),
/* inbandEventStreams= */
null
,
"cacheKey"
,
/* contentLength= */
1
);
RangedUri
rangedUri
=
new
RangedUri
(
"path/to/resource"
,
/* start= */
0
,
/* length= */
1
);
String
cacheKey
=
DashUtil
.
resolveCacheKey
(
representation
,
rangedUri
);
assertThat
(
cacheKey
).
isEqualTo
(
"cacheKey"
);
}
private
static
Period
newPeriod
(
AdaptationSet
...
adaptationSets
)
{
return
new
Period
(
""
,
0
,
Arrays
.
asList
(
adaptationSets
));
}
...
...
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