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
6fc5e6b9
authored
Feb 21, 2020
by
olly
Committed by
Oliver Woodman
Feb 25, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Migrate HLS to Format.Builder
Issue: #2863 PiperOrigin-RevId: 296482726
parent
f342df20
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
172 additions
and
276 deletions
library/common/src/main/java/com/google/android/exoplayer2/Format.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/DefaultHlsExtractorFactory.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylist.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/HlsMediaPeriodTest.java
library/common/src/main/java/com/google/android/exoplayer2/Format.java
View file @
6fc5e6b9
...
...
@@ -1347,39 +1347,6 @@ public final class Format implements Parcelable {
return
buildUpon
().
setLabel
(
label
).
build
();
}
// TODO: Inline into HlsSampleStreamWrapper and remove.
public
Format
copyWithContainerInfo
(
@Nullable
String
id
,
@Nullable
String
label
,
@Nullable
String
sampleMimeType
,
@Nullable
String
codecs
,
@Nullable
Metadata
metadata
,
int
bitrate
,
int
width
,
int
height
,
int
channelCount
,
@C
.
SelectionFlags
int
selectionFlags
,
@Nullable
String
language
)
{
if
(
this
.
metadata
!=
null
)
{
metadata
=
this
.
metadata
.
copyWithAppendedEntriesFrom
(
metadata
);
}
return
buildUpon
()
.
setId
(
id
)
.
setLabel
(
label
)
.
setLanguage
(
language
)
.
setSelectionFlags
(
selectionFlags
)
.
setAverageBitrate
(
bitrate
)
.
setPeakBitrate
(
bitrate
)
.
setMetadata
(
metadata
)
.
setCodecs
(
codecs
)
.
setSampleMimeType
(
sampleMimeType
)
.
setWidth
(
width
)
.
setHeight
(
height
)
.
setChannelCount
(
channelCount
)
.
build
();
}
/** @deprecated Use {@link #withManifestFormatInfo(Format)}. */
@Deprecated
public
Format
copyWithManifestFormatInfo
(
Format
manifestFormat
)
{
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/DefaultHlsExtractorFactory.java
View file @
6fc5e6b9
...
...
@@ -235,15 +235,11 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory {
// closed caption track on channel 0.
muxedCaptionFormats
=
Collections
.
singletonList
(
Format
.
createTextSampleFormat
(
/* id= */
null
,
MimeTypes
.
APPLICATION_CEA608
,
/* selectionFlags= */
0
,
/* language= */
null
));
new
Format
.
Builder
().
setSampleMimeType
(
MimeTypes
.
APPLICATION_CEA608
).
build
());
}
else
{
muxedCaptionFormats
=
Collections
.
emptyList
();
}
String
codecs
=
format
.
codecs
;
@Nullable
String
codecs
=
format
.
codecs
;
if
(!
TextUtils
.
isEmpty
(
codecs
))
{
// Sometimes AAC and H264 streams are declared in TS chunks even though they don't really
// exist. If we know from the codec attribute that they don't exist, then we can
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java
View file @
6fc5e6b9
...
...
@@ -659,7 +659,11 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
}
TrackGroup
id3TrackGroup
=
new
TrackGroup
(
Format
.
createSampleFormat
(
/* id= */
"ID3"
,
MimeTypes
.
APPLICATION_ID3
));
new
TrackGroup
(
new
Format
.
Builder
()
.
setId
(
"ID3"
)
.
setSampleMimeType
(
MimeTypes
.
APPLICATION_ID3
)
.
build
());
muxedTrackGroups
.
add
(
id3TrackGroup
);
sampleStreamWrapper
.
prepareWithMasterPlaylistInfo
(
...
...
@@ -785,33 +789,34 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
}
private
static
Format
deriveVideoFormat
(
Format
variantFormat
)
{
String
codecs
=
Util
.
getCodecsOfType
(
variantFormat
.
codecs
,
C
.
TRACK_TYPE_VIDEO
);
String
sampleMimeType
=
MimeTypes
.
getMediaMimeType
(
codecs
);
return
Format
.
createVideoContainerFormat
(
variantFormat
.
id
,
variantFormat
.
label
,
variantFormat
.
containerMimeType
,
sampleMimeType
,
codecs
,
variantFormat
.
metadata
,
variantFormat
.
bitrate
,
variantFormat
.
width
,
variantFormat
.
height
,
variantFormat
.
frameRate
,
/* initializationData= */
null
,
variantFormat
.
selectionFlags
,
variantFormat
.
roleFlags
);
@Nullable
String
codecs
=
Util
.
getCodecsOfType
(
variantFormat
.
codecs
,
C
.
TRACK_TYPE_VIDEO
);
@Nullable
String
sampleMimeType
=
MimeTypes
.
getMediaMimeType
(
codecs
);
return
new
Format
.
Builder
()
.
setId
(
variantFormat
.
id
)
.
setLabel
(
variantFormat
.
label
)
.
setContainerMimeType
(
variantFormat
.
containerMimeType
)
.
setSampleMimeType
(
sampleMimeType
)
.
setCodecs
(
codecs
)
.
setMetadata
(
variantFormat
.
metadata
)
.
setAverageBitrate
(
variantFormat
.
averageBitrate
)
.
setPeakBitrate
(
variantFormat
.
peakBitrate
)
.
setWidth
(
variantFormat
.
width
)
.
setHeight
(
variantFormat
.
height
)
.
setFrameRate
(
variantFormat
.
frameRate
)
.
setSelectionFlags
(
variantFormat
.
selectionFlags
)
.
setRoleFlags
(
variantFormat
.
roleFlags
)
.
build
();
}
private
static
Format
deriveAudioFormat
(
Format
variantFormat
,
@Nullable
Format
mediaTagFormat
,
boolean
isPrimaryTrackInVariant
)
{
String
codecs
;
Metadata
metadata
;
@Nullable
String
codecs
;
@Nullable
Metadata
metadata
;
int
channelCount
=
Format
.
NO_VALUE
;
int
selectionFlags
=
0
;
int
roleFlags
=
0
;
String
language
=
null
;
String
label
=
null
;
@Nullable
String
language
=
null
;
@Nullable
String
label
=
null
;
if
(
mediaTagFormat
!=
null
)
{
codecs
=
mediaTagFormat
.
codecs
;
metadata
=
mediaTagFormat
.
metadata
;
...
...
@@ -831,22 +836,23 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
label
=
variantFormat
.
label
;
}
}
String
sampleMimeType
=
MimeTypes
.
getMediaMimeType
(
codecs
);
int
bitrate
=
isPrimaryTrackInVariant
?
variantFormat
.
bitrate
:
Format
.
NO_VALUE
;
return
Format
.
createAudioContainerFormat
(
variantFormat
.
id
,
label
,
variantFormat
.
containerMimeType
,
sampleMimeType
,
codecs
,
metadata
,
bitrate
,
channelCount
,
/* sampleRate= */
Format
.
NO_VALUE
,
/* initializationData= */
null
,
selectionFlags
,
roleFlags
,
language
);
@Nullable
String
sampleMimeType
=
MimeTypes
.
getMediaMimeType
(
codecs
);
int
averageBitrate
=
isPrimaryTrackInVariant
?
variantFormat
.
averageBitrate
:
Format
.
NO_VALUE
;
int
peakBitrate
=
isPrimaryTrackInVariant
?
variantFormat
.
peakBitrate
:
Format
.
NO_VALUE
;
return
new
Format
.
Builder
()
.
setId
(
variantFormat
.
id
)
.
setLabel
(
label
)
.
setContainerMimeType
(
variantFormat
.
containerMimeType
)
.
setSampleMimeType
(
sampleMimeType
)
.
setCodecs
(
codecs
)
.
setMetadata
(
metadata
)
.
setAverageBitrate
(
averageBitrate
)
.
setPeakBitrate
(
peakBitrate
)
.
setChannelCount
(
channelCount
)
.
setSelectionFlags
(
selectionFlags
)
.
setRoleFlags
(
roleFlags
)
.
setLanguage
(
language
)
.
build
();
}
}
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
View file @
6fc5e6b9
...
...
@@ -1269,38 +1269,50 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
*
* @param playlistFormat The format information obtained from the master playlist.
* @param sampleFormat The format information obtained from the samples.
* @param propagateBitrate
Whether the bitrate from the playlist format should be included in the
* derived format.
* @param propagateBitrate
s Whether the bitrates from the playlist format should be included in
*
the
derived format.
* @return The derived track format.
*/
private
static
Format
deriveFormat
(
@Nullable
Format
playlistFormat
,
Format
sampleFormat
,
boolean
propagateBitrate
)
{
@Nullable
Format
playlistFormat
,
Format
sampleFormat
,
boolean
propagateBitrate
s
)
{
if
(
playlistFormat
==
null
)
{
return
sampleFormat
;
}
int
bitrate
=
propagateBitrate
?
playlistFormat
.
bitrate
:
Format
.
NO_VALUE
;
int
channelCount
=
playlistFormat
.
channelCount
!=
Format
.
NO_VALUE
?
playlistFormat
.
channelCount
:
sampleFormat
.
channelCount
;
int
sampleTrackType
=
MimeTypes
.
getTrackType
(
sampleFormat
.
sampleMimeType
);
@Nullable
String
codecs
=
Util
.
getCodecsOfType
(
playlistFormat
.
codecs
,
sampleTrackType
);
@Nullable
String
mimeType
=
MimeTypes
.
getMediaMimeType
(
codecs
);
if
(
mimeType
==
null
)
{
mimeType
=
sampleFormat
.
sampleMimeType
;
}
return
sampleFormat
.
copyWithContainerInfo
(
playlistFormat
.
id
,
playlistFormat
.
label
,
mimeType
,
codecs
,
playlistFormat
.
metadata
,
bitrate
,
playlistFormat
.
width
,
playlistFormat
.
height
,
channelCount
,
playlistFormat
.
selectionFlags
,
playlistFormat
.
language
);
@Nullable
String
sampleMimeType
=
MimeTypes
.
getMediaMimeType
(
codecs
);
Format
.
Builder
formatBuilder
=
sampleFormat
.
buildUpon
()
.
setId
(
playlistFormat
.
id
)
.
setLabel
(
playlistFormat
.
label
)
.
setLanguage
(
playlistFormat
.
language
)
.
setSelectionFlags
(
playlistFormat
.
selectionFlags
)
.
setAverageBitrate
(
propagateBitrates
?
playlistFormat
.
averageBitrate
:
Format
.
NO_VALUE
)
.
setPeakBitrate
(
propagateBitrates
?
playlistFormat
.
peakBitrate
:
Format
.
NO_VALUE
)
.
setCodecs
(
codecs
)
.
setWidth
(
playlistFormat
.
width
)
.
setHeight
(
playlistFormat
.
height
);
if
(
sampleMimeType
!=
null
)
{
formatBuilder
.
setSampleMimeType
(
sampleMimeType
);
}
if
(
playlistFormat
.
channelCount
!=
Format
.
NO_VALUE
)
{
formatBuilder
.
setChannelCount
(
playlistFormat
.
channelCount
);
}
if
(
playlistFormat
.
metadata
!=
null
)
{
Metadata
metadata
=
playlistFormat
.
metadata
;
if
(
sampleFormat
.
metadata
!=
null
)
{
metadata
=
sampleFormat
.
metadata
.
copyWithAppendedEntriesFrom
(
metadata
);
}
formatBuilder
.
setMetadata
(
metadata
);
}
return
formatBuilder
.
build
();
}
private
static
boolean
isMediaChunk
(
Chunk
chunk
)
{
...
...
@@ -1409,9 +1421,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
// TODO(ibaker): Create a Formats util class with common constants like this.
private
static
final
Format
ID3_FORMAT
=
Format
.
createSampleFormat
(
/* id= */
null
,
MimeTypes
.
APPLICATION_ID3
);
new
Format
.
Builder
().
setSampleMimeType
(
MimeTypes
.
APPLICATION_ID3
).
build
(
);
private
static
final
Format
EMSG_FORMAT
=
Format
.
createSampleFormat
(
/* id= */
null
,
MimeTypes
.
APPLICATION_EMSG
);
new
Format
.
Builder
().
setSampleMimeType
(
MimeTypes
.
APPLICATION_EMSG
).
build
(
);
private
final
EventMessageDecoder
emsgDecoder
;
private
final
TrackOutput
delegate
;
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java
View file @
6fc5e6b9
...
...
@@ -187,9 +187,11 @@ public final class WebvttExtractor implements Extractor {
private
TrackOutput
buildTrackOutput
(
long
subsampleOffsetUs
)
{
TrackOutput
trackOutput
=
output
.
track
(
0
,
C
.
TRACK_TYPE_TEXT
);
trackOutput
.
format
(
Format
.
createTextSampleFormat
(
/* id= */
null
,
MimeTypes
.
TEXT_VTT
,
/* selectionFlags= */
0
,
language
)
.
copyWithSubsampleOffsetUs
(
subsampleOffsetUs
));
new
Format
.
Builder
()
.
setSampleMimeType
(
MimeTypes
.
TEXT_VTT
)
.
setLanguage
(
language
)
.
setSubsampleOffsetUs
(
subsampleOffsetUs
)
.
build
());
output
.
endTracks
();
return
trackOutput
;
}
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylist.java
View file @
6fc5e6b9
...
...
@@ -102,16 +102,7 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
*/
public
static
Variant
createMediaPlaylistVariantUrl
(
Uri
url
)
{
Format
format
=
Format
.
createContainerFormat
(
"0"
,
/* label= */
null
,
MimeTypes
.
APPLICATION_M3U8
,
/* sampleMimeType= */
null
,
/* codecs= */
null
,
/* bitrate= */
Format
.
NO_VALUE
,
/* selectionFlags= */
0
,
/* roleFlags= */
0
,
/* language= */
null
);
new
Format
.
Builder
().
setId
(
"0"
).
setContainerMimeType
(
MimeTypes
.
APPLICATION_M3U8
).
build
();
return
new
Variant
(
url
,
format
,
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java
View file @
6fc5e6b9
...
...
@@ -342,22 +342,17 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
replaceVariableReferences
(
iterator
.
next
(),
variableDefinitions
);
// #EXT-X-STREAM-INF's URI.
Uri
uri
=
UriUtil
.
resolveToUri
(
baseUri
,
line
);
// TODO: Set Format.averageBitrate.
Format
format
=
Format
.
createVideoContainerFormat
(
/* id= */
Integer
.
toString
(
variants
.
size
()),
/* label= */
null
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
/* sampleMimeType= */
null
,
codecs
,
/* metadata= */
null
,
peakBitrate
,
width
,
height
,
frameRate
,
/* initializationData= */
null
,
/* selectionFlags= */
0
,
/* roleFlags= */
0
);
new
Format
.
Builder
()
.
setId
(
variants
.
size
())
.
setContainerMimeType
(
MimeTypes
.
APPLICATION_M3U8
)
.
setCodecs
(
codecs
)
.
setAverageBitrate
(
averageBitrate
)
.
setPeakBitrate
(
peakBitrate
)
.
setWidth
(
width
)
.
setHeight
(
height
)
.
setFrameRate
(
frameRate
)
.
build
();
Variant
variant
=
new
Variant
(
uri
,
format
,
videoGroupId
,
audioGroupId
,
subtitlesGroupId
,
closedCaptionsGroupId
);
...
...
@@ -400,131 +395,89 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
line
=
mediaTags
.
get
(
i
);
String
groupId
=
parseStringAttr
(
line
,
REGEX_GROUP_ID
,
variableDefinitions
);
String
name
=
parseStringAttr
(
line
,
REGEX_NAME
,
variableDefinitions
);
String
referenceUri
=
parseOptionalStringAttr
(
line
,
REGEX_URI
,
variableDefinitions
);
Uri
uri
=
referenceUri
==
null
?
null
:
UriUtil
.
resolveToUri
(
baseUri
,
referenceUri
);
String
language
=
parseOptionalStringAttr
(
line
,
REGEX_LANGUAGE
,
variableDefinitions
);
@C
.
SelectionFlags
int
selectionFlags
=
parseSelectionFlags
(
line
);
@C
.
RoleFlags
int
roleFlags
=
parseRoleFlags
(
line
,
variableDefinitions
);
String
formatId
=
groupId
+
":"
+
name
;
Format
format
;
Format
.
Builder
formatBuilder
=
new
Format
.
Builder
()
.
setId
(
groupId
+
":"
+
name
)
.
setLabel
(
name
)
.
setContainerMimeType
(
MimeTypes
.
APPLICATION_M3U8
)
.
setSelectionFlags
(
parseSelectionFlags
(
line
))
.
setRoleFlags
(
parseRoleFlags
(
line
,
variableDefinitions
))
.
setLanguage
(
parseOptionalStringAttr
(
line
,
REGEX_LANGUAGE
,
variableDefinitions
));
@Nullable
String
referenceUri
=
parseOptionalStringAttr
(
line
,
REGEX_URI
,
variableDefinitions
);
@Nullable
Uri
uri
=
referenceUri
==
null
?
null
:
UriUtil
.
resolveToUri
(
baseUri
,
referenceUri
);
Metadata
metadata
=
new
Metadata
(
new
HlsTrackMetadataEntry
(
groupId
,
name
,
Collections
.
emptyList
()));
switch
(
parseStringAttr
(
line
,
REGEX_TYPE
,
variableDefinitions
))
{
case
TYPE_VIDEO:
Variant
variant
=
getVariantWithVideoGroup
(
variants
,
groupId
);
String
codecs
=
null
;
int
width
=
Format
.
NO_VALUE
;
int
height
=
Format
.
NO_VALUE
;
float
frameRate
=
Format
.
NO_VALUE
;
@Nullable
Variant
variant
=
getVariantWithVideoGroup
(
variants
,
groupId
);
if
(
variant
!=
null
)
{
Format
variantFormat
=
variant
.
format
;
codecs
=
Util
.
getCodecsOfType
(
variantFormat
.
codecs
,
C
.
TRACK_TYPE_VIDEO
);
width
=
variantFormat
.
width
;
height
=
variantFormat
.
height
;
frameRate
=
variantFormat
.
frameRate
;
}
String
sampleMimeType
=
codecs
!=
null
?
MimeTypes
.
getMediaMimeType
(
codecs
)
:
null
;
format
=
Format
.
createVideoContainerFormat
(
/* id= */
formatId
,
/* label= */
name
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
sampleMimeType
,
codecs
,
/* metadata= */
null
,
/* bitrate= */
Format
.
NO_VALUE
,
width
,
height
,
frameRate
,
/* initializationData= */
null
,
selectionFlags
,
roleFlags
)
.
copyWithMetadata
(
metadata
);
@Nullable
String
codecs
=
Util
.
getCodecsOfType
(
variantFormat
.
codecs
,
C
.
TRACK_TYPE_VIDEO
);
formatBuilder
.
setCodecs
(
codecs
)
.
setSampleMimeType
(
MimeTypes
.
getMediaMimeType
(
codecs
))
.
setWidth
(
variantFormat
.
width
)
.
setHeight
(
variantFormat
.
height
)
.
setFrameRate
(
variantFormat
.
frameRate
);
}
if
(
uri
==
null
)
{
// TODO: Remove this case and add a Rendition with a null uri to videos.
}
else
{
videos
.
add
(
new
Rendition
(
uri
,
format
,
groupId
,
name
));
formatBuilder
.
setMetadata
(
metadata
);
videos
.
add
(
new
Rendition
(
uri
,
formatBuilder
.
build
(),
groupId
,
name
));
}
break
;
case
TYPE_AUDIO:
@Nullable
String
sampleMimeType
=
null
;
variant
=
getVariantWithAudioGroup
(
variants
,
groupId
);
codecs
=
variant
!=
null
?
Util
.
getCodecsOfType
(
variant
.
format
.
codecs
,
C
.
TRACK_TYPE_AUDIO
)
:
null
;
sampleMimeType
=
codecs
!=
null
?
MimeTypes
.
getMediaMimeType
(
codecs
)
:
null
;
if
(
variant
!=
null
)
{
@Nullable
String
codecs
=
Util
.
getCodecsOfType
(
variant
.
format
.
codecs
,
C
.
TRACK_TYPE_AUDIO
);
formatBuilder
.
setCodecs
(
codecs
);
sampleMimeType
=
MimeTypes
.
getMediaMimeType
(
codecs
);
}
@Nullable
String
channelsString
=
parseOptionalStringAttr
(
line
,
REGEX_CHANNELS
,
variableDefinitions
);
int
channelCount
=
Format
.
NO_VALUE
;
if
(
channelsString
!=
null
)
{
channelCount
=
Integer
.
parseInt
(
Util
.
splitAtFirst
(
channelsString
,
"/"
)[
0
]);
int
channelCount
=
Integer
.
parseInt
(
Util
.
splitAtFirst
(
channelsString
,
"/"
)[
0
]);
formatBuilder
.
setChannelCount
(
channelCount
);
if
(
MimeTypes
.
AUDIO_E_AC3
.
equals
(
sampleMimeType
)
&&
channelsString
.
endsWith
(
"/JOC"
))
{
sampleMimeType
=
MimeTypes
.
AUDIO_E_AC3_JOC
;
}
}
format
=
Format
.
createAudioContainerFormat
(
/* id= */
formatId
,
/* label= */
name
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
sampleMimeType
,
codecs
,
/* metadata= */
null
,
/* bitrate= */
Format
.
NO_VALUE
,
channelCount
,
/* sampleRate= */
Format
.
NO_VALUE
,
/* initializationData= */
null
,
selectionFlags
,
roleFlags
,
language
);
formatBuilder
.
setSampleMimeType
(
sampleMimeType
);
if
(
uri
==
null
)
{
// TODO: Remove muxedAudioFormat and add a Rendition with a null uri to audios.
muxedAudioFormat
=
format
;
muxedAudioFormat
=
format
Builder
.
build
()
;
}
else
{
audios
.
add
(
new
Rendition
(
uri
,
format
.
copyWithMetadata
(
metadata
),
groupId
,
name
));
formatBuilder
.
setMetadata
(
metadata
);
audios
.
add
(
new
Rendition
(
uri
,
formatBuilder
.
build
(),
groupId
,
name
));
}
break
;
case
TYPE_SUBTITLES:
format
=
Format
.
createTextContainerFormat
(
/* id= */
formatId
,
/* label= */
name
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
/* sampleMimeType= */
MimeTypes
.
TEXT_VTT
,
/* codecs= */
null
,
/* bitrate= */
Format
.
NO_VALUE
,
selectionFlags
,
roleFlags
,
language
)
.
copyWithMetadata
(
metadata
);
subtitles
.
add
(
new
Rendition
(
uri
,
format
,
groupId
,
name
));
formatBuilder
.
setSampleMimeType
(
MimeTypes
.
TEXT_VTT
).
setMetadata
(
metadata
);
subtitles
.
add
(
new
Rendition
(
uri
,
formatBuilder
.
build
(),
groupId
,
name
));
break
;
case
TYPE_CLOSED_CAPTIONS:
String
instreamId
=
parseStringAttr
(
line
,
REGEX_INSTREAM_ID
,
variableDefinitions
);
String
mimeType
;
int
accessibilityChannel
;
if
(
instreamId
.
startsWith
(
"CC"
))
{
m
imeType
=
MimeTypes
.
APPLICATION_CEA608
;
sampleM
imeType
=
MimeTypes
.
APPLICATION_CEA608
;
accessibilityChannel
=
Integer
.
parseInt
(
instreamId
.
substring
(
2
));
}
else
/* starts with SERVICE */
{
m
imeType
=
MimeTypes
.
APPLICATION_CEA708
;
sampleM
imeType
=
MimeTypes
.
APPLICATION_CEA708
;
accessibilityChannel
=
Integer
.
parseInt
(
instreamId
.
substring
(
7
));
}
if
(
muxedCaptionFormats
==
null
)
{
muxedCaptionFormats
=
new
ArrayList
<>();
}
muxedCaptionFormats
.
add
(
Format
.
createTextContainerFormat
(
/* id= */
formatId
,
/* label= */
name
,
/* containerMimeType= */
null
,
/* sampleMimeType= */
mimeType
,
/* codecs= */
null
,
/* bitrate= */
Format
.
NO_VALUE
,
selectionFlags
,
roleFlags
,
language
,
accessibilityChannel
));
formatBuilder
.
setSampleMimeType
(
sampleMimeType
)
.
setAccessibilityChannel
(
accessibilityChannel
);
muxedCaptionFormats
.
add
(
formatBuilder
.
build
());
// TODO: Remove muxedCaptionFormats and add a Rendition with a null uri to closedCaptions.
break
;
default
:
...
...
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriodTest.java
View file @
6fc5e6b9
...
...
@@ -55,11 +55,11 @@ public final class HlsMediaPeriodTest {
HlsMasterPlaylist
testMasterPlaylist
=
createMasterPlaylist
(
/* variants= */
Arrays
.
asList
(
createAudioOnlyVariant
(
/*
b
itrate= */
10000
),
createMuxedVideoAudioVariant
(
/*
b
itrate= */
200000
),
createAudioOnlyVariant
(
/*
b
itrate= */
300000
),
createMuxedVideoAudioVariant
(
/*
b
itrate= */
400000
),
createMuxedVideoAudioVariant
(
/*
b
itrate= */
600000
)),
createAudioOnlyVariant
(
/*
peakB
itrate= */
10000
),
createMuxedVideoAudioVariant
(
/*
peakB
itrate= */
200000
),
createAudioOnlyVariant
(
/*
peakB
itrate= */
300000
),
createMuxedVideoAudioVariant
(
/*
peakB
itrate= */
400000
),
createMuxedVideoAudioVariant
(
/*
peakB
itrate= */
600000
)),
/* audios= */
Arrays
.
asList
(
createAudioRendition
(
/* language= */
"spa"
),
createAudioRendition
(
/* language= */
"ger"
),
...
...
@@ -121,40 +121,22 @@ public final class HlsMediaPeriodTest {
/* sessionKeyDrmInitData= */
Collections
.
emptyList
());
}
private
static
Variant
createMuxedVideoAudioVariant
(
int
b
itrate
)
{
private
static
Variant
createMuxedVideoAudioVariant
(
int
peakB
itrate
)
{
return
createVariant
(
Format
.
createVideoContainerFormat
(
/* id= */
null
,
/* label= */
null
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
/* sampleMimeType= */
null
,
/* codecs= */
"avc1.100.41,mp4a.40.2"
,
/* metadata= */
null
,
bitrate
,
/* width= */
Format
.
NO_VALUE
,
/* height= */
Format
.
NO_VALUE
,
/* frameRate= */
Format
.
NO_VALUE
,
/* initializationData= */
null
,
/* selectionFlags= */
0
,
/* roleFlags= */
0
));
new
Format
.
Builder
()
.
setContainerMimeType
(
MimeTypes
.
APPLICATION_M3U8
)
.
setCodecs
(
"avc1.100.41,mp4a.40.2"
)
.
setPeakBitrate
(
peakBitrate
)
.
build
());
}
private
static
Variant
createAudioOnlyVariant
(
int
b
itrate
)
{
private
static
Variant
createAudioOnlyVariant
(
int
peakB
itrate
)
{
return
createVariant
(
Format
.
createVideoContainerFormat
(
/* id= */
null
,
/* label= */
null
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
/* sampleMimeType= */
null
,
/* codecs= */
"mp4a.40.2"
,
/* metadata= */
null
,
bitrate
,
/* width= */
Format
.
NO_VALUE
,
/* height= */
Format
.
NO_VALUE
,
/* frameRate= */
Format
.
NO_VALUE
,
/* initializationData= */
null
,
/* selectionFlags= */
0
,
/* roleFlags= */
0
));
new
Format
.
Builder
()
.
setContainerMimeType
(
MimeTypes
.
APPLICATION_M3U8
)
.
setCodecs
(
"mp4a.40.2"
)
.
setPeakBitrate
(
peakBitrate
)
.
build
());
}
private
static
Rendition
createAudioRendition
(
String
language
)
{
...
...
@@ -174,32 +156,19 @@ public final class HlsMediaPeriodTest {
}
private
static
Format
createAudioFormat
(
String
language
)
{
return
Format
.
createAudioContainerFormat
(
/* id= */
null
,
/* label= */
null
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
MimeTypes
.
getMediaMimeType
(
"mp4a.40.2"
),
/* codecs= */
"mp4a.40.2"
,
/* metadata= */
null
,
/* bitrate= */
Format
.
NO_VALUE
,
/* channelCount= */
Format
.
NO_VALUE
,
/* sampleRate= */
Format
.
NO_VALUE
,
/* initializationData= */
null
,
/* selectionFlags= */
0
,
/* roleFlags= */
0
,
language
);
return
new
Format
.
Builder
()
.
setContainerMimeType
(
MimeTypes
.
APPLICATION_M3U8
)
.
setSampleMimeType
(
MimeTypes
.
getMediaMimeType
(
"mp4a.40.2"
))
.
setCodecs
(
"mp4a.40.2"
)
.
setLanguage
(
language
)
.
build
();
}
private
static
Format
createSubtitleFormat
(
String
language
)
{
return
Format
.
createTextContainerFormat
(
/* id= */
null
,
/* label= */
null
,
/* containerMimeType= */
MimeTypes
.
APPLICATION_M3U8
,
/* sampleMimeType= */
MimeTypes
.
TEXT_VTT
,
/* codecs= */
null
,
/* bitrate= */
Format
.
NO_VALUE
,
/* selectionFlags= */
0
,
/* roleFlags= */
0
,
language
);
return
new
Format
.
Builder
()
.
setContainerMimeType
(
MimeTypes
.
APPLICATION_M3U8
)
.
setSampleMimeType
(
MimeTypes
.
TEXT_VTT
)
.
setLanguage
(
language
)
.
build
();
}
}
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