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
49858b82
authored
Apr 07, 2020
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Merge pull request #7184 from TiVo:p-subtitle-format-from-codecs
PiperOrigin-RevId: 305137114
parent
cc29798d
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
83 additions
and
23 deletions
RELEASENOTES.md
library/core/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java
library/core/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 @
49858b82
...
...
@@ -37,6 +37,8 @@
*
Update the manifest URI to avoid repeated HTTP redirects
(
[
#6907
](
https://github.com/google/ExoPlayer/issues/6907
)
).
*
Parse period
`AssetIdentifier`
elements.
*
HLS: Recognize IMSC subtitles
(
[
#7185
](
https://github.com/google/ExoPlayer/issues/7185
)
).
*
UI: Add an option to set whether to use the orientation sensor for rotation
in spherical playbacks
(
[
#6761
](
https://github.com/google/ExoPlayer/issues/6761
)
).
...
...
library/core/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java
View file @
49858b82
...
...
@@ -122,22 +122,22 @@ public final class MimeTypes {
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
)
{
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
)
{
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
)
{
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
)
{
return
BASE_TYPE_APPLICATION
.
equals
(
getTopLevelType
(
mimeType
));
}
...
...
@@ -173,13 +173,14 @@ public final class MimeTypes {
* @param codecs The codecs attribute.
* @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
)
{
return
null
;
}
String
[]
codecList
=
Util
.
splitCodecs
(
codecs
);
for
(
String
codec
:
codecList
)
{
String
mimeType
=
getMediaMimeType
(
codec
);
@Nullable
String
mimeType
=
getMediaMimeType
(
codec
);
if
(
mimeType
!=
null
&&
isVideo
(
mimeType
))
{
return
mimeType
;
}
...
...
@@ -193,13 +194,14 @@ public final class MimeTypes {
* @param codecs The codecs attribute.
* @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
)
{
return
null
;
}
String
[]
codecList
=
Util
.
splitCodecs
(
codecs
);
for
(
String
codec
:
codecList
)
{
String
mimeType
=
getMediaMimeType
(
codec
);
@Nullable
String
mimeType
=
getMediaMimeType
(
codec
);
if
(
mimeType
!=
null
&&
isAudio
(
mimeType
))
{
return
mimeType
;
}
...
...
@@ -213,7 +215,8 @@ public final class MimeTypes {
* @param codec The codec identifier to derive.
* @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
)
{
return
null
;
}
...
...
@@ -234,7 +237,7 @@ public final class MimeTypes {
}
else
if
(
codec
.
startsWith
(
"vp8"
)
||
codec
.
startsWith
(
"vp08"
))
{
return
MimeTypes
.
VIDEO_VP8
;
}
else
if
(
codec
.
startsWith
(
"mp4a"
))
{
String
mimeType
=
null
;
@Nullable
String
mimeType
=
null
;
if
(
codec
.
startsWith
(
"mp4a."
))
{
String
objectTypeString
=
codec
.
substring
(
5
);
// remove the 'mp4a.' prefix
if
(
objectTypeString
.
length
()
>=
2
)
{
...
...
@@ -243,7 +246,7 @@ public final class MimeTypes {
int
objectTypeInt
=
Integer
.
parseInt
(
objectTypeHexString
,
16
);
mimeType
=
getMimeTypeFromMp4ObjectType
(
objectTypeInt
);
}
catch
(
NumberFormatException
ignored
)
{
//
ignored
//
Ignored.
}
}
}
...
...
@@ -266,6 +269,10 @@ public final class MimeTypes {
return
MimeTypes
.
AUDIO_VORBIS
;
}
else
if
(
codec
.
startsWith
(
"flac"
))
{
return
MimeTypes
.
AUDIO_FLAC
;
}
else
if
(
codec
.
startsWith
(
"stpp"
))
{
return
MimeTypes
.
APPLICATION_TTML
;
}
else
if
(
codec
.
startsWith
(
"wvtt"
))
{
return
MimeTypes
.
TEXT_VTT
;
}
else
{
return
getCustomMimeTypeForCodec
(
codec
);
}
...
...
@@ -405,7 +412,8 @@ public final class MimeTypes {
* Returns the top-level type of {@code mimeType}, or null if {@code mimeType} is null or does not
* 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
)
{
return
null
;
}
...
...
@@ -416,7 +424,8 @@ public final class MimeTypes {
return
mimeType
.
substring
(
0
,
indexOfSlash
);
}
private
static
@Nullable
String
getCustomMimeTypeForCodec
(
String
codec
)
{
@Nullable
private
static
String
getCustomMimeTypeForCodec
(
String
codec
)
{
int
customMimeTypeCount
=
customMimeTypes
.
size
();
for
(
int
i
=
0
;
i
<
customMimeTypeCount
;
i
++)
{
CustomMimeType
customMimeType
=
customMimeTypes
.
get
(
i
);
...
...
library/core/src/test/java/com/google/android/exoplayer2/util/MimeTypesTest.java
View file @
49858b82
...
...
@@ -73,6 +73,10 @@ public final class MimeTypesTest {
assertThat
(
MimeTypes
.
getMediaMimeType
(
"mp4a.AA"
)).
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
(
"wvtt"
)).
isEqualTo
(
MimeTypes
.
TEXT_VTT
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"stpp."
)).
isEqualTo
(
MimeTypes
.
APPLICATION_TTML
);
assertThat
(
MimeTypes
.
getMediaMimeType
(
"stpp.ttml.im1t"
)).
isEqualTo
(
MimeTypes
.
APPLICATION_TTML
);
}
@Test
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java
View file @
49858b82
...
...
@@ -480,19 +480,28 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
}
break
;
case
TYPE_SUBTITLES:
codecs
=
null
;
sampleMimeType
=
null
;
variant
=
getVariantWithSubtitleGroup
(
variants
,
groupId
);
if
(
variant
!=
null
)
{
codecs
=
Util
.
getCodecsOfType
(
variant
.
format
.
codecs
,
C
.
TRACK_TYPE_TEXT
);
sampleMimeType
=
MimeTypes
.
getMediaMimeType
(
codecs
);
}
if
(
sampleMimeType
==
null
)
{
sampleMimeType
=
MimeTypes
.
TEXT_VTT
;
}
format
=
Format
.
createTextContainerFormat
(
/* id= */
formatId
,
/* label= */
name
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
/* sampleMimeType= */
MimeTypes
.
TEXT_VTT
,
/* codecs= */
null
,
/* bitrate= */
Format
.
NO_VALUE
,
selectionFlags
,
roleFlags
,
language
)
/* id= */
formatId
,
/* label= */
name
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
sampleMimeType
,
codecs
,
/* bitrate= */
Format
.
NO_VALUE
,
selectionFlags
,
roleFlags
,
language
)
.
copyWithMetadata
(
metadata
);
subtitles
.
add
(
new
Rendition
(
uri
,
format
,
groupId
,
name
));
break
;
case
TYPE_CLOSED_CAPTIONS:
String
instreamId
=
parseStringAttr
(
line
,
REGEX_INSTREAM_ID
,
variableDefinitions
);
...
...
@@ -569,6 +578,17 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
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
(
HlsMasterPlaylist
masterPlaylist
,
LineIterator
iterator
,
String
baseUri
)
throws
IOException
{
@HlsMediaPlaylist
.
PlaylistType
int
playlistType
=
HlsMediaPlaylist
.
PLAYLIST_TYPE_UNKNOWN
;
...
...
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylistParserTest.java
View file @
49858b82
...
...
@@ -194,6 +194,19 @@ public class HlsMasterPlaylistParserTest {
+
"#EXT-X-MEDIA:TYPE=SUBTITLES,"
+
"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
public
void
testParseMasterPlaylist
()
throws
IOException
{
HlsMasterPlaylist
masterPlaylist
=
parseMasterPlaylist
(
PLAYLIST_URI
,
PLAYLIST_SIMPLE
);
...
...
@@ -380,6 +393,18 @@ public class HlsMasterPlaylistParserTest {
.
isEqualTo
(
createExtXMediaMetadata
(
/* groupId= */
"aud3"
,
/* name= */
"English"
));
}
@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"
);
}
private
static
Metadata
createExtXStreamInfMetadata
(
HlsTrackMetadataEntry
.
VariantInfo
...
infos
)
{
return
new
Metadata
(
new
HlsTrackMetadataEntry
(
/* groupId= */
null
,
/* name= */
null
,
Arrays
.
asList
(
infos
)));
...
...
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