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
7f49b33f
authored
Nov 04, 2020
by
bachinger
Committed by
Andrew Lewis
Nov 06, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Block HLS playlist requests at part level
Issue: #5011 PiperOrigin-RevId: 340625816
parent
4332dc23
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
254 additions
and
13 deletions
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylist.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/DefaultHlsPlaylistTrackerTest.java
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylistParserTest.java
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment_next
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment_preload
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment_preload_next
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_next
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java
View file @
7f49b33f
...
@@ -30,6 +30,7 @@ import com.google.android.exoplayer2.source.MediaLoadData;
...
@@ -30,6 +30,7 @@ import com.google.android.exoplayer2.source.MediaLoadData;
import
com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher
;
import
com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher
;
import
com.google.android.exoplayer2.source.hls.HlsDataSourceFactory
;
import
com.google.android.exoplayer2.source.hls.HlsDataSourceFactory
;
import
com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant
;
import
com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant
;
import
com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Part
;
import
com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment
;
import
com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.HttpDataSource
;
import
com.google.android.exoplayer2.upstream.HttpDataSource
;
...
@@ -40,6 +41,7 @@ import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
...
@@ -40,6 +41,7 @@ import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import
com.google.android.exoplayer2.upstream.ParsingLoadable
;
import
com.google.android.exoplayer2.upstream.ParsingLoadable
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.common.collect.Iterables
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashMap
;
...
@@ -465,6 +467,7 @@ public final class DefaultHlsPlaylistTracker
...
@@ -465,6 +467,7 @@ public final class DefaultHlsPlaylistTracker
private
final
class
MediaPlaylistBundle
implements
Loader
.
Callback
<
ParsingLoadable
<
HlsPlaylist
>>
{
private
final
class
MediaPlaylistBundle
implements
Loader
.
Callback
<
ParsingLoadable
<
HlsPlaylist
>>
{
private
static
final
String
BLOCK_MSN_PARAM
=
"_HLS_msn"
;
private
static
final
String
BLOCK_MSN_PARAM
=
"_HLS_msn"
;
private
static
final
String
BLOCK_PART_PARAM
=
"_HLS_part"
;
private
static
final
String
SKIP_PARAM
=
"_HLS_skip"
;
private
static
final
String
SKIP_PARAM
=
"_HLS_skip"
;
private
final
Uri
playlistUrl
;
private
final
Uri
playlistUrl
;
...
@@ -729,16 +732,25 @@ public final class DefaultHlsPlaylistTracker
...
@@ -729,16 +732,25 @@ public final class DefaultHlsPlaylistTracker
return
playlistUrl
;
return
playlistUrl
;
}
}
Uri
.
Builder
uriBuilder
=
playlistUrl
.
buildUpon
();
Uri
.
Builder
uriBuilder
=
playlistUrl
.
buildUpon
();
if
(
playlistSnapshot
.
serverControl
.
skipUntilUs
!=
C
.
TIME_UNSET
)
{
uriBuilder
.
appendQueryParameter
(
SKIP_PARAM
,
playlistSnapshot
.
serverControl
.
canSkipDateRanges
?
"v2"
:
"YES"
);
}
if
(
playlistSnapshot
.
serverControl
.
canBlockReload
)
{
if
(
playlistSnapshot
.
serverControl
.
canBlockReload
)
{
long
reload
MediaSequence
=
long
target
MediaSequence
=
playlistSnapshot
.
mediaSequence
playlistSnapshot
.
mediaSequence
+
playlistSnapshot
.
segments
.
size
()
+
playlistSnapshot
.
segments
.
size
()
+
playlistSnapshot
.
skippedSegmentCount
;
+
playlistSnapshot
.
skippedSegmentCount
;
uriBuilder
.
appendQueryParameter
(
BLOCK_MSN_PARAM
,
String
.
valueOf
(
reloadMediaSequence
));
uriBuilder
.
appendQueryParameter
(
BLOCK_MSN_PARAM
,
String
.
valueOf
(
targetMediaSequence
));
if
(
playlistSnapshot
.
partTargetDurationUs
!=
C
.
TIME_UNSET
)
{
List
<
Part
>
trailingParts
=
playlistSnapshot
.
trailingParts
;
int
targetPartIndex
=
trailingParts
.
size
();
if
(!
trailingParts
.
isEmpty
()
&&
Iterables
.
getLast
(
trailingParts
).
isPreload
)
{
// Ignore the preload part.
targetPartIndex
--;
}
uriBuilder
.
appendQueryParameter
(
BLOCK_PART_PARAM
,
String
.
valueOf
(
targetPartIndex
));
}
}
if
(
playlistSnapshot
.
serverControl
.
skipUntilUs
!=
C
.
TIME_UNSET
)
{
uriBuilder
.
appendQueryParameter
(
SKIP_PARAM
,
playlistSnapshot
.
serverControl
.
canSkipDateRanges
?
"v2"
:
"YES"
);
}
}
return
uriBuilder
.
build
();
return
uriBuilder
.
build
();
}
}
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylist.java
View file @
7f49b33f
...
@@ -176,6 +176,8 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
...
@@ -176,6 +176,8 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
/** Whether the part is independent. */
/** Whether the part is independent. */
public
final
boolean
isIndependent
;
public
final
boolean
isIndependent
;
/** Whether the part is a preloading part. */
public
final
boolean
isPreload
;
/**
/**
* Creates an instance.
* Creates an instance.
...
@@ -192,6 +194,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
...
@@ -192,6 +194,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
* @param byteRangeLength See {@link #byteRangeLength}.
* @param byteRangeLength See {@link #byteRangeLength}.
* @param hasGapTag See {@link #hasGapTag}.
* @param hasGapTag See {@link #hasGapTag}.
* @param isIndependent See {@link #isIndependent}.
* @param isIndependent See {@link #isIndependent}.
* @param isPreload See {@link #isPreload}.
*/
*/
public
Part
(
public
Part
(
String
url
,
String
url
,
...
@@ -205,7 +208,8 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
...
@@ -205,7 +208,8 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
long
byteRangeOffset
,
long
byteRangeOffset
,
long
byteRangeLength
,
long
byteRangeLength
,
boolean
hasGapTag
,
boolean
hasGapTag
,
boolean
isIndependent
)
{
boolean
isIndependent
,
boolean
isPreload
)
{
super
(
super
(
url
,
url
,
initializationSegment
,
initializationSegment
,
...
@@ -219,6 +223,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
...
@@ -219,6 +223,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
byteRangeLength
,
byteRangeLength
,
hasGapTag
);
hasGapTag
);
this
.
isIndependent
=
isIndependent
;
this
.
isIndependent
=
isIndependent
;
this
.
isPreload
=
isPreload
;
}
}
}
}
...
@@ -502,8 +507,13 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
...
@@ -502,8 +507,13 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
// The media sequences are equal.
// The media sequences are equal.
int
segmentCount
=
segments
.
size
()
+
skippedSegmentCount
;
int
segmentCount
=
segments
.
size
()
+
skippedSegmentCount
;
int
otherSegmentCount
=
other
.
segments
.
size
()
+
other
.
skippedSegmentCount
;
int
otherSegmentCount
=
other
.
segments
.
size
()
+
other
.
skippedSegmentCount
;
return
segmentCount
>
otherSegmentCount
if
(
segmentCount
!=
otherSegmentCount
)
{
||
(
segmentCount
==
otherSegmentCount
&&
hasEndTag
&&
!
other
.
hasEndTag
);
return
segmentCount
>
otherSegmentCount
;
}
int
partCount
=
trailingParts
.
size
();
int
otherPartCount
=
other
.
trailingParts
.
size
();
return
partCount
>
otherPartCount
||
(
partCount
==
otherPartCount
&&
hasEndTag
&&
!
other
.
hasEndTag
);
}
}
/**
/**
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java
View file @
7f49b33f
...
@@ -824,7 +824,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
...
@@ -824,7 +824,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
byteRangeStart
,
byteRangeStart
,
byteRangeLength
,
byteRangeLength
,
/* hasGapTag= */
false
,
/* hasGapTag= */
false
,
/* isIndependent= */
false
);
/* isIndependent= */
false
,
/* isPreload= */
true
);
}
else
if
(
line
.
startsWith
(
TAG_PART
))
{
}
else
if
(
line
.
startsWith
(
TAG_PART
))
{
@Nullable
@Nullable
String
segmentEncryptionIV
=
String
segmentEncryptionIV
=
...
@@ -869,7 +870,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
...
@@ -869,7 +870,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
partByteRangeOffset
,
partByteRangeOffset
,
partByteRangeLength
,
partByteRangeLength
,
isGap
,
isGap
,
isIndependent
));
isIndependent
,
/* isPreload= */
false
));
partStartTimeUs
+=
partDurationUs
;
partStartTimeUs
+=
partDurationUs
;
if
(
partByteRangeLength
!=
C
.
LENGTH_UNSET
)
{
if
(
partByteRangeLength
!=
C
.
LENGTH_UNSET
)
{
partByteRangeOffset
+=
partByteRangeLength
;
partByteRangeOffset
+=
partByteRangeLength
;
...
...
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTrackerTest.java
View file @
7f49b33f
...
@@ -64,6 +64,21 @@ public class DefaultHlsPlaylistTrackerTest {
...
@@ -64,6 +64,21 @@ public class DefaultHlsPlaylistTrackerTest {
"media/m3u8/live_low_latency_media_can_block_reload"
;
"media/m3u8/live_low_latency_media_can_block_reload"
;
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_NEXT
=
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_NEXT
=
"media/m3u8/live_low_latency_media_can_block_reload_next"
;
"media/m3u8/live_low_latency_media_can_block_reload_next"
;
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY
=
"media/m3u8/live_low_latency_media_can_block_reload_low_latency"
;
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_NEXT
=
"media/m3u8/live_low_latency_media_can_block_reload_low_latency_next"
;
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_FULL_SEGMENT
=
"media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment"
;
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_FULL_SEGMENT_NEXT
=
"media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment_next"
;
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_FULL_SEGMENT_PRELOAD
=
"media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment_preload"
;
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_FULL_SEGMENT_PRELOAD_NEXT
=
"media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment_preload_next"
;
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_SKIP_UNTIL_AND_BLOCK_RELOAD
=
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_SKIP_UNTIL_AND_BLOCK_RELOAD
=
"media/m3u8/live_low_latency_media_can_skip_until_and_block_reload"
;
"media/m3u8/live_low_latency_media_can_skip_until_and_block_reload"
;
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_SKIP_UNTIL_AND_BLOCK_RELOAD_NEXT
=
private
static
final
String
SAMPLE_M3U8_LIVE_MEDIA_CAN_SKIP_UNTIL_AND_BLOCK_RELOAD_NEXT
=
...
@@ -256,6 +271,96 @@ public class DefaultHlsPlaylistTrackerTest {
...
@@ -256,6 +271,96 @@ public class DefaultHlsPlaylistTrackerTest {
}
}
@Test
@Test
public
void
start_playlistCanBlockReloadLowLatency_requestBlockingReloadWithCorrectMediaSequenceAndPart
()
throws
IOException
,
TimeoutException
,
InterruptedException
{
List
<
HttpUrl
>
httpUrls
=
enqueueWebServerResponses
(
new
String
[]
{
"/master.m3u8"
,
"/media0/playlist.m3u8"
,
"/media0/playlist.m3u8?_HLS_msn=14&_HLS_part=1"
},
getMockResponse
(
SAMPLE_M3U8_LIVE_MASTER
),
getMockResponse
(
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY
),
getMockResponse
(
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_NEXT
));
List
<
HlsMediaPlaylist
>
mediaPlaylists
=
runPlaylistTrackerAndCollectMediaPlaylists
(
new
DefaultHttpDataSourceFactory
(),
Uri
.
parse
(
mockWebServer
.
url
(
"/master.m3u8"
).
toString
()),
/* awaitedMediaPlaylistCount= */
2
);
assertRequestUrlsCalled
(
httpUrls
);
assertThat
(
mediaPlaylists
.
get
(
0
).
mediaSequence
).
isEqualTo
(
10
);
assertThat
(
mediaPlaylists
.
get
(
0
).
segments
).
hasSize
(
4
);
assertThat
(
mediaPlaylists
.
get
(
0
).
trailingParts
).
hasSize
(
2
);
assertThat
(
mediaPlaylists
.
get
(
1
).
mediaSequence
).
isEqualTo
(
10
);
assertThat
(
mediaPlaylists
.
get
(
1
).
segments
).
hasSize
(
4
);
assertThat
(
mediaPlaylists
.
get
(
1
).
trailingParts
).
hasSize
(
3
);
}
@Test
public
void
start_playlistCanBlockReloadLowLatencyFullSegment_correctMsnAndPartParams
()
throws
IOException
,
TimeoutException
,
InterruptedException
{
List
<
HttpUrl
>
httpUrls
=
enqueueWebServerResponses
(
new
String
[]
{
"/master.m3u8"
,
"/media0/playlist.m3u8"
,
"/media0/playlist.m3u8?_HLS_msn=14&_HLS_part=0"
},
getMockResponse
(
SAMPLE_M3U8_LIVE_MASTER
),
getMockResponse
(
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_FULL_SEGMENT
),
getMockResponse
(
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_FULL_SEGMENT_NEXT
));
List
<
HlsMediaPlaylist
>
mediaPlaylists
=
runPlaylistTrackerAndCollectMediaPlaylists
(
new
DefaultHttpDataSourceFactory
(),
Uri
.
parse
(
mockWebServer
.
url
(
"/master.m3u8"
).
toString
()),
/* awaitedMediaPlaylistCount= */
2
);
assertRequestUrlsCalled
(
httpUrls
);
assertThat
(
mediaPlaylists
.
get
(
0
).
mediaSequence
).
isEqualTo
(
10
);
assertThat
(
mediaPlaylists
.
get
(
0
).
segments
).
hasSize
(
4
);
assertThat
(
mediaPlaylists
.
get
(
0
).
trailingParts
).
isEmpty
();
assertThat
(
mediaPlaylists
.
get
(
1
).
mediaSequence
).
isEqualTo
(
10
);
assertThat
(
mediaPlaylists
.
get
(
1
).
segments
).
hasSize
(
4
);
assertThat
(
mediaPlaylists
.
get
(
1
).
trailingParts
).
hasSize
(
1
);
}
@Test
public
void
start_playlistCanBlockReloadLowLatencyFullSegmentWithPreloadPart_ignoresPreloadPart
()
throws
IOException
,
TimeoutException
,
InterruptedException
{
List
<
HttpUrl
>
httpUrls
=
enqueueWebServerResponses
(
new
String
[]
{
"/master.m3u8"
,
"/media0/playlist.m3u8"
,
"/media0/playlist.m3u8?_HLS_msn=14&_HLS_part=0"
},
getMockResponse
(
SAMPLE_M3U8_LIVE_MASTER
),
getMockResponse
(
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_FULL_SEGMENT_PRELOAD
),
getMockResponse
(
SAMPLE_M3U8_LIVE_MEDIA_CAN_BLOCK_RELOAD_LOW_LATENCY_FULL_SEGMENT_PRELOAD_NEXT
));
List
<
HlsMediaPlaylist
>
mediaPlaylists
=
runPlaylistTrackerAndCollectMediaPlaylists
(
new
DefaultHttpDataSourceFactory
(),
Uri
.
parse
(
mockWebServer
.
url
(
"/master.m3u8"
).
toString
()),
/* awaitedMediaPlaylistCount= */
2
);
assertRequestUrlsCalled
(
httpUrls
);
assertThat
(
mediaPlaylists
.
get
(
0
).
mediaSequence
).
isEqualTo
(
10
);
assertThat
(
mediaPlaylists
.
get
(
0
).
segments
).
hasSize
(
4
);
assertThat
(
mediaPlaylists
.
get
(
0
).
trailingParts
).
hasSize
(
1
);
assertThat
(
mediaPlaylists
.
get
(
1
).
mediaSequence
).
isEqualTo
(
10
);
assertThat
(
mediaPlaylists
.
get
(
1
).
segments
).
hasSize
(
4
);
assertThat
(
mediaPlaylists
.
get
(
1
).
trailingParts
).
hasSize
(
2
);
}
@Test
public
void
start_httpBadRequest_forcesFullNonBlockingPlaylistRequest
()
public
void
start_httpBadRequest_forcesFullNonBlockingPlaylistRequest
()
throws
IOException
,
TimeoutException
,
InterruptedException
{
throws
IOException
,
TimeoutException
,
InterruptedException
{
List
<
HttpUrl
>
httpUrls
=
List
<
HttpUrl
>
httpUrls
=
...
@@ -263,9 +368,9 @@ public class DefaultHlsPlaylistTrackerTest {
...
@@ -263,9 +368,9 @@ public class DefaultHlsPlaylistTrackerTest {
new
String
[]
{
new
String
[]
{
"/master.m3u8"
,
"/master.m3u8"
,
"/media0/playlist.m3u8"
,
"/media0/playlist.m3u8"
,
"/media0/playlist.m3u8?_HLS_
skip=YES&_HLS_msn=16
"
,
"/media0/playlist.m3u8?_HLS_
msn=16&_HLS_skip=YES
"
,
"/media0/playlist.m3u8"
,
"/media0/playlist.m3u8"
,
"/media0/playlist.m3u8?_HLS_
skip=YES&_HLS_msn=17
"
"/media0/playlist.m3u8?_HLS_
msn=17&_HLS_skip=YES
"
},
},
getMockResponse
(
SAMPLE_M3U8_LIVE_MASTER
),
getMockResponse
(
SAMPLE_M3U8_LIVE_MASTER
),
getMockResponse
(
SAMPLE_M3U8_LIVE_MEDIA_CAN_SKIP_UNTIL_AND_BLOCK_RELOAD
),
getMockResponse
(
SAMPLE_M3U8_LIVE_MEDIA_CAN_SKIP_UNTIL_AND_BLOCK_RELOAD
),
...
...
library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylistParserTest.java
View file @
7f49b33f
...
@@ -354,6 +354,7 @@ public class HlsMediaPlaylistParserTest {
...
@@ -354,6 +354,7 @@ public class HlsMediaPlaylistParserTest {
assertThat
(
firstPart
.
durationUs
).
isEqualTo
(
2_000_000
);
assertThat
(
firstPart
.
durationUs
).
isEqualTo
(
2_000_000
);
assertThat
(
firstPart
.
relativeStartTimeUs
).
isEqualTo
(
playlist
.
segments
.
get
(
0
).
durationUs
);
assertThat
(
firstPart
.
relativeStartTimeUs
).
isEqualTo
(
playlist
.
segments
.
get
(
0
).
durationUs
);
assertThat
(
firstPart
.
isIndependent
).
isTrue
();
assertThat
(
firstPart
.
isIndependent
).
isTrue
();
assertThat
(
firstPart
.
isPreload
).
isFalse
();
assertThat
(
firstPart
.
hasGapTag
).
isTrue
();
assertThat
(
firstPart
.
hasGapTag
).
isTrue
();
assertThat
(
firstPart
.
url
).
isEqualTo
(
"part267.1.ts"
);
assertThat
(
firstPart
.
url
).
isEqualTo
(
"part267.1.ts"
);
HlsMediaPlaylist
.
Part
secondPart
=
playlist
.
segments
.
get
(
1
).
parts
.
get
(
1
);
HlsMediaPlaylist
.
Part
secondPart
=
playlist
.
segments
.
get
(
1
).
parts
.
get
(
1
);
...
@@ -518,6 +519,7 @@ public class HlsMediaPlaylistParserTest {
...
@@ -518,6 +519,7 @@ public class HlsMediaPlaylistParserTest {
assertThat
(
preloadPart
.
byteRangeOffset
).
isEqualTo
(
1234
);
assertThat
(
preloadPart
.
byteRangeOffset
).
isEqualTo
(
1234
);
assertThat
(
preloadPart
.
initializationSegment
.
url
).
isEqualTo
(
"map.mp4"
);
assertThat
(
preloadPart
.
initializationSegment
.
url
).
isEqualTo
(
"map.mp4"
);
assertThat
(
preloadPart
.
encryptionIV
).
isEqualTo
(
"0x410C8AC18AA42EFA18B5155484F5FC34"
);
assertThat
(
preloadPart
.
encryptionIV
).
isEqualTo
(
"0x410C8AC18AA42EFA18B5155484F5FC34"
);
assertThat
(
preloadPart
.
isPreload
).
isTrue
();
}
}
@Test
@Test
...
@@ -539,6 +541,7 @@ public class HlsMediaPlaylistParserTest {
...
@@ -539,6 +541,7 @@ public class HlsMediaPlaylistParserTest {
assertThat
(
playlist
.
trailingParts
).
hasSize
(
2
);
assertThat
(
playlist
.
trailingParts
).
hasSize
(
2
);
assertThat
(
playlist
.
trailingParts
.
get
(
1
).
url
).
isEqualTo
(
"filePart267.2.ts"
);
assertThat
(
playlist
.
trailingParts
.
get
(
1
).
url
).
isEqualTo
(
"filePart267.2.ts"
);
assertThat
(
playlist
.
trailingParts
.
get
(
1
).
isPreload
).
isTrue
();
}
}
@Test
@Test
...
...
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency
0 → 100644
View file @
7f49b33f
#EXTM3U
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES
#EXT-X-TARGETDURATION:4
#EXT-X-PART-INF:PART-TARGET=1.000000
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:10
#EXTINF:4.00000,
fileSequence10.ts
#EXTINF:4.00000,
fileSequence11.ts
#EXTINF:4.00000,
fileSequence12.ts
#EXTINF:4.00000,
fileSequence13.ts
#EXT-X-PART:DURATION=1.00000,URI="fileSequence14.0.ts"
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="fileSequence14.1.ts"
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment
0 → 100644
View file @
7f49b33f
#EXTM3U
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES
#EXT-X-TARGETDURATION:4
#EXT-X-PART-INF:PART-TARGET=1.000000
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:10
#EXTINF:4.00000,
fileSequence10.ts
#EXTINF:4.00000,
fileSequence11.ts
#EXTINF:4.00000,
fileSequence12.ts
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.0.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.1.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.2.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.3.ts"
#EXTINF:4.00000,
fileSequence13.ts
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment_next
0 → 100644
View file @
7f49b33f
#EXTM3U
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES
#EXT-X-TARGETDURATION:4
#EXT-X-PART-INF:PART-TARGET=1.000000
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:10
#EXTINF:4.00000,
fileSequence10.ts
#EXTINF:4.00000,
fileSequence11.ts
#EXTINF:4.00000,
fileSequence12.ts
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.0.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.1.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.2.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.3.ts"
#EXTINF:4.00000,
fileSequence13.ts
#EXT-X-PART:DURATION=1.00000,URI="fileSequence14.0.ts"
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment_preload
0 → 100644
View file @
7f49b33f
#EXTM3U
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES
#EXT-X-TARGETDURATION:4
#EXT-X-PART-INF:PART-TARGET=1.000000
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:10
#EXTINF:4.00000,
fileSequence10.ts
#EXTINF:4.00000,
fileSequence11.ts
#EXTINF:4.00000,
fileSequence12.ts
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.0.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.1.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.2.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.3.ts"
#EXTINF:4.00000,
fileSequence13.ts
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="fileSequence14.0.ts"
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_full_segment_preload_next
0 → 100644
View file @
7f49b33f
#EXTM3U
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES
#EXT-X-TARGETDURATION:4
#EXT-X-PART-INF:PART-TARGET=1.000000
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:10
#EXTINF:4.00000,
fileSequence10.ts
#EXTINF:4.00000,
fileSequence11.ts
#EXTINF:4.00000,
fileSequence12.ts
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.0.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.1.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.2.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence13.3.ts"
#EXTINF:4.00000,
fileSequence13.ts
#EXT-X-PART:DURATION=1.00000,URI="fileSequence14.0.ts"
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="fileSequence14.1.ts"
testdata/src/test/assets/media/m3u8/live_low_latency_media_can_block_reload_low_latency_next
0 → 100644
View file @
7f49b33f
#EXTM3U
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES
#EXT-X-TARGETDURATION:4
#EXT-X-PART-INF:PART-TARGET=1.000000
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:10
#EXTINF:4.00000,
fileSequence10.ts
#EXTINF:4.00000,
fileSequence11.ts
#EXTINF:4.00000,
fileSequence12.ts
#EXTINF:4.00000,
fileSequence13.ts
#EXT-X-PART:DURATION=1.00000,URI="fileSequence14.0.ts"
#EXT-X-PART:DURATION=1.00000,URI="fileSequence14.1.ts"
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="fileSequence14.2.ts"
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