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