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
0c81022a
authored
May 28, 2020
by
bachinger
Committed by
Oliver Woodman
May 29, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Make HlsMediaSource add the media item to the timeline
PiperOrigin-RevId: 313605791
parent
37024ae4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
173 additions
and
22 deletions
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaSourceTest.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java
View file @
0c81022a
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
*/
*/
package
com
.
google
.
android
.
exoplayer2
.
source
.
hls
;
package
com
.
google
.
android
.
exoplayer2
.
source
.
hls
;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Assertions
.
checkNotNull
;
import
static
java
.
lang
.
annotation
.
RetentionPolicy
.
SOURCE
;
import
static
java
.
lang
.
annotation
.
RetentionPolicy
.
SOURCE
;
import
android.net.Uri
;
import
android.net.Uri
;
...
@@ -49,7 +50,7 @@ import com.google.android.exoplayer2.upstream.DataSource;
...
@@ -49,7 +50,7 @@ import com.google.android.exoplayer2.upstream.DataSource;
import
com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy
;
import
com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy
;
import
com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy
;
import
com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy
;
import
com.google.android.exoplayer2.upstream.TransferListener
;
import
com.google.android.exoplayer2.upstream.TransferListener
;
import
com.google.android.exoplayer2.util.
Assertion
s
;
import
com.google.android.exoplayer2.util.
MimeType
s
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.Retention
;
...
@@ -121,7 +122,7 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -121,7 +122,7 @@ public final class HlsMediaSource extends BaseMediaSource
* manifests, segments and keys.
* manifests, segments and keys.
*/
*/
public
Factory
(
HlsDataSourceFactory
hlsDataSourceFactory
)
{
public
Factory
(
HlsDataSourceFactory
hlsDataSourceFactory
)
{
this
.
hlsDataSourceFactory
=
Assertions
.
checkNotNull
(
hlsDataSourceFactory
);
this
.
hlsDataSourceFactory
=
checkNotNull
(
hlsDataSourceFactory
);
playlistParserFactory
=
new
DefaultHlsPlaylistParserFactory
();
playlistParserFactory
=
new
DefaultHlsPlaylistParserFactory
();
playlistTrackerFactory
=
DefaultHlsPlaylistTracker
.
FACTORY
;
playlistTrackerFactory
=
DefaultHlsPlaylistTracker
.
FACTORY
;
extractorFactory
=
HlsExtractorFactory
.
DEFAULT
;
extractorFactory
=
HlsExtractorFactory
.
DEFAULT
;
...
@@ -332,7 +333,8 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -332,7 +333,8 @@ public final class HlsMediaSource extends BaseMediaSource
@Deprecated
@Deprecated
@Override
@Override
public
HlsMediaSource
createMediaSource
(
Uri
uri
)
{
public
HlsMediaSource
createMediaSource
(
Uri
uri
)
{
return
createMediaSource
(
new
MediaItem
.
Builder
().
setUri
(
uri
).
build
());
return
createMediaSource
(
new
MediaItem
.
Builder
().
setUri
(
uri
).
setMimeType
(
MimeTypes
.
APPLICATION_M3U8
).
build
());
}
}
/**
/**
...
@@ -344,18 +346,29 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -344,18 +346,29 @@ public final class HlsMediaSource extends BaseMediaSource
*/
*/
@Override
@Override
public
HlsMediaSource
createMediaSource
(
MediaItem
mediaItem
)
{
public
HlsMediaSource
createMediaSource
(
MediaItem
mediaItem
)
{
Assertions
.
checkNotNull
(
mediaItem
.
playbackProperties
);
checkNotNull
(
mediaItem
.
playbackProperties
);
HlsPlaylistParserFactory
playlistParserFactory
=
this
.
playlistParserFactory
;
HlsPlaylistParserFactory
playlistParserFactory
=
this
.
playlistParserFactory
;
List
<
StreamKey
>
streamKeys
=
List
<
StreamKey
>
streamKeys
=
!
mediaItem
.
playbackProperties
.
streamKeys
.
isEmpty
()
mediaItem
.
playbackProperties
.
streamKeys
.
isEmpty
()
?
mediaItem
.
playbackPropertie
s
.
streamKeys
?
thi
s
.
streamKeys
:
thi
s
.
streamKeys
;
:
mediaItem
.
playbackPropertie
s
.
streamKeys
;
if
(!
streamKeys
.
isEmpty
())
{
if
(!
streamKeys
.
isEmpty
())
{
playlistParserFactory
=
playlistParserFactory
=
new
FilteringHlsPlaylistParserFactory
(
playlistParserFactory
,
streamKeys
);
new
FilteringHlsPlaylistParserFactory
(
playlistParserFactory
,
streamKeys
);
}
}
boolean
needsTag
=
mediaItem
.
playbackProperties
.
tag
==
null
&&
tag
!=
null
;
boolean
needsStreamKeys
=
mediaItem
.
playbackProperties
.
streamKeys
.
isEmpty
()
&&
!
streamKeys
.
isEmpty
();
if
(
needsTag
&&
needsStreamKeys
)
{
mediaItem
=
mediaItem
.
buildUpon
().
setTag
(
tag
).
setStreamKeys
(
streamKeys
).
build
();
}
else
if
(
needsTag
)
{
mediaItem
=
mediaItem
.
buildUpon
().
setTag
(
tag
).
build
();
}
else
if
(
needsStreamKeys
)
{
mediaItem
=
mediaItem
.
buildUpon
().
setStreamKeys
(
streamKeys
).
build
();
}
return
new
HlsMediaSource
(
return
new
HlsMediaSource
(
mediaItem
.
playbackProperties
.
uri
,
mediaItem
,
hlsDataSourceFactory
,
hlsDataSourceFactory
,
extractorFactory
,
extractorFactory
,
compositeSequenceableLoaderFactory
,
compositeSequenceableLoaderFactory
,
...
@@ -365,8 +378,7 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -365,8 +378,7 @@ public final class HlsMediaSource extends BaseMediaSource
hlsDataSourceFactory
,
loadErrorHandlingPolicy
,
playlistParserFactory
),
hlsDataSourceFactory
,
loadErrorHandlingPolicy
,
playlistParserFactory
),
allowChunklessPreparation
,
allowChunklessPreparation
,
metadataType
,
metadataType
,
useSessionKeys
,
useSessionKeys
);
mediaItem
.
playbackProperties
.
tag
!=
null
?
mediaItem
.
playbackProperties
.
tag
:
tag
);
}
}
@Override
@Override
...
@@ -376,7 +388,8 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -376,7 +388,8 @@ public final class HlsMediaSource extends BaseMediaSource
}
}
private
final
HlsExtractorFactory
extractorFactory
;
private
final
HlsExtractorFactory
extractorFactory
;
private
final
Uri
manifestUri
;
private
final
MediaItem
mediaItem
;
private
final
MediaItem
.
PlaybackProperties
playbackProperties
;
private
final
HlsDataSourceFactory
dataSourceFactory
;
private
final
HlsDataSourceFactory
dataSourceFactory
;
private
final
CompositeSequenceableLoaderFactory
compositeSequenceableLoaderFactory
;
private
final
CompositeSequenceableLoaderFactory
compositeSequenceableLoaderFactory
;
private
final
DrmSessionManager
drmSessionManager
;
private
final
DrmSessionManager
drmSessionManager
;
...
@@ -385,12 +398,11 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -385,12 +398,11 @@ public final class HlsMediaSource extends BaseMediaSource
private
final
@MetadataType
int
metadataType
;
private
final
@MetadataType
int
metadataType
;
private
final
boolean
useSessionKeys
;
private
final
boolean
useSessionKeys
;
private
final
HlsPlaylistTracker
playlistTracker
;
private
final
HlsPlaylistTracker
playlistTracker
;
@Nullable
private
final
Object
tag
;
@Nullable
private
TransferListener
mediaTransferListener
;
@Nullable
private
TransferListener
mediaTransferListener
;
private
HlsMediaSource
(
private
HlsMediaSource
(
Uri
manifestUri
,
MediaItem
mediaItem
,
HlsDataSourceFactory
dataSourceFactory
,
HlsDataSourceFactory
dataSourceFactory
,
HlsExtractorFactory
extractorFactory
,
HlsExtractorFactory
extractorFactory
,
CompositeSequenceableLoaderFactory
compositeSequenceableLoaderFactory
,
CompositeSequenceableLoaderFactory
compositeSequenceableLoaderFactory
,
...
@@ -399,9 +411,9 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -399,9 +411,9 @@ public final class HlsMediaSource extends BaseMediaSource
HlsPlaylistTracker
playlistTracker
,
HlsPlaylistTracker
playlistTracker
,
boolean
allowChunklessPreparation
,
boolean
allowChunklessPreparation
,
@MetadataType
int
metadataType
,
@MetadataType
int
metadataType
,
boolean
useSessionKeys
,
boolean
useSessionKeys
)
{
@Nullable
Object
tag
)
{
this
.
playbackProperties
=
checkNotNull
(
mediaItem
.
playbackProperties
);
this
.
m
anifestUri
=
manifestUri
;
this
.
m
ediaItem
=
mediaItem
;
this
.
dataSourceFactory
=
dataSourceFactory
;
this
.
dataSourceFactory
=
dataSourceFactory
;
this
.
extractorFactory
=
extractorFactory
;
this
.
extractorFactory
=
extractorFactory
;
this
.
compositeSequenceableLoaderFactory
=
compositeSequenceableLoaderFactory
;
this
.
compositeSequenceableLoaderFactory
=
compositeSequenceableLoaderFactory
;
...
@@ -411,13 +423,17 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -411,13 +423,17 @@ public final class HlsMediaSource extends BaseMediaSource
this
.
allowChunklessPreparation
=
allowChunklessPreparation
;
this
.
allowChunklessPreparation
=
allowChunklessPreparation
;
this
.
metadataType
=
metadataType
;
this
.
metadataType
=
metadataType
;
this
.
useSessionKeys
=
useSessionKeys
;
this
.
useSessionKeys
=
useSessionKeys
;
this
.
tag
=
tag
;
}
}
@Override
@Override
@Nullable
@Nullable
public
Object
getTag
()
{
public
Object
getTag
()
{
return
tag
;
return
playbackProperties
.
tag
;
}
// TODO(bachinger): add @Override annotation once the method is defined by MediaSource.
public
MediaItem
getMediaItem
()
{
return
mediaItem
;
}
}
@Override
@Override
...
@@ -425,7 +441,7 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -425,7 +441,7 @@ public final class HlsMediaSource extends BaseMediaSource
this
.
mediaTransferListener
=
mediaTransferListener
;
this
.
mediaTransferListener
=
mediaTransferListener
;
drmSessionManager
.
prepare
();
drmSessionManager
.
prepare
();
EventDispatcher
eventDispatcher
=
createEventDispatcher
(
/* mediaPeriodId= */
null
);
EventDispatcher
eventDispatcher
=
createEventDispatcher
(
/* mediaPeriodId= */
null
);
playlistTracker
.
start
(
manifestU
ri
,
eventDispatcher
,
/* listener= */
this
);
playlistTracker
.
start
(
playbackProperties
.
u
ri
,
eventDispatcher
,
/* listener= */
this
);
}
}
@Override
@Override
...
@@ -477,7 +493,7 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -477,7 +493,7 @@ public final class HlsMediaSource extends BaseMediaSource
long
windowDefaultStartPositionUs
=
playlist
.
startOffsetUs
;
long
windowDefaultStartPositionUs
=
playlist
.
startOffsetUs
;
// masterPlaylist is non-null because the first playlist has been fetched by now.
// masterPlaylist is non-null because the first playlist has been fetched by now.
HlsManifest
manifest
=
HlsManifest
manifest
=
new
HlsManifest
(
Assertions
.
checkNotNull
(
playlistTracker
.
getMasterPlaylist
()),
playlist
);
new
HlsManifest
(
checkNotNull
(
playlistTracker
.
getMasterPlaylist
()),
playlist
);
if
(
playlistTracker
.
isLive
())
{
if
(
playlistTracker
.
isLive
())
{
long
offsetFromInitialStartTimeUs
=
long
offsetFromInitialStartTimeUs
=
playlist
.
startTimeUs
-
playlistTracker
.
getInitialStartTimeUs
();
playlist
.
startTimeUs
-
playlistTracker
.
getInitialStartTimeUs
();
...
@@ -511,7 +527,7 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -511,7 +527,7 @@ public final class HlsMediaSource extends BaseMediaSource
/* isDynamic= */
!
playlist
.
hasEndTag
,
/* isDynamic= */
!
playlist
.
hasEndTag
,
/* isLive= */
true
,
/* isLive= */
true
,
manifest
,
manifest
,
tag
);
mediaItem
);
}
else
/* not live */
{
}
else
/* not live */
{
if
(
windowDefaultStartPositionUs
==
C
.
TIME_UNSET
)
{
if
(
windowDefaultStartPositionUs
==
C
.
TIME_UNSET
)
{
windowDefaultStartPositionUs
=
0
;
windowDefaultStartPositionUs
=
0
;
...
@@ -529,7 +545,7 @@ public final class HlsMediaSource extends BaseMediaSource
...
@@ -529,7 +545,7 @@ public final class HlsMediaSource extends BaseMediaSource
/* isDynamic= */
false
,
/* isDynamic= */
false
,
/* isLive= */
false
,
/* isLive= */
false
,
manifest
,
manifest
,
tag
);
mediaItem
);
}
}
refreshSourceInfo
(
timeline
);
refreshSourceInfo
(
timeline
);
}
}
...
...
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaSourceTest.java
0 → 100644
View file @
0c81022a
/*
* Copyright 2020 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
.
exoplayer2
.
source
.
hls
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
androidx.annotation.Nullable
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.offline.StreamKey
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
java.util.Collections
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
/** Unit test for {@link DashMediaSource}. */
@RunWith
(
AndroidJUnit4
.
class
)
public
class
HlsMediaSourceTest
{
// Tests backwards compatibility
@SuppressWarnings
(
"deprecation"
)
@Test
public
void
factorySetTag_nullMediaItemTag_setsMediaItemTag
()
{
Object
tag
=
new
Object
();
MediaItem
mediaItem
=
MediaItem
.
fromUri
(
"http://www.google.com"
);
HlsMediaSource
.
Factory
factory
=
new
HlsMediaSource
.
Factory
(
mock
(
DataSource
.
Factory
.
class
)).
setTag
(
tag
);
MediaItem
dashMediaItem
=
factory
.
createMediaSource
(
mediaItem
).
getMediaItem
();
assertThat
(
dashMediaItem
.
playbackProperties
).
isNotNull
();
assertThat
(
dashMediaItem
.
playbackProperties
.
uri
).
isEqualTo
(
mediaItem
.
playbackProperties
.
uri
);
assertThat
(
dashMediaItem
.
playbackProperties
.
tag
).
isEqualTo
(
tag
);
}
// Tests backwards compatibility
@SuppressWarnings
(
"deprecation"
)
@Test
public
void
factorySetTag_nonNullMediaItemTag_doesNotOverrideMediaItemTag
()
{
Object
factoryTag
=
new
Object
();
Object
mediaItemTag
=
new
Object
();
MediaItem
mediaItem
=
new
MediaItem
.
Builder
().
setUri
(
"http://www.google.com"
).
setTag
(
mediaItemTag
).
build
();
HlsMediaSource
.
Factory
factory
=
new
HlsMediaSource
.
Factory
(
mock
(
DataSource
.
Factory
.
class
)).
setTag
(
factoryTag
);
MediaItem
dashMediaItem
=
factory
.
createMediaSource
(
mediaItem
).
getMediaItem
();
assertThat
(
dashMediaItem
.
playbackProperties
).
isNotNull
();
assertThat
(
dashMediaItem
.
playbackProperties
.
uri
).
isEqualTo
(
mediaItem
.
playbackProperties
.
uri
);
assertThat
(
dashMediaItem
.
playbackProperties
.
tag
).
isEqualTo
(
mediaItemTag
);
}
// Tests backwards compatibility
@SuppressWarnings
(
"deprecation"
)
@Test
public
void
factorySetTag_setsDeprecatedMediaSourceTag
()
{
Object
tag
=
new
Object
();
MediaItem
mediaItem
=
MediaItem
.
fromUri
(
"http://www.google.com"
);
HlsMediaSource
.
Factory
factory
=
new
HlsMediaSource
.
Factory
(
mock
(
DataSource
.
Factory
.
class
)).
setTag
(
tag
);
@Nullable
Object
mediaSourceTag
=
factory
.
createMediaSource
(
mediaItem
).
getTag
();
assertThat
(
mediaSourceTag
).
isEqualTo
(
tag
);
}
// Tests backwards compatibility
@SuppressWarnings
(
"deprecation"
)
@Test
public
void
factoryCreateMediaSource_setsDeprecatedMediaSourceTag
()
{
Object
tag
=
new
Object
();
MediaItem
mediaItem
=
new
MediaItem
.
Builder
().
setUri
(
"http://www.google.com"
).
setTag
(
tag
).
build
();
HlsMediaSource
.
Factory
factory
=
new
HlsMediaSource
.
Factory
(
mock
(
DataSource
.
Factory
.
class
)).
setTag
(
new
Object
());
@Nullable
Object
mediaSourceTag
=
factory
.
createMediaSource
(
mediaItem
).
getTag
();
assertThat
(
mediaSourceTag
).
isEqualTo
(
tag
);
}
// Tests backwards compatibility
@SuppressWarnings
(
"deprecation"
)
@Test
public
void
factorySetStreamKeys_emptyMediaItemStreamKeys_setsMediaItemStreamKeys
()
{
MediaItem
mediaItem
=
MediaItem
.
fromUri
(
"http://www.google.com"
);
StreamKey
streamKey
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
1
);
HlsMediaSource
.
Factory
factory
=
new
HlsMediaSource
.
Factory
(
mock
(
DataSource
.
Factory
.
class
))
.
setStreamKeys
(
Collections
.
singletonList
(
streamKey
));
MediaItem
dashMediaItem
=
factory
.
createMediaSource
(
mediaItem
).
getMediaItem
();
assertThat
(
dashMediaItem
.
playbackProperties
).
isNotNull
();
assertThat
(
dashMediaItem
.
playbackProperties
.
uri
).
isEqualTo
(
mediaItem
.
playbackProperties
.
uri
);
assertThat
(
dashMediaItem
.
playbackProperties
.
streamKeys
).
containsExactly
(
streamKey
);
}
// Tests backwards compatibility
@SuppressWarnings
(
"deprecation"
)
@Test
public
void
factorySetStreamKeys_withMediaItemStreamKeys_doesNotOverrideMediaItemStreamKeys
()
{
StreamKey
mediaItemStreamKey
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
1
);
MediaItem
mediaItem
=
new
MediaItem
.
Builder
()
.
setUri
(
"http://www.google.com"
)
.
setStreamKeys
(
Collections
.
singletonList
(
mediaItemStreamKey
))
.
build
();
HlsMediaSource
.
Factory
factory
=
new
HlsMediaSource
.
Factory
(
mock
(
DataSource
.
Factory
.
class
))
.
setStreamKeys
(
Collections
.
singletonList
(
new
StreamKey
(
/* groupIndex= */
1
,
/* trackIndex= */
0
)));
MediaItem
dashMediaItem
=
factory
.
createMediaSource
(
mediaItem
).
getMediaItem
();
assertThat
(
dashMediaItem
.
playbackProperties
).
isNotNull
();
assertThat
(
dashMediaItem
.
playbackProperties
.
uri
).
isEqualTo
(
mediaItem
.
playbackProperties
.
uri
);
assertThat
(
dashMediaItem
.
playbackProperties
.
streamKeys
).
containsExactly
(
mediaItemStreamKey
);
}
}
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