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
2b44ff3c
authored
Apr 07, 2020
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge pull request #7184 from TiVo:p-subtitle-format-from-codecs
PiperOrigin-RevId: 305137114
parents
8d2bc7d1
fbd97ad8
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
77 additions
and
14 deletions
RELEASENOTES.md
library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java
library/common/src/test/java/com/google/android/exoplayer2/util/MimeTypesTest.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/HlsMasterPlaylistParserTest.java
RELEASENOTES.md
View file @
2b44ff3c
...
@@ -88,6 +88,8 @@
...
@@ -88,6 +88,8 @@
`OfflineLicenseHelper`
`OfflineLicenseHelper`
(
[
#7078
](
https://github.com/google/ExoPlayer/issues/7078
)
).
(
[
#7078
](
https://github.com/google/ExoPlayer/issues/7078
)
).
*
Remove generics from DRM components.
*
Remove generics from DRM components.
*
HLS: Recognize IMSC subtitles
(
[
#7185
](
https://github.com/google/ExoPlayer/issues/7185
)
).
*
Downloads: Merge downloads in
`SegmentDownloader`
to improve overall
*
Downloads: Merge downloads in
`SegmentDownloader`
to improve overall
download speed (
[
#5978
](
https://github.com/google/ExoPlayer/issues/5978
)
).
download speed (
[
#5978
](
https://github.com/google/ExoPlayer/issues/5978
)
).
*
MP3: Add
`IndexSeeker`
for accurate seeks in VBR streams
*
MP3: Add
`IndexSeeker`
for accurate seeks in VBR streams
...
...
library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java
View file @
2b44ff3c
...
@@ -123,22 +123,22 @@ public final class MimeTypes {
...
@@ -123,22 +123,22 @@ public final class MimeTypes {
customMimeTypes
.
add
(
customMimeType
);
customMimeTypes
.
add
(
customMimeType
);
}
}
/** Returns whether the given string is an audio
mime
type. */
/** Returns whether the given string is an audio
MIME
type. */
public
static
boolean
isAudio
(
@Nullable
String
mimeType
)
{
public
static
boolean
isAudio
(
@Nullable
String
mimeType
)
{
return
BASE_TYPE_AUDIO
.
equals
(
getTopLevelType
(
mimeType
));
return
BASE_TYPE_AUDIO
.
equals
(
getTopLevelType
(
mimeType
));
}
}
/** Returns whether the given string is a video
mime
type. */
/** Returns whether the given string is a video
MIME
type. */
public
static
boolean
isVideo
(
@Nullable
String
mimeType
)
{
public
static
boolean
isVideo
(
@Nullable
String
mimeType
)
{
return
BASE_TYPE_VIDEO
.
equals
(
getTopLevelType
(
mimeType
));
return
BASE_TYPE_VIDEO
.
equals
(
getTopLevelType
(
mimeType
));
}
}
/** Returns whether the given string is a text
mime
type. */
/** Returns whether the given string is a text
MIME
type. */
public
static
boolean
isText
(
@Nullable
String
mimeType
)
{
public
static
boolean
isText
(
@Nullable
String
mimeType
)
{
return
BASE_TYPE_TEXT
.
equals
(
getTopLevelType
(
mimeType
));
return
BASE_TYPE_TEXT
.
equals
(
getTopLevelType
(
mimeType
));
}
}
/** Returns whether the given string is an application
mime
type. */
/** Returns whether the given string is an application
MIME
type. */
public
static
boolean
isApplication
(
@Nullable
String
mimeType
)
{
public
static
boolean
isApplication
(
@Nullable
String
mimeType
)
{
return
BASE_TYPE_APPLICATION
.
equals
(
getTopLevelType
(
mimeType
));
return
BASE_TYPE_APPLICATION
.
equals
(
getTopLevelType
(
mimeType
));
}
}
...
@@ -174,13 +174,14 @@ public final class MimeTypes {
...
@@ -174,13 +174,14 @@ public final class MimeTypes {
* @param codecs The codecs attribute.
* @param codecs The codecs attribute.
* @return The derived video mimeType, or null if it could not be derived.
* @return The derived video mimeType, or null if it could not be derived.
*/
*/
public
static
@Nullable
String
getVideoMediaMimeType
(
@Nullable
String
codecs
)
{
@Nullable
public
static
String
getVideoMediaMimeType
(
@Nullable
String
codecs
)
{
if
(
codecs
==
null
)
{
if
(
codecs
==
null
)
{
return
null
;
return
null
;
}
}
String
[]
codecList
=
Util
.
splitCodecs
(
codecs
);
String
[]
codecList
=
Util
.
splitCodecs
(
codecs
);
for
(
String
codec
:
codecList
)
{
for
(
String
codec
:
codecList
)
{
String
mimeType
=
getMediaMimeType
(
codec
);
@Nullable
String
mimeType
=
getMediaMimeType
(
codec
);
if
(
mimeType
!=
null
&&
isVideo
(
mimeType
))
{
if
(
mimeType
!=
null
&&
isVideo
(
mimeType
))
{
return
mimeType
;
return
mimeType
;
}
}
...
@@ -194,13 +195,14 @@ public final class MimeTypes {
...
@@ -194,13 +195,14 @@ public final class MimeTypes {
* @param codecs The codecs attribute.
* @param codecs The codecs attribute.
* @return The derived audio mimeType, or null if it could not be derived.
* @return The derived audio mimeType, or null if it could not be derived.
*/
*/
public
static
@Nullable
String
getAudioMediaMimeType
(
@Nullable
String
codecs
)
{
@Nullable
public
static
String
getAudioMediaMimeType
(
@Nullable
String
codecs
)
{
if
(
codecs
==
null
)
{
if
(
codecs
==
null
)
{
return
null
;
return
null
;
}
}
String
[]
codecList
=
Util
.
splitCodecs
(
codecs
);
String
[]
codecList
=
Util
.
splitCodecs
(
codecs
);
for
(
String
codec
:
codecList
)
{
for
(
String
codec
:
codecList
)
{
String
mimeType
=
getMediaMimeType
(
codec
);
@Nullable
String
mimeType
=
getMediaMimeType
(
codec
);
if
(
mimeType
!=
null
&&
isAudio
(
mimeType
))
{
if
(
mimeType
!=
null
&&
isAudio
(
mimeType
))
{
return
mimeType
;
return
mimeType
;
}
}
...
@@ -214,7 +216,8 @@ public final class MimeTypes {
...
@@ -214,7 +216,8 @@ public final class MimeTypes {
* @param codec The codec identifier to derive.
* @param codec The codec identifier to derive.
* @return The mimeType, or null if it could not be derived.
* @return The mimeType, or null if it could not be derived.
*/
*/
public
static
@Nullable
String
getMediaMimeType
(
@Nullable
String
codec
)
{
@Nullable
public
static
String
getMediaMimeType
(
@Nullable
String
codec
)
{
if
(
codec
==
null
)
{
if
(
codec
==
null
)
{
return
null
;
return
null
;
}
}
...
@@ -235,7 +238,7 @@ public final class MimeTypes {
...
@@ -235,7 +238,7 @@ public final class MimeTypes {
}
else
if
(
codec
.
startsWith
(
"vp8"
)
||
codec
.
startsWith
(
"vp08"
))
{
}
else
if
(
codec
.
startsWith
(
"vp8"
)
||
codec
.
startsWith
(
"vp08"
))
{
return
MimeTypes
.
VIDEO_VP8
;
return
MimeTypes
.
VIDEO_VP8
;
}
else
if
(
codec
.
startsWith
(
"mp4a"
))
{
}
else
if
(
codec
.
startsWith
(
"mp4a"
))
{
String
mimeType
=
null
;
@Nullable
String
mimeType
=
null
;
if
(
codec
.
startsWith
(
"mp4a."
))
{
if
(
codec
.
startsWith
(
"mp4a."
))
{
String
objectTypeString
=
codec
.
substring
(
5
);
// remove the 'mp4a.' prefix
String
objectTypeString
=
codec
.
substring
(
5
);
// remove the 'mp4a.' prefix
if
(
objectTypeString
.
length
()
>=
2
)
{
if
(
objectTypeString
.
length
()
>=
2
)
{
...
@@ -244,7 +247,7 @@ public final class MimeTypes {
...
@@ -244,7 +247,7 @@ public final class MimeTypes {
int
objectTypeInt
=
Integer
.
parseInt
(
objectTypeHexString
,
16
);
int
objectTypeInt
=
Integer
.
parseInt
(
objectTypeHexString
,
16
);
mimeType
=
getMimeTypeFromMp4ObjectType
(
objectTypeInt
);
mimeType
=
getMimeTypeFromMp4ObjectType
(
objectTypeInt
);
}
catch
(
NumberFormatException
ignored
)
{
}
catch
(
NumberFormatException
ignored
)
{
//
ignored
//
Ignored.
}
}
}
}
}
}
...
@@ -267,6 +270,10 @@ public final class MimeTypes {
...
@@ -267,6 +270,10 @@ public final class MimeTypes {
return
MimeTypes
.
AUDIO_VORBIS
;
return
MimeTypes
.
AUDIO_VORBIS
;
}
else
if
(
codec
.
startsWith
(
"flac"
))
{
}
else
if
(
codec
.
startsWith
(
"flac"
))
{
return
MimeTypes
.
AUDIO_FLAC
;
return
MimeTypes
.
AUDIO_FLAC
;
}
else
if
(
codec
.
startsWith
(
"stpp"
))
{
return
MimeTypes
.
APPLICATION_TTML
;
}
else
if
(
codec
.
startsWith
(
"wvtt"
))
{
return
MimeTypes
.
TEXT_VTT
;
}
else
{
}
else
{
return
getCustomMimeTypeForCodec
(
codec
);
return
getCustomMimeTypeForCodec
(
codec
);
}
}
...
@@ -406,7 +413,8 @@ public final class MimeTypes {
...
@@ -406,7 +413,8 @@ public final class MimeTypes {
* Returns the top-level type of {@code mimeType}, or null if {@code mimeType} is null or does not
* Returns the top-level type of {@code mimeType}, or null if {@code mimeType} is null or does not
* contain a forward slash character ({@code '/'}).
* contain a forward slash character ({@code '/'}).
*/
*/
private
static
@Nullable
String
getTopLevelType
(
@Nullable
String
mimeType
)
{
@Nullable
private
static
String
getTopLevelType
(
@Nullable
String
mimeType
)
{
if
(
mimeType
==
null
)
{
if
(
mimeType
==
null
)
{
return
null
;
return
null
;
}
}
...
@@ -417,7 +425,8 @@ public final class MimeTypes {
...
@@ -417,7 +425,8 @@ public final class MimeTypes {
return
mimeType
.
substring
(
0
,
indexOfSlash
);
return
mimeType
.
substring
(
0
,
indexOfSlash
);
}
}
private
static
@Nullable
String
getCustomMimeTypeForCodec
(
String
codec
)
{
@Nullable
private
static
String
getCustomMimeTypeForCodec
(
String
codec
)
{
int
customMimeTypeCount
=
customMimeTypes
.
size
();
int
customMimeTypeCount
=
customMimeTypes
.
size
();
for
(
int
i
=
0
;
i
<
customMimeTypeCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
customMimeTypeCount
;
i
++)
{
CustomMimeType
customMimeType
=
customMimeTypes
.
get
(
i
);
CustomMimeType
customMimeType
=
customMimeTypes
.
get
(
i
);
...
...
library/common/src/test/java/com/google/android/exoplayer2/util/MimeTypesTest.java
View file @
2b44ff3c
...
@@ -73,6 +73,10 @@ public final class MimeTypesTest {
...
@@ -73,6 +73,10 @@ public final class MimeTypesTest {
assertThat
(
MimeTypes
.
getMediaMimeType
(
"mp4a.AA"
)).
isEqualTo
(
MimeTypes
.
AUDIO_DTS_HD
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"mp4a.AA"
)).
isEqualTo
(
MimeTypes
.
AUDIO_DTS_HD
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"mp4a.AB"
)).
isEqualTo
(
MimeTypes
.
AUDIO_DTS_HD
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"mp4a.AB"
)).
isEqualTo
(
MimeTypes
.
AUDIO_DTS_HD
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"mp4a.AD"
)).
isEqualTo
(
MimeTypes
.
AUDIO_OPUS
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"mp4a.AD"
)).
isEqualTo
(
MimeTypes
.
AUDIO_OPUS
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"wvtt"
)).
isEqualTo
(
MimeTypes
.
TEXT_VTT
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"stpp."
)).
isEqualTo
(
MimeTypes
.
APPLICATION_TTML
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"stpp.ttml.im1t"
)).
isEqualTo
(
MimeTypes
.
APPLICATION_TTML
);
}
}
@Test
@Test
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java
View file @
2b44ff3c
...
@@ -458,7 +458,18 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
...
@@ -458,7 +458,18 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
}
}
break
;
break
;
case
TYPE_SUBTITLES:
case
TYPE_SUBTITLES:
formatBuilder
.
setSampleMimeType
(
MimeTypes
.
TEXT_VTT
).
setMetadata
(
metadata
);
sampleMimeType
=
null
;
variant
=
getVariantWithSubtitleGroup
(
variants
,
groupId
);
if
(
variant
!=
null
)
{
@Nullable
String
codecs
=
Util
.
getCodecsOfType
(
variant
.
format
.
codecs
,
C
.
TRACK_TYPE_TEXT
);
formatBuilder
.
setCodecs
(
codecs
);
sampleMimeType
=
MimeTypes
.
getMediaMimeType
(
codecs
);
}
if
(
sampleMimeType
==
null
)
{
sampleMimeType
=
MimeTypes
.
TEXT_VTT
;
}
formatBuilder
.
setSampleMimeType
(
sampleMimeType
).
setMetadata
(
metadata
);
subtitles
.
add
(
new
Rendition
(
uri
,
formatBuilder
.
build
(),
groupId
,
name
));
subtitles
.
add
(
new
Rendition
(
uri
,
formatBuilder
.
build
(),
groupId
,
name
));
break
;
break
;
case
TYPE_CLOSED_CAPTIONS:
case
TYPE_CLOSED_CAPTIONS:
...
@@ -527,6 +538,17 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
...
@@ -527,6 +538,17 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
return
null
;
return
null
;
}
}
@Nullable
private
static
Variant
getVariantWithSubtitleGroup
(
ArrayList
<
Variant
>
variants
,
String
groupId
)
{
for
(
int
i
=
0
;
i
<
variants
.
size
();
i
++)
{
Variant
variant
=
variants
.
get
(
i
);
if
(
groupId
.
equals
(
variant
.
subtitleGroupId
))
{
return
variant
;
}
}
return
null
;
}
private
static
HlsMediaPlaylist
parseMediaPlaylist
(
private
static
HlsMediaPlaylist
parseMediaPlaylist
(
HlsMasterPlaylist
masterPlaylist
,
LineIterator
iterator
,
String
baseUri
)
throws
IOException
{
HlsMasterPlaylist
masterPlaylist
,
LineIterator
iterator
,
String
baseUri
)
throws
IOException
{
@HlsMediaPlaylist
.
PlaylistType
int
playlistType
=
HlsMediaPlaylist
.
PLAYLIST_TYPE_UNKNOWN
;
@HlsMediaPlaylist
.
PlaylistType
int
playlistType
=
HlsMediaPlaylist
.
PLAYLIST_TYPE_UNKNOWN
;
...
...
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylistParserTest.java
View file @
2b44ff3c
...
@@ -194,6 +194,19 @@ public class HlsMasterPlaylistParserTest {
...
@@ -194,6 +194,19 @@ public class HlsMasterPlaylistParserTest {
+
"#EXT-X-MEDIA:TYPE=SUBTITLES,"
+
"#EXT-X-MEDIA:TYPE=SUBTITLES,"
+
"GROUP-ID=\"sub1\",NAME=\"English\",URI=\"s1/en/prog_index.m3u8\"\n"
;
+
"GROUP-ID=\"sub1\",NAME=\"English\",URI=\"s1/en/prog_index.m3u8\"\n"
;
private
static
final
String
PLAYLIST_WITH_TTML_SUBTITLE
=
" #EXTM3U\n"
+
"\n"
+
"#EXT-X-VERSION:6\n"
+
"\n"
+
"#EXT-X-INDEPENDENT-SEGMENTS\n"
+
"\n"
+
"#EXT-X-STREAM-INF:BANDWIDTH=1280000,CODECS=\"stpp.ttml.im1t,mp4a.40.2,avc1.66.30\",RESOLUTION=304x128,AUDIO=\"aud1\",SUBTITLES=\"sub1\"\n"
+
"http://example.com/low.m3u8\n"
+
"\n"
+
"#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"aud1\",NAME=\"English\",URI=\"a1/index.m3u8\"\n"
+
"#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"sub1\",NAME=\"English\",AUTOSELECT=YES,DEFAULT=YES,URI=\"s1/en/prog_index.m3u8\"\n"
;
@Test
@Test
public
void
parseMasterPlaylist_withSimple_success
()
throws
IOException
{
public
void
parseMasterPlaylist_withSimple_success
()
throws
IOException
{
HlsMasterPlaylist
masterPlaylist
=
parseMasterPlaylist
(
PLAYLIST_URI
,
PLAYLIST_SIMPLE
);
HlsMasterPlaylist
masterPlaylist
=
parseMasterPlaylist
(
PLAYLIST_URI
,
PLAYLIST_SIMPLE
);
...
@@ -321,6 +334,7 @@ public class HlsMasterPlaylistParserTest {
...
@@ -321,6 +334,7 @@ public class HlsMasterPlaylistParserTest {
Format
firstTextFormat
=
playlist
.
subtitles
.
get
(
0
).
format
;
Format
firstTextFormat
=
playlist
.
subtitles
.
get
(
0
).
format
;
assertThat
(
firstTextFormat
.
id
).
isEqualTo
(
"sub1:Eng"
);
assertThat
(
firstTextFormat
.
id
).
isEqualTo
(
"sub1:Eng"
);
assertThat
(
firstTextFormat
.
sampleMimeType
).
isEqualTo
(
MimeTypes
.
TEXT_VTT
);
}
}
@Test
@Test
...
@@ -346,6 +360,18 @@ public class HlsMasterPlaylistParserTest {
...
@@ -346,6 +360,18 @@ public class HlsMasterPlaylistParserTest {
}
}
@Test
@Test
public
void
parseMasterPlaylist_withTtmlSubtitle
()
throws
IOException
{
HlsMasterPlaylist
playlistWithTtmlSubtitle
=
parseMasterPlaylist
(
PLAYLIST_URI
,
PLAYLIST_WITH_TTML_SUBTITLE
);
HlsMasterPlaylist
.
Variant
variant
=
playlistWithTtmlSubtitle
.
variants
.
get
(
0
);
Format
firstTextFormat
=
playlistWithTtmlSubtitle
.
subtitles
.
get
(
0
).
format
;
assertThat
(
firstTextFormat
.
id
).
isEqualTo
(
"sub1:English"
);
assertThat
(
firstTextFormat
.
containerMimeType
).
isEqualTo
(
MimeTypes
.
APPLICATION_M3U8
);
assertThat
(
firstTextFormat
.
sampleMimeType
).
isEqualTo
(
MimeTypes
.
APPLICATION_TTML
);
assertThat
(
variant
.
format
.
codecs
).
isEqualTo
(
"stpp.ttml.im1t,mp4a.40.2,avc1.66.30"
);
}
@Test
public
void
parseMasterPlaylist_withMatchingStreamInfUrls_success
()
throws
IOException
{
public
void
parseMasterPlaylist_withMatchingStreamInfUrls_success
()
throws
IOException
{
HlsMasterPlaylist
playlist
=
HlsMasterPlaylist
playlist
=
parseMasterPlaylist
(
PLAYLIST_URI
,
PLAYLIST_WITH_MATCHING_STREAM_INF_URLS
);
parseMasterPlaylist
(
PLAYLIST_URI
,
PLAYLIST_WITH_MATCHING_STREAM_INF_URLS
);
...
...
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