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
315ba6f3
authored
Mar 30, 2020
by
bachinger
Committed by
Oliver Woodman
Mar 30, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
add subtitle to the media item
PiperOrigin-RevId: 303753642
parent
0782c5f2
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
208 additions
and
38 deletions
demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java
library/core/src/main/java/com/google/android/exoplayer2/MediaItem.java
library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java
library/core/src/test/java/com/google/android/exoplayer2/MediaItemTest.java
library/core/src/test/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactoryTest.java
demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java
View file @
315ba6f3
...
@@ -33,7 +33,6 @@ import androidx.annotation.Nullable;
...
@@ -33,7 +33,6 @@ import androidx.annotation.Nullable;
import
androidx.appcompat.app.AppCompatActivity
;
import
androidx.appcompat.app.AppCompatActivity
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.ExoPlaybackException
;
import
com.google.android.exoplayer2.ExoPlaybackException
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.PlaybackPreparer
;
import
com.google.android.exoplayer2.PlaybackPreparer
;
import
com.google.android.exoplayer2.Player
;
import
com.google.android.exoplayer2.Player
;
...
@@ -47,8 +46,6 @@ import com.google.android.exoplayer2.offline.DownloadRequest;
...
@@ -47,8 +46,6 @@ import com.google.android.exoplayer2.offline.DownloadRequest;
import
com.google.android.exoplayer2.source.BehindLiveWindowException
;
import
com.google.android.exoplayer2.source.BehindLiveWindowException
;
import
com.google.android.exoplayer2.source.DefaultMediaSourceFactory
;
import
com.google.android.exoplayer2.source.DefaultMediaSourceFactory
;
import
com.google.android.exoplayer2.source.MediaSource
;
import
com.google.android.exoplayer2.source.MediaSource
;
import
com.google.android.exoplayer2.source.MergingMediaSource
;
import
com.google.android.exoplayer2.source.SingleSampleMediaSource
;
import
com.google.android.exoplayer2.source.TrackGroupArray
;
import
com.google.android.exoplayer2.source.TrackGroupArray
;
import
com.google.android.exoplayer2.source.ads.AdsLoader
;
import
com.google.android.exoplayer2.source.ads.AdsLoader
;
import
com.google.android.exoplayer2.source.ads.AdsMediaSource
;
import
com.google.android.exoplayer2.source.ads.AdsMediaSource
;
...
@@ -412,43 +409,24 @@ public class PlayerActivity extends AppCompatActivity
...
@@ -412,43 +409,24 @@ public class PlayerActivity extends AppCompatActivity
:
new
UriSample
[]
{(
UriSample
)
intentAsSample
};
:
new
UriSample
[]
{(
UriSample
)
intentAsSample
};
boolean
seenAdsTagUri
=
false
;
boolean
seenAdsTagUri
=
false
;
List
<
MediaSource
>
mediaSources
=
new
ArrayList
<>();
for
(
UriSample
sample
:
samples
)
{
for
(
UriSample
sample
:
samples
)
{
seenAdsTagUri
|=
sample
.
adTagUri
!=
null
;
seenAdsTagUri
|=
sample
.
adTagUri
!=
null
;
if
(!
Util
.
checkCleartextTrafficPermitted
(
sample
.
uri
))
{
if
(!
Util
.
checkCleartextTrafficPermitted
(
sample
.
uri
))
{
showToast
(
R
.
string
.
error_cleartext_not_permitted
);
showToast
(
R
.
string
.
error_cleartext_not_permitted
);
return
Collections
.
emptyList
();
return
Collections
.
emptyList
();
}
}
if
(
Util
.
maybeRequestReadExternalStoragePermission
(
/* activity= */
this
,
sample
.
uri
))
{
if
(
Util
.
maybeRequestReadExternalStoragePermission
(
/* activity= */
this
,
sample
.
uri
)
||
(
sample
.
subtitleInfo
!=
null
&&
Util
.
maybeRequestReadExternalStoragePermission
(
/* activity= */
this
,
sample
.
subtitleInfo
.
uri
)))
{
// The player will be reinitialized if the permission is granted.
// The player will be reinitialized if the permission is granted.
return
Collections
.
emptyList
();
return
Collections
.
emptyList
();
}
}
}
List
<
MediaSource
>
mediaSources
=
new
ArrayList
<>();
for
(
UriSample
sample
:
samples
)
{
MediaSource
mediaSource
=
createLeafMediaSource
(
sample
);
MediaSource
mediaSource
=
createLeafMediaSource
(
sample
);
if
(
mediaSource
==
null
)
{
if
(
mediaSource
!=
null
)
{
continue
;
mediaSources
.
add
(
mediaSource
);
}
Sample
.
SubtitleInfo
subtitleInfo
=
sample
.
subtitleInfo
;
if
(
subtitleInfo
!=
null
)
{
if
(
Util
.
maybeRequestReadExternalStoragePermission
(
/* activity= */
this
,
subtitleInfo
.
uri
))
{
// The player will be reinitialized if the permission is granted.
return
Collections
.
emptyList
();
}
Format
subtitleFormat
=
new
Format
.
Builder
()
.
setSampleMimeType
(
subtitleInfo
.
mimeType
)
.
setSelectionFlags
(
C
.
SELECTION_FLAG_DEFAULT
)
.
setLanguage
(
subtitleInfo
.
language
)
.
build
();
MediaSource
subtitleMediaSource
=
new
SingleSampleMediaSource
.
Factory
(
dataSourceFactory
)
.
createMediaSource
(
subtitleInfo
.
uri
,
subtitleFormat
,
C
.
TIME_UNSET
);
mediaSource
=
new
MergingMediaSource
(
mediaSource
,
subtitleMediaSource
);
}
}
mediaSources
.
add
(
mediaSource
);
}
}
if
(
seenAdsTagUri
&&
mediaSources
.
size
()
==
1
)
{
if
(
seenAdsTagUri
&&
mediaSources
.
size
()
==
1
)
{
Uri
adTagUri
=
samples
[
0
].
adTagUri
;
Uri
adTagUri
=
samples
[
0
].
adTagUri
;
...
@@ -497,6 +475,15 @@ public class PlayerActivity extends AppCompatActivity
...
@@ -497,6 +475,15 @@ public class PlayerActivity extends AppCompatActivity
drmSessionForClearTypes
=
parameters
.
drmInfo
.
drmSessionForClearTypes
;
drmSessionForClearTypes
=
parameters
.
drmInfo
.
drmSessionForClearTypes
;
drmDataSourceFactory
=
((
DemoApplication
)
getApplication
()).
buildHttpDataSourceFactory
();
drmDataSourceFactory
=
((
DemoApplication
)
getApplication
()).
buildHttpDataSourceFactory
();
}
}
if
(
parameters
.
subtitleInfo
!=
null
)
{
builder
.
setSubtitles
(
Collections
.
singletonList
(
new
MediaItem
.
Subtitle
(
parameters
.
subtitleInfo
.
uri
,
parameters
.
subtitleInfo
.
mimeType
,
parameters
.
subtitleInfo
.
language
,
C
.
SELECTION_FLAG_DEFAULT
)));
}
DownloadRequest
downloadRequest
=
DownloadRequest
downloadRequest
=
((
DemoApplication
)
getApplication
())
((
DemoApplication
)
getApplication
())
...
@@ -531,7 +518,7 @@ public class PlayerActivity extends AppCompatActivity
...
@@ -531,7 +518,7 @@ public class PlayerActivity extends AppCompatActivity
debugViewHelper
=
null
;
debugViewHelper
=
null
;
player
.
release
();
player
.
release
();
player
=
null
;
player
=
null
;
mediaSources
=
null
;
mediaSources
=
Collections
.
emptyList
()
;
trackSelector
=
null
;
trackSelector
=
null
;
}
}
if
(
adsLoader
!=
null
)
{
if
(
adsLoader
!=
null
)
{
...
...
library/core/src/main/java/com/google/android/exoplayer2/MediaItem.java
View file @
315ba6f3
...
@@ -61,12 +61,14 @@ public final class MediaItem {
...
@@ -61,12 +61,14 @@ public final class MediaItem {
@Nullable
private
UUID
drmUuid
;
@Nullable
private
UUID
drmUuid
;
private
boolean
drmMultiSession
;
private
boolean
drmMultiSession
;
private
List
<
StreamKey
>
streamKeys
;
private
List
<
StreamKey
>
streamKeys
;
private
List
<
Subtitle
>
subtitles
;
@Nullable
private
Object
tag
;
@Nullable
private
Object
tag
;
@Nullable
private
MediaMetadata
mediaMetadata
;
@Nullable
private
MediaMetadata
mediaMetadata
;
/** Creates a builder. */
/** Creates a builder. */
public
Builder
()
{
public
Builder
()
{
streamKeys
=
Collections
.
emptyList
();
streamKeys
=
Collections
.
emptyList
();
subtitles
=
Collections
.
emptyList
();
drmLicenseRequestHeaders
=
Collections
.
emptyMap
();
drmLicenseRequestHeaders
=
Collections
.
emptyMap
();
}
}
...
@@ -138,6 +140,8 @@ public final class MediaItem {
...
@@ -138,6 +140,8 @@ public final class MediaItem {
/**
/**
* Sets the optional request headers attached to the drm license request.
* Sets the optional request headers attached to the drm license request.
*
*
* <p>{@code null} or an empty {@link Map} can be used for a reset.
*
* <p>If no valid drm configuration is specified, the drm license request headers are ignored.
* <p>If no valid drm configuration is specified, the drm license request headers are ignored.
*/
*/
public
Builder
setDrmLicenseRequestHeaders
(
public
Builder
setDrmLicenseRequestHeaders
(
...
@@ -176,6 +180,8 @@ public final class MediaItem {
...
@@ -176,6 +180,8 @@ public final class MediaItem {
* Sets the optional stream keys by which the manifest is filtered (only used for adaptive
* Sets the optional stream keys by which the manifest is filtered (only used for adaptive
* streams).
* streams).
*
*
* <p>{@code null} or an empty {@link List} can be used for a reset.
*
* <p>If a {@link PlaybackProperties#sourceUri} is set, the stream keys are used to create a
* <p>If a {@link PlaybackProperties#sourceUri} is set, the stream keys are used to create a
* {@link PlaybackProperties} object. Otherwise it will be ignored.
* {@link PlaybackProperties} object. Otherwise it will be ignored.
*/
*/
...
@@ -188,6 +194,22 @@ public final class MediaItem {
...
@@ -188,6 +194,22 @@ public final class MediaItem {
}
}
/**
/**
* Sets the optional subtitles.
*
* <p>{@code null} or an empty {@link List} can be used for a reset.
*
* <p>If a {@link PlaybackProperties#sourceUri} is set, the subtitles are used to create a
* {@link PlaybackProperties} object. Otherwise it will be ignored.
*/
public
Builder
setSubtitles
(
@Nullable
List
<
Subtitle
>
subtitles
)
{
this
.
subtitles
=
subtitles
!=
null
&&
!
subtitles
.
isEmpty
()
?
Collections
.
unmodifiableList
(
new
ArrayList
<>(
subtitles
))
:
Collections
.
emptyList
();
return
this
;
}
/**
* Sets the optional tag for custom attributes. The tag for the media source which will be
* Sets the optional tag for custom attributes. The tag for the media source which will be
* published in the {@link com.google.android.exoplayer2.Timeline} of the source as {@link
* published in the {@link com.google.android.exoplayer2.Timeline} of the source as {@link
* com.google.android.exoplayer2.Timeline.Window#tag}.
* com.google.android.exoplayer2.Timeline.Window#tag}.
...
@@ -222,6 +244,7 @@ public final class MediaItem {
...
@@ -222,6 +244,7 @@ public final class MediaItem {
drmUuid
,
drmLicenseUri
,
drmLicenseRequestHeaders
,
drmMultiSession
)
drmUuid
,
drmLicenseUri
,
drmLicenseRequestHeaders
,
drmMultiSession
)
:
null
,
:
null
,
streamKeys
,
streamKeys
,
subtitles
,
tag
);
tag
);
mediaId
=
mediaId
!=
null
?
mediaId
:
sourceUri
.
toString
();
mediaId
=
mediaId
!=
null
?
mediaId
:
sourceUri
.
toString
();
}
}
...
@@ -266,7 +289,7 @@ public final class MediaItem {
...
@@ -266,7 +289,7 @@ public final class MediaItem {
if
(
this
==
obj
)
{
if
(
this
==
obj
)
{
return
true
;
return
true
;
}
}
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
(
))
{
if
(
!(
obj
instanceof
DrmConfiguration
))
{
return
false
;
return
false
;
}
}
...
@@ -307,6 +330,9 @@ public final class MediaItem {
...
@@ -307,6 +330,9 @@ public final class MediaItem {
/** Optional stream keys by which the manifest is filtered. */
/** Optional stream keys by which the manifest is filtered. */
public
final
List
<
StreamKey
>
streamKeys
;
public
final
List
<
StreamKey
>
streamKeys
;
/** Optional subtitles to be sideloaded. */
public
final
List
<
Subtitle
>
subtitles
;
/**
/**
* Optional tag for custom attributes. The tag for the media source which will be published in
* Optional tag for custom attributes. The tag for the media source which will be published in
* the {@link com.google.android.exoplayer2.Timeline} of the source as {@link
* the {@link com.google.android.exoplayer2.Timeline} of the source as {@link
...
@@ -319,11 +345,13 @@ public final class MediaItem {
...
@@ -319,11 +345,13 @@ public final class MediaItem {
@Nullable
String
mimeType
,
@Nullable
String
mimeType
,
@Nullable
DrmConfiguration
drmConfiguration
,
@Nullable
DrmConfiguration
drmConfiguration
,
List
<
StreamKey
>
streamKeys
,
List
<
StreamKey
>
streamKeys
,
List
<
Subtitle
>
subtitles
,
@Nullable
Object
tag
)
{
@Nullable
Object
tag
)
{
this
.
sourceUri
=
sourceUri
;
this
.
sourceUri
=
sourceUri
;
this
.
mimeType
=
mimeType
;
this
.
mimeType
=
mimeType
;
this
.
drmConfiguration
=
drmConfiguration
;
this
.
drmConfiguration
=
drmConfiguration
;
this
.
streamKeys
=
streamKeys
;
this
.
streamKeys
=
streamKeys
;
this
.
subtitles
=
subtitles
;
this
.
tag
=
tag
;
this
.
tag
=
tag
;
}
}
...
@@ -332,7 +360,7 @@ public final class MediaItem {
...
@@ -332,7 +360,7 @@ public final class MediaItem {
if
(
this
==
obj
)
{
if
(
this
==
obj
)
{
return
true
;
return
true
;
}
}
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
(
))
{
if
(
!(
obj
instanceof
PlaybackProperties
))
{
return
false
;
return
false
;
}
}
PlaybackProperties
other
=
(
PlaybackProperties
)
obj
;
PlaybackProperties
other
=
(
PlaybackProperties
)
obj
;
...
@@ -340,7 +368,8 @@ public final class MediaItem {
...
@@ -340,7 +368,8 @@ public final class MediaItem {
return
sourceUri
.
equals
(
other
.
sourceUri
)
return
sourceUri
.
equals
(
other
.
sourceUri
)
&&
Util
.
areEqual
(
mimeType
,
other
.
mimeType
)
&&
Util
.
areEqual
(
mimeType
,
other
.
mimeType
)
&&
Util
.
areEqual
(
drmConfiguration
,
other
.
drmConfiguration
)
&&
Util
.
areEqual
(
drmConfiguration
,
other
.
drmConfiguration
)
&&
Util
.
areEqual
(
streamKeys
,
other
.
streamKeys
)
&&
streamKeys
.
equals
(
other
.
streamKeys
)
&&
subtitles
.
equals
(
other
.
subtitles
)
&&
Util
.
areEqual
(
tag
,
other
.
tag
);
&&
Util
.
areEqual
(
tag
,
other
.
tag
);
}
}
...
@@ -350,11 +379,78 @@ public final class MediaItem {
...
@@ -350,11 +379,78 @@ public final class MediaItem {
result
=
31
*
result
+
(
mimeType
==
null
?
0
:
mimeType
.
hashCode
());
result
=
31
*
result
+
(
mimeType
==
null
?
0
:
mimeType
.
hashCode
());
result
=
31
*
result
+
(
drmConfiguration
==
null
?
0
:
drmConfiguration
.
hashCode
());
result
=
31
*
result
+
(
drmConfiguration
==
null
?
0
:
drmConfiguration
.
hashCode
());
result
=
31
*
result
+
streamKeys
.
hashCode
();
result
=
31
*
result
+
streamKeys
.
hashCode
();
result
=
31
*
result
+
subtitles
.
hashCode
();
result
=
31
*
result
+
(
tag
==
null
?
0
:
tag
.
hashCode
());
result
=
31
*
result
+
(
tag
==
null
?
0
:
tag
.
hashCode
());
return
result
;
return
result
;
}
}
}
}
/** Properties for a text track. */
public
static
final
class
Subtitle
{
/** The {@link Uri} to the subtitle file. */
public
final
Uri
uri
;
/** The MIME type. */
public
final
String
mimeType
;
/** The language. */
@Nullable
public
final
String
language
;
/** The selection flags. */
@C
.
SelectionFlags
public
final
int
selectionFlags
;
/**
* Creates an instance.
*
* @param uri The {@link Uri uri} to the subtitle file.
* @param mimeType The mime type.
* @param language The optional language.
*/
public
Subtitle
(
Uri
uri
,
String
mimeType
,
@Nullable
String
language
)
{
this
(
uri
,
mimeType
,
language
,
/* selectionFlags= */
0
);
}
/**
* Creates an instance with the given selection flags.
*
* @param uri The {@link Uri uri} to the subtitle file.
* @param mimeType The mime type.
* @param language The optional language.
* @param selectionFlags The selection flags.
*/
public
Subtitle
(
Uri
uri
,
String
mimeType
,
@Nullable
String
language
,
@C
.
SelectionFlags
int
selectionFlags
)
{
this
.
uri
=
uri
;
this
.
mimeType
=
mimeType
;
this
.
language
=
language
;
this
.
selectionFlags
=
selectionFlags
;
}
@Override
public
boolean
equals
(
@Nullable
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(!(
obj
instanceof
Subtitle
))
{
return
false
;
}
Subtitle
other
=
(
Subtitle
)
obj
;
return
uri
.
equals
(
other
.
uri
)
&&
mimeType
.
equals
(
other
.
mimeType
)
&&
Util
.
areEqual
(
language
,
other
.
language
)
&&
selectionFlags
==
other
.
selectionFlags
;
}
@Override
public
int
hashCode
()
{
int
result
=
uri
.
hashCode
();
result
=
31
*
result
+
mimeType
.
hashCode
();
result
=
31
*
result
+
(
language
==
null
?
0
:
language
.
hashCode
());
result
=
31
*
result
+
selectionFlags
;
return
result
;
}
}
/** Identifies the media item. */
/** Identifies the media item. */
public
final
String
mediaId
;
public
final
String
mediaId
;
...
@@ -374,15 +470,15 @@ public final class MediaItem {
...
@@ -374,15 +470,15 @@ public final class MediaItem {
}
}
@Override
@Override
public
boolean
equals
(
@Nullable
Object
o
)
{
public
boolean
equals
(
@Nullable
Object
o
bj
)
{
if
(
this
==
o
)
{
if
(
this
==
o
bj
)
{
return
true
;
return
true
;
}
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
(
))
{
if
(
!(
obj
instanceof
MediaItem
))
{
return
false
;
return
false
;
}
}
MediaItem
other
=
(
MediaItem
)
o
;
MediaItem
other
=
(
MediaItem
)
o
bj
;
return
Util
.
areEqual
(
mediaId
,
other
.
mediaId
)
return
Util
.
areEqual
(
mediaId
,
other
.
mediaId
)
&&
Util
.
areEqual
(
playbackProperties
,
other
.
playbackProperties
)
&&
Util
.
areEqual
(
playbackProperties
,
other
.
playbackProperties
)
...
...
library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java
View file @
315ba6f3
...
@@ -21,6 +21,7 @@ import android.util.SparseArray;
...
@@ -21,6 +21,7 @@ import android.util.SparseArray;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.ExoPlayerLibraryInfo
;
import
com.google.android.exoplayer2.ExoPlayerLibraryInfo
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.drm.DefaultDrmSessionManager
;
import
com.google.android.exoplayer2.drm.DefaultDrmSessionManager
;
import
com.google.android.exoplayer2.drm.DrmSessionManager
;
import
com.google.android.exoplayer2.drm.DrmSessionManager
;
...
@@ -122,6 +123,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
...
@@ -122,6 +123,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
return
new
DefaultMediaSourceFactory
(
context
,
dataSourceFactory
);
return
new
DefaultMediaSourceFactory
(
context
,
dataSourceFactory
);
}
}
private
final
DataSource
.
Factory
dataSourceFactory
;
private
final
SparseArray
<
MediaSourceFactory
>
mediaSourceFactories
;
private
final
SparseArray
<
MediaSourceFactory
>
mediaSourceFactories
;
@C
.
ContentType
private
final
int
[]
supportedTypes
;
@C
.
ContentType
private
final
int
[]
supportedTypes
;
private
final
String
userAgent
;
private
final
String
userAgent
;
...
@@ -133,6 +135,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
...
@@ -133,6 +135,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
@Nullable
private
List
<
StreamKey
>
streamKeys
;
@Nullable
private
List
<
StreamKey
>
streamKeys
;
private
DefaultMediaSourceFactory
(
Context
context
,
DataSource
.
Factory
dataSourceFactory
)
{
private
DefaultMediaSourceFactory
(
Context
context
,
DataSource
.
Factory
dataSourceFactory
)
{
this
.
dataSourceFactory
=
dataSourceFactory
;
drmSessionManager
=
DrmSessionManager
.
getDummyDrmSessionManager
();
drmSessionManager
=
DrmSessionManager
.
getDummyDrmSessionManager
();
userAgent
=
Util
.
getUserAgent
(
context
,
ExoPlayerLibraryInfo
.
VERSION_SLASHY
);
userAgent
=
Util
.
getUserAgent
(
context
,
ExoPlayerLibraryInfo
.
VERSION_SLASHY
);
drmHttpDataSourceFactory
=
new
DefaultHttpDataSourceFactory
(
userAgent
);
drmHttpDataSourceFactory
=
new
DefaultHttpDataSourceFactory
(
userAgent
);
...
@@ -244,7 +247,30 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
...
@@ -244,7 +247,30 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
!
mediaItem
.
playbackProperties
.
streamKeys
.
isEmpty
()
!
mediaItem
.
playbackProperties
.
streamKeys
.
isEmpty
()
?
mediaItem
.
playbackProperties
.
streamKeys
?
mediaItem
.
playbackProperties
.
streamKeys
:
streamKeys
);
:
streamKeys
);
return
mediaSourceFactory
.
createMediaSource
(
mediaItem
);
MediaSource
leafMediaSource
=
mediaSourceFactory
.
createMediaSource
(
mediaItem
);
if
(
mediaItem
.
playbackProperties
.
subtitles
.
isEmpty
())
{
return
leafMediaSource
;
}
List
<
MediaItem
.
Subtitle
>
subtitles
=
mediaItem
.
playbackProperties
.
subtitles
;
MediaSource
[]
mediaSources
=
new
MediaSource
[
subtitles
.
size
()
+
1
];
mediaSources
[
0
]
=
leafMediaSource
;
SingleSampleMediaSource
.
Factory
singleSampleSourceFactory
=
new
SingleSampleMediaSource
.
Factory
(
dataSourceFactory
);
for
(
int
i
=
0
;
i
<
subtitles
.
size
();
i
++)
{
MediaItem
.
Subtitle
subtitle
=
subtitles
.
get
(
i
);
Format
subtitleFormat
=
new
Format
.
Builder
()
.
setSampleMimeType
(
subtitle
.
mimeType
)
.
setLanguage
(
subtitle
.
language
)
.
setSelectionFlags
(
subtitle
.
selectionFlags
)
.
build
();
mediaSources
[
i
+
1
]
=
singleSampleSourceFactory
.
createMediaSource
(
subtitle
.
uri
,
subtitleFormat
,
C
.
TIME_UNSET
);
}
return
new
MergingMediaSource
(
mediaSources
);
}
}
// internal methods
// internal methods
...
...
library/core/src/test/java/com/google/android/exoplayer2/MediaItemTest.java
View file @
315ba6f3
...
@@ -23,6 +23,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
...
@@ -23,6 +23,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import
com.google.android.exoplayer2.offline.StreamKey
;
import
com.google.android.exoplayer2.offline.StreamKey
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -131,6 +132,24 @@ public class MediaItemTest {
...
@@ -131,6 +132,24 @@ public class MediaItemTest {
}
}
@Test
@Test
public
void
builderSetSubtitles_setsSubtitles
()
{
List
<
MediaItem
.
Subtitle
>
subtitles
=
Arrays
.
asList
(
new
MediaItem
.
Subtitle
(
Uri
.
parse
(
URI_STRING
+
"/en"
),
MimeTypes
.
APPLICATION_TTML
,
/* language= */
"en"
),
new
MediaItem
.
Subtitle
(
Uri
.
parse
(
URI_STRING
+
"/de"
),
MimeTypes
.
APPLICATION_TTML
,
/* language= */
null
,
C
.
SELECTION_FLAG_DEFAULT
));
MediaItem
mediaItem
=
new
MediaItem
.
Builder
().
setSourceUri
(
URI_STRING
).
setSubtitles
(
subtitles
).
build
();
assertThat
(
mediaItem
.
playbackProperties
.
subtitles
).
isEqualTo
(
subtitles
);
}
@Test
public
void
builderSetTag_isNullByDefault
()
{
public
void
builderSetTag_isNullByDefault
()
{
MediaItem
mediaItem
=
new
MediaItem
.
Builder
().
setSourceUri
(
URI_STRING
).
build
();
MediaItem
mediaItem
=
new
MediaItem
.
Builder
().
setSourceUri
(
URI_STRING
).
build
();
...
...
library/core/src/test/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactoryTest.java
View file @
315ba6f3
...
@@ -17,10 +17,15 @@ package com.google.android.exoplayer2.source;
...
@@ -17,10 +17,15 @@ package com.google.android.exoplayer2.source;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
android.net.Uri
;
import
androidx.test.core.app.ApplicationProvider
;
import
androidx.test.core.app.ApplicationProvider
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runner.RunWith
;
...
@@ -29,6 +34,7 @@ import org.junit.runner.RunWith;
...
@@ -29,6 +34,7 @@ import org.junit.runner.RunWith;
public
final
class
DefaultMediaSourceFactoryTest
{
public
final
class
DefaultMediaSourceFactoryTest
{
private
static
final
String
URI_MEDIA
=
"http://exoplayer.dev/video"
;
private
static
final
String
URI_MEDIA
=
"http://exoplayer.dev/video"
;
private
static
final
String
URI_TEXT
=
"http://exoplayer.dev/text"
;
@Test
@Test
public
void
createMediaSource_withoutMimeType_progressiveSource
()
{
public
void
createMediaSource_withoutMimeType_progressiveSource
()
{
...
@@ -81,6 +87,42 @@ public final class DefaultMediaSourceFactoryTest {
...
@@ -81,6 +87,42 @@ public final class DefaultMediaSourceFactoryTest {
}
}
@Test
@Test
public
void
createMediaSource_withSubtitle_isMergingMediaSource
()
{
DefaultMediaSourceFactory
defaultMediaSourceFactory
=
DefaultMediaSourceFactory
.
newInstance
(
ApplicationProvider
.
getApplicationContext
());
List
<
MediaItem
.
Subtitle
>
subtitles
=
Arrays
.
asList
(
new
MediaItem
.
Subtitle
(
Uri
.
parse
(
URI_TEXT
),
MimeTypes
.
APPLICATION_TTML
,
"en"
),
new
MediaItem
.
Subtitle
(
Uri
.
parse
(
URI_TEXT
),
MimeTypes
.
APPLICATION_TTML
,
"de"
,
C
.
SELECTION_FLAG_DEFAULT
));
MediaItem
mediaItem
=
new
MediaItem
.
Builder
().
setSourceUri
(
URI_MEDIA
).
setSubtitles
(
subtitles
).
build
();
MediaSource
mediaSource
=
defaultMediaSourceFactory
.
createMediaSource
(
mediaItem
);
assertThat
(
mediaSource
).
isInstanceOf
(
MergingMediaSource
.
class
);
}
@Test
public
void
createMediaSource_withSubtitle_hasTag
()
{
DefaultMediaSourceFactory
defaultMediaSourceFactory
=
DefaultMediaSourceFactory
.
newInstance
(
ApplicationProvider
.
getApplicationContext
());
Object
tag
=
new
Object
();
MediaItem
mediaItem
=
new
MediaItem
.
Builder
()
.
setTag
(
tag
)
.
setSourceUri
(
URI_MEDIA
)
.
setSubtitles
(
Collections
.
singletonList
(
new
MediaItem
.
Subtitle
(
Uri
.
parse
(
URI_TEXT
),
MimeTypes
.
APPLICATION_TTML
,
"en"
)))
.
build
();
MediaSource
mediaSource
=
defaultMediaSourceFactory
.
createMediaSource
(
mediaItem
);
assertThat
(
mediaSource
.
getTag
()).
isEqualTo
(
tag
);
}
@Test
public
void
getSupportedTypes_coreModule_onlyOther
()
{
public
void
getSupportedTypes_coreModule_onlyOther
()
{
int
[]
supportedTypes
=
int
[]
supportedTypes
=
DefaultMediaSourceFactory
.
newInstance
(
ApplicationProvider
.
getApplicationContext
())
DefaultMediaSourceFactory
.
newInstance
(
ApplicationProvider
.
getApplicationContext
())
...
...
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