Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
brainfood
/
videojs-contrib-hls
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
b0fe8348
authored
2016-05-31 12:04:16 -0400
by
jrivera
Browse Files
Options
Browse Files
Tag
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
2 parents
9ee2a7db
e45497bc
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
301 additions
and
17 deletions
src/master-playlist-controller.js
src/ranges.js
src/segment-loader.js
src/videojs-contrib-hls.js
test/master-playlist-controller.test.js
test/ranges.test.js
test/segment-loader.test.js
test/videojs-contrib-hls.test.js
src/master-playlist-controller.js
View file @
b0fe834
...
...
@@ -170,6 +170,40 @@ export default class MasterPlaylistController extends videojs.EventTarget {
}
/**
* get the total number of media requests from the `audiosegmentloader_`
* and the `mainSegmentLoader_`
*
* @private
*/
mediaRequests_
()
{
return
this
.
audioSegmentLoader_
.
mediaRequests
+
this
.
mainSegmentLoader_
.
mediaRequests
;
}
/**
* get the total time that media requests have spent trnasfering
* from the `audiosegmentloader_` and the `mainSegmentLoader_`
*
* @private
*/
mediaTransferDuration_
()
{
return
this
.
audioSegmentLoader_
.
mediaTransferDuration
+
this
.
mainSegmentLoader_
.
mediaTransferDuration
;
}
/**
* get the total number of bytes transfered during media requests
* from the `audiosegmentloader_` and the `mainSegmentLoader_`
*
* @private
*/
mediaBytesTransferred_
()
{
return
this
.
audioSegmentLoader_
.
mediaBytesTransferred
+
this
.
mainSegmentLoader_
.
mediaBytesTransferred
;
}
/**
* fill our internal list of HlsAudioTracks with data from
* the master playlist or use a default
*
...
...
@@ -350,7 +384,8 @@ export default class MasterPlaylistController extends videojs.EventTarget {
if
(
media
!==
this
.
masterPlaylistLoader_
.
media
())
{
this
.
masterPlaylistLoader_
.
media
(
media
);
this
.
mainSegmentLoader_
.
sourceUpdater_
.
remove
(
this
.
tech_
.
currentTime
()
+
5
,
Infinity
);
this
.
mainSegmentLoader_
.
sourceUpdater_
.
remove
(
this
.
tech_
.
currentTime
()
+
5
,
Infinity
);
}
}
...
...
src/ranges.js
View file @
b0fe834
...
...
@@ -198,27 +198,58 @@ const bufferIntersection = function(bufferA, bufferB) {
* covers adjusted according to currentTime
* @param {TimeRanges} referenceRange - the original time range that the
* segment covers
* @param {Number} currentTime - time in seconds where the current playback
* is at
* @param {TimeRanges} buffered - the currently buffered time ranges
* @returns {Number} percent of the segment currently buffered
*/
const
calculateBufferedPercent
=
function
(
segmentRange
,
referenceRange
,
buffered
)
{
const
calculateBufferedPercent
=
function
(
adjustedRange
,
referenceRange
,
currentTime
,
buffered
)
{
let
referenceDuration
=
referenceRange
.
end
(
0
)
-
referenceRange
.
start
(
0
);
let
segmentDuration
=
segmentRange
.
end
(
0
)
-
segmentRange
.
start
(
0
);
let
intersection
=
bufferIntersection
(
segmentRange
,
buffered
);
let
count
=
intersection
.
length
;
let
adjustedDuration
=
adjustedRange
.
end
(
0
)
-
adjustedRange
.
start
(
0
);
let
bufferMissingFromAdjusted
=
referenceDuration
-
adjustedDuration
;
let
adjustedIntersection
=
bufferIntersection
(
adjustedRange
,
buffered
);
let
referenceIntersection
=
bufferIntersection
(
referenceRange
,
buffered
);
let
adjustedOverlap
=
0
;
let
referenceOverlap
=
0
;
let
count
=
adjustedIntersection
.
length
;
while
(
count
--
)
{
segmentDuration
-=
intersection
.
end
(
count
)
-
intersection
.
start
(
count
);
adjustedOverlap
+=
adjustedIntersection
.
end
(
count
)
-
adjustedIntersection
.
start
(
count
);
// If the current overlap segment starts at currentTime, then increase the
// overlap duration so that it actually starts at the beginning of referenceRange
// by including the difference between the two Range's durations
// This is a work around for the way Flash has no buffer before currentTime
if
(
adjustedIntersection
.
start
(
count
)
===
currentTime
)
{
adjustedOverlap
+=
bufferMissingFromAdjusted
;
}
}
return
(
referenceDuration
-
segmentDuration
)
/
referenceDuration
*
100
;
count
=
referenceIntersection
.
length
;
while
(
count
--
)
{
referenceOverlap
+=
referenceIntersection
.
end
(
count
)
-
referenceIntersection
.
start
(
count
);
}
// Use whichever value is larger for the percentage-buffered since that value
// is likely more accurate because the only way
return
Math
.
max
(
adjustedOverlap
,
referenceOverlap
)
/
referenceDuration
*
100
;
};
/**
* Return the amount of a
segment specified by the mediaIndex overlaps
* the current buffered content.
* Return the amount of a
range specified by the startOfSegment and segmentDuration
*
overlaps
the current buffered content.
*
* @param {Number} startOfSegment - the time where the segment begins
* @param {Number} segmentDuration - the duration of the segment in seconds
* @param {Number} currentTime - time in seconds where the current playback
* is at
* @param {TimeRanges} buffered - the state of the buffer
* @returns {Number} percentage of the segment's time range that is
* already in `buffered`
...
...
@@ -254,6 +285,7 @@ const getSegmentBufferedPercent = function(startOfSegment,
let
percent
=
calculateBufferedPercent
(
adjustedSegmentRange
,
originalSegmentRange
,
currentTime
,
buffered
);
// If the segment is reported as having a zero duration, return 0%
...
...
src/segment-loader.js
View file @
b0fe834
...
...
@@ -131,7 +131,7 @@ export default class SegmentLoader extends videojs.EventTarget {
this
.
state
=
'INIT'
;
this
.
bandwidth
=
settings
.
bandwidth
;
this
.
roundTrip
=
NaN
;
this
.
bytesReceived
=
0
;
this
.
resetStats_
()
;
// private properties
this
.
hasPlayed_
=
settings
.
hasPlayed
;
...
...
@@ -153,6 +153,17 @@ export default class SegmentLoader extends videojs.EventTarget {
}
/**
* reset all of our media stats
*
* @private
*/
resetStats_
()
{
this
.
mediaBytesTransferred
=
0
;
this
.
mediaRequests
=
0
;
this
.
mediaTransferDuration
=
0
;
}
/**
* dispose of the SegmentLoader and reset to the default state
*/
dispose
()
{
...
...
@@ -161,6 +172,7 @@ export default class SegmentLoader extends videojs.EventTarget {
if
(
this
.
sourceUpdater_
)
{
this
.
sourceUpdater_
.
dispose
();
}
this
.
resetStats_
();
}
/**
...
...
@@ -625,7 +637,9 @@ export default class SegmentLoader extends videojs.EventTarget {
// calculate the download bandwidth based on segment request
this
.
roundTrip
=
request
.
roundTripTime
;
this
.
bandwidth
=
request
.
bandwidth
;
this
.
bytesReceived
+=
request
.
bytesReceived
||
0
;
this
.
mediaBytesTransferred
+=
request
.
bytesReceived
||
0
;
this
.
mediaRequests
+=
1
;
this
.
mediaTransferDuration
+=
request
.
roundTripTime
||
0
;
if
(
segment
.
key
)
{
segmentInfo
.
encryptedBytes
=
new
Uint8Array
(
request
.
response
);
...
...
src/videojs-contrib-hls.js
View file @
b0fe834
...
...
@@ -301,12 +301,16 @@ class HlsHandler extends Component {
this
.
tech_
=
tech
;
this
.
source_
=
source
;
this
.
stats
=
{};
// handle global & Source Handler level options
this
.
options_
=
videojs
.
mergeOptions
(
videojs
.
options
.
hls
||
{},
options
.
hls
);
this
.
setOptions_
();
this
.
bytesReceived
=
0
;
// start playlist selection at a reasonable bandwidth for
// broadband internet
// 0.5 Mbps
this
.
bandwidth
=
this
.
options_
.
bandwidth
||
4194304
;
// listen for fullscreenchange events for this player so that we
// can adjust our quality selection quickly
...
...
@@ -406,6 +410,19 @@ class HlsHandler extends Component {
}
});
Object
.
defineProperty
(
this
.
stats
,
'bandwidth'
,
{
get
:
()
=>
this
.
bandwidth
||
0
});
Object
.
defineProperty
(
this
.
stats
,
'mediaRequests'
,
{
get
:
()
=>
this
.
masterPlaylistController_
.
mediaRequests_
()
||
0
});
Object
.
defineProperty
(
this
.
stats
,
'mediaTransferDuration'
,
{
get
:
()
=>
this
.
masterPlaylistController_
.
mediaTransferDuration_
()
||
0
});
Object
.
defineProperty
(
this
.
stats
,
'mediaBytesTransferred'
,
{
get
:
()
=>
this
.
masterPlaylistController_
.
mediaBytesTransferred_
()
||
0
});
this
.
tech_
.
one
(
'canplay'
,
this
.
masterPlaylistController_
.
setupFirstPlay
.
bind
(
this
.
masterPlaylistController_
));
...
...
@@ -527,7 +544,6 @@ class HlsHandler extends Component {
this
.
masterPlaylistController_
.
dispose
();
}
this
.
tech_
.
audioTracks
().
removeEventListener
(
'change'
,
this
.
audioTrackChange_
);
super
.
dispose
();
}
}
...
...
test/master-playlist-controller.test.js
View file @
b0fe834
...
...
@@ -64,6 +64,9 @@ QUnit.test('obeys none preload option', function() {
openMediaSource
(
this
.
player
,
this
.
clock
);
QUnit
.
equal
(
this
.
requests
.
length
,
0
,
'no segment requests'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default bandwidth'
);
});
QUnit
.
test
(
'obeys auto preload option'
,
function
()
{
...
...
@@ -76,6 +79,9 @@ QUnit.test('obeys auto preload option', function() {
openMediaSource
(
this
.
player
,
this
.
clock
);
QUnit
.
equal
(
this
.
requests
.
length
,
1
,
'1 segment request'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default bandwidth'
);
});
QUnit
.
test
(
'obeys metadata preload option'
,
function
()
{
...
...
@@ -88,6 +94,9 @@ QUnit.test('obeys metadata preload option', function() {
openMediaSource
(
this
.
player
,
this
.
clock
);
QUnit
.
equal
(
this
.
requests
.
length
,
1
,
'1 segment request'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default bandwidth'
);
});
QUnit
.
test
(
'clears some of the buffer for a fast quality change'
,
function
()
{
...
...
@@ -114,6 +123,9 @@ QUnit.test('clears some of the buffer for a fast quality change', function() {
QUnit
.
equal
(
removes
.
length
,
1
,
'removed buffered content'
);
QUnit
.
equal
(
removes
[
0
].
start
,
7
+
5
,
'removed from a bit after current time'
);
QUnit
.
equal
(
removes
[
0
].
end
,
Infinity
,
'removed to the end'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default bandwidth'
);
});
QUnit
.
test
(
'does not clear the buffer when no fast quality change occurs'
,
function
()
{
...
...
@@ -134,6 +146,8 @@ QUnit.test('does not clear the buffer when no fast quality change occurs', funct
this
.
masterPlaylistController
.
fastQualityChange_
();
QUnit
.
equal
(
removes
.
length
,
0
,
'did not remove content'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default bandwidth'
);
});
QUnit
.
test
(
'if buffered, will request second segment byte range'
,
function
()
{
...
...
@@ -163,6 +177,13 @@ QUnit.test('if buffered, will request second segment byte range', function() {
this
.
masterPlaylistController
.
mediaSource
.
sourceBuffers
[
0
].
trigger
(
'updateend'
);
this
.
clock
.
tick
(
10
*
1000
);
QUnit
.
equal
(
this
.
requests
[
2
].
headers
.
Range
,
'bytes=1823412-2299991'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
Infinity
,
'Live stream'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 segment request'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes downloaded'
);
});
QUnit
.
test
(
're-initializes the combined playlist loader when switching sources'
,
...
...
@@ -218,6 +239,8 @@ QUnit.test('updates the combined segment loader on live playlist refreshes', fun
this
.
masterPlaylistController
.
masterPlaylistLoader_
.
trigger
(
'loadedplaylist'
);
QUnit
.
equal
(
updates
.
length
,
1
,
'updated the segment list'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default bandwidth'
);
});
QUnit
.
test
(
...
...
@@ -240,6 +263,13 @@ function() {
standardXHRResponse
(
this
.
requests
.
shift
());
this
.
masterPlaylistController
.
mainSegmentLoader_
.
trigger
(
'progress'
);
QUnit
.
equal
(
progressCount
,
1
,
'fired a progress event'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
Infinity
,
'Live stream'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 segment request'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes downloaded'
);
});
QUnit
.
test
(
'blacklists switching from video+audio playlists to audio only'
,
function
()
{
...
...
@@ -264,6 +294,9 @@ QUnit.test('blacklists switching from video+audio playlists to audio only', func
'selected video+audio'
);
audioPlaylist
=
this
.
masterPlaylistController
.
masterPlaylistLoader_
.
master
.
playlists
[
0
];
QUnit
.
equal
(
audioPlaylist
.
excludeUntil
,
Infinity
,
'excluded incompatible playlist'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
e10
,
'bandwidth we set above'
);
});
QUnit
.
test
(
'blacklists switching from audio-only playlists to video+audio'
,
function
()
{
...
...
@@ -290,6 +323,9 @@ QUnit.test('blacklists switching from audio-only playlists to video+audio', func
QUnit
.
equal
(
videoAudioPlaylist
.
excludeUntil
,
Infinity
,
'excluded incompatible playlist'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
,
'bandwidth we set above'
);
});
QUnit
.
test
(
'blacklists switching from video-only playlists to video+audio'
,
function
()
{
...
...
@@ -317,6 +353,9 @@ QUnit.test('blacklists switching from video-only playlists to video+audio', func
QUnit
.
equal
(
videoAudioPlaylist
.
excludeUntil
,
Infinity
,
'excluded incompatible playlist'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
,
'bandwidth we set above'
);
});
QUnit
.
test
(
'blacklists switching between playlists with incompatible audio codecs'
,
...
...
@@ -343,6 +382,8 @@ function() {
alternatePlaylist
=
this
.
masterPlaylistController
.
masterPlaylistLoader_
.
master
.
playlists
[
1
];
QUnit
.
equal
(
alternatePlaylist
.
excludeUntil
,
Infinity
,
'excluded incompatible playlist'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
,
'bandwidth we set above'
);
});
QUnit
.
test
(
'updates the combined segment loader on media changes'
,
function
()
{
...
...
@@ -369,6 +410,14 @@ QUnit.test('updates the combined segment loader on media changes', function() {
// media
standardXHRResponse
(
this
.
requests
.
shift
());
QUnit
.
equal
(
updates
.
length
,
1
,
'updated the segment list'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
Infinity
,
'Live stream'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 segment request'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes downloaded'
);
});
QUnit
.
test
(
'selects a playlist after main/combined segment downloads'
,
function
()
{
...
...
@@ -392,6 +441,8 @@ QUnit.test('selects a playlist after main/combined segment downloads', function(
// and another
this
.
masterPlaylistController
.
mainSegmentLoader_
.
trigger
(
'progress'
);
QUnit
.
strictEqual
(
calls
,
3
,
'selects after additional segments'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default bandwidth'
);
});
QUnit
.
test
(
'updates the duration after switching playlists'
,
function
()
{
...
...
@@ -424,6 +475,13 @@ QUnit.test('updates the duration after switching playlists', function() {
QUnit
.
ok
(
selectedPlaylist
,
'selected playlist'
);
QUnit
.
ok
(
this
.
masterPlaylistController
.
mediaSource
.
duration
!==
0
,
'updates the duration'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
Infinity
,
'Live stream'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 segment request'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes downloaded'
);
});
QUnit
.
test
(
'seekable uses the intersection of alternate audio and combined tracks'
,
...
...
test/ranges.test.js
View file @
b0fe834
...
...
@@ -94,7 +94,7 @@ QUnit.test('detects time range end-point changed by updates', function() {
QUnit
.
module
(
'Segment Percent Buffered Calculations'
);
QUnit
.
test
(
'calculates the percent buffered for segments'
,
function
()
{
QUnit
.
test
(
'calculates the percent buffered for segments
in the simple case
'
,
function
()
{
let
segmentStart
=
10
;
let
segmentDuration
=
10
;
let
currentTime
=
0
;
...
...
@@ -108,8 +108,8 @@ QUnit.test('calculates the percent buffered for segments', function() {
QUnit
.
equal
(
percentBuffered
,
40
,
'calculated the buffered amount correctly'
);
});
QUnit
.
test
(
'c
alculates the percent buffered for segments taking into accoun
t '
+
'currentTime'
,
function
()
{
QUnit
.
test
(
'c
onsider the buffer before currentTime to be filled if the segement begins a
t '
+
'
or before the
currentTime'
,
function
()
{
let
segmentStart
=
10
;
let
segmentDuration
=
10
;
let
currentTime
=
15
;
...
...
@@ -123,6 +123,21 @@ QUnit.test('calculates the percent buffered for segments taking into account ' +
QUnit
.
equal
(
percentBuffered
,
90
,
'calculated the buffered amount correctly'
);
});
QUnit
.
test
(
'does not consider the buffer before currentTime as filled if the segment '
+
'begins after the currentTime'
,
function
()
{
let
segmentStart
=
10
;
let
segmentDuration
=
10
;
let
currentTime
=
18
;
let
buffered
=
createTimeRanges
([[
19
,
30
]]);
let
percentBuffered
=
Ranges
.
getSegmentBufferedPercent
(
segmentStart
,
segmentDuration
,
currentTime
,
buffered
);
QUnit
.
equal
(
percentBuffered
,
10
,
'calculated the buffered amount correctly'
);
});
QUnit
.
test
(
'calculates the percent buffered for segments with multiple buffered '
+
'regions'
,
function
()
{
let
segmentStart
=
10
;
...
...
@@ -166,3 +181,32 @@ QUnit.test('calculates the percent buffered as 0 for zero-length segments', func
QUnit
.
equal
(
percentBuffered
,
0
,
'calculated the buffered amount correctly'
);
});
QUnit
.
test
(
'calculates the percent buffered as 0 for segments that do not overlap '
+
'buffered regions taking into account currentTime'
,
function
()
{
let
segmentStart
=
10
;
let
segmentDuration
=
10
;
let
currentTime
=
19
;
let
buffered
=
createTimeRanges
([[
20
,
30
]]);
let
percentBuffered
=
Ranges
.
getSegmentBufferedPercent
(
segmentStart
,
segmentDuration
,
currentTime
,
buffered
);
QUnit
.
equal
(
percentBuffered
,
0
,
'calculated the buffered amount correctly'
);
});
QUnit
.
test
(
'calculates the percent buffered for segments that end before currentTime'
,
function
()
{
let
segmentStart
=
10
;
let
segmentDuration
=
10
;
let
currentTime
=
19.6
;
let
buffered
=
createTimeRanges
([[
0
,
19.5
]]);
let
percentBuffered
=
Ranges
.
getSegmentBufferedPercent
(
segmentStart
,
segmentDuration
,
currentTime
,
buffered
);
QUnit
.
equal
(
percentBuffered
,
95
,
'calculated the buffered amount correctly'
);
});
...
...
test/segment-loader.test.js
View file @
b0fe834
...
...
@@ -105,6 +105,11 @@ QUnit.test('calling load is idempotent', function() {
this
.
requests
.
shift
().
respond
(
200
,
null
,
''
);
loader
.
load
();
QUnit
.
equal
(
this
.
requests
.
length
,
0
,
'load has no effect'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaTransferDuration
,
100
,
'100 ms (clock above)'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'calling load should unpause'
,
function
()
{
...
...
@@ -135,6 +140,11 @@ QUnit.test('calling load should unpause', function() {
loader
.
load
();
QUnit
.
equal
(
loader
.
paused
(),
false
,
'unpaused'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaTransferDuration
,
1
,
'1 ms (clock above)'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'regularly checks the buffer while unpaused'
,
function
()
{
...
...
@@ -159,6 +169,11 @@ QUnit.test('regularly checks the buffer while unpaused', function() {
currentTime
=
Config
.
GOAL_BUFFER_LENGTH
;
this
.
clock
.
tick
(
10
*
1000
);
QUnit
.
equal
(
this
.
requests
.
length
,
1
,
'requested another segment'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaTransferDuration
,
1
,
'1 ms (clock above)'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'does not check the buffer while paused'
,
function
()
{
...
...
@@ -177,6 +192,11 @@ QUnit.test('does not check the buffer while paused', function() {
this
.
clock
.
tick
(
10
*
1000
);
QUnit
.
equal
(
this
.
requests
.
length
,
0
,
'did not make a request'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaTransferDuration
,
1
,
'1 ms (clock above)'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'calculates bandwidth after downloading a segment'
,
function
()
{
...
...
@@ -191,7 +211,12 @@ QUnit.test('calculates bandwidth after downloading a segment', function() {
QUnit
.
equal
(
loader
.
bandwidth
,
(
10
/
100
)
*
8
*
1000
,
'calculated bandwidth'
);
QUnit
.
equal
(
loader
.
roundTrip
,
100
,
'saves request round trip time'
);
QUnit
.
equal
(
loader
.
bytesReceived
,
10
,
'saves bytes received'
);
// TODO: Bandwidth Stat will be stale??
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaTransferDuration
,
100
,
'100 ms (clock above)'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'segment request timeouts reset bandwidth'
,
function
()
{
...
...
@@ -223,6 +248,10 @@ QUnit.test('appending a segment triggers progress', function() {
mediaSource
.
sourceBuffers
[
0
].
trigger
(
'updateend'
);
QUnit
.
equal
(
progresses
,
1
,
'fired progress'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'only requests one segment at a time'
,
function
()
{
...
...
@@ -251,6 +280,11 @@ QUnit.test('only appends one segment at a time', function() {
QUnit
.
equal
(
mediaSource
.
sourceBuffers
[
0
].
updates_
.
filter
(
update
=>
update
.
append
).
length
,
1
,
'only one append'
);
QUnit
.
equal
(
this
.
requests
.
length
,
0
,
'only made one request'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaTransferDuration
,
100
,
'100 ms (clock above)'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'adjusts the playlist offset if no buffering progress is made'
,
function
()
{
...
...
@@ -288,6 +322,11 @@ QUnit.test('adjusts the playlist offset if no buffering progress is made', funct
// so the loader should try the next segment
QUnit
.
equal
(
this
.
requests
[
0
].
url
,
'1.ts'
,
'moved ahead a segment'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
20
,
'20 bytes'
);
QUnit
.
equal
(
loader
.
mediaTransferDuration
,
2
,
'2 ms (clocks above)'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
2
,
'2 requests'
);
});
QUnit
.
test
(
'never attempt to load a segment that '
+
...
...
@@ -319,6 +358,11 @@ QUnit.test('never attempt to load a segment that ' +
// the loader should move on to the next segment
QUnit
.
equal
(
this
.
requests
[
0
].
url
,
'1.ts'
,
'moved ahead a segment'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaTransferDuration
,
1
,
'1 ms (clocks above)'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 requests'
);
});
QUnit
.
test
(
'adjusts the playlist offset if no buffering progress is made'
,
function
()
{
...
...
@@ -356,6 +400,11 @@ QUnit.test('adjusts the playlist offset if no buffering progress is made', funct
// so the loader should try the next segment
QUnit
.
equal
(
this
.
requests
[
0
].
url
,
'1.ts'
,
'moved ahead a segment'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
20
,
'20 bytes'
);
QUnit
.
equal
(
loader
.
mediaTransferDuration
,
2
,
'2 ms (clocks above)'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
2
,
'2 requests'
);
});
QUnit
.
test
(
'adjusts the playlist offset even when segment.end is set if no'
+
...
...
@@ -453,6 +502,10 @@ QUnit.test('abort does not cancel segment processing in progress', function() {
loader
.
abort
();
QUnit
.
equal
(
loader
.
state
,
'APPENDING'
,
'still appending'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'sets the timestampOffset on timeline change'
,
function
()
{
...
...
@@ -474,6 +527,10 @@ QUnit.test('sets the timestampOffset on timeline change', function() {
this
.
requests
[
0
].
response
=
new
Uint8Array
(
10
).
buffer
;
this
.
requests
.
shift
().
respond
(
200
,
null
,
''
);
QUnit
.
equal
(
mediaSource
.
sourceBuffers
[
0
].
timestampOffset
,
10
,
'set timestampOffset'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
20
,
'20 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
2
,
'2 requests'
);
});
QUnit
.
test
(
'tracks segment end times as they are buffered'
,
function
()
{
...
...
@@ -491,6 +548,10 @@ QUnit.test('tracks segment end times as they are buffered', function() {
]);
mediaSource
.
sourceBuffers
[
0
].
trigger
(
'updateend'
);
QUnit
.
equal
(
playlist
.
segments
[
0
].
end
,
9.5
,
'updated duration'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'segment 404s should trigger an error'
,
function
()
{
...
...
@@ -548,6 +609,10 @@ QUnit.test('fires ended at the end of a playlist', function() {
mediaSource
.
sourceBuffers
[
0
].
buffered
=
videojs
.
createTimeRanges
([[
0
,
10
]]);
mediaSource
.
sourceBuffers
[
0
].
trigger
(
'updateend'
);
QUnit
.
equal
(
endOfStreams
,
1
,
'triggered ended'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'live playlists do not trigger ended'
,
function
()
{
...
...
@@ -572,6 +637,10 @@ QUnit.test('live playlists do not trigger ended', function() {
mediaSource
.
sourceBuffers
[
0
].
buffered
=
videojs
.
createTimeRanges
([[
0
,
10
]]);
mediaSource
.
sourceBuffers
[
0
].
trigger
(
'updateend'
);
QUnit
.
equal
(
endOfStreams
,
0
,
'did not trigger ended'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'respects the global withCredentials option'
,
function
()
{
...
...
@@ -781,6 +850,10 @@ QUnit.test('the key is saved to the segment in the correct format', function() {
QUnit
.
deepEqual
(
segment
.
key
.
bytes
,
new
Uint32Array
([
0
,
0x01000000
,
0x02000000
,
0x03000000
]),
'passed the specified segment key'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request was completed'
);
});
QUnit
.
test
(
'supplies media sequence of current segment as the IV by default, if no IV '
+
...
...
@@ -811,6 +884,10 @@ function() {
QUnit
.
deepEqual
(
segment
.
key
.
iv
,
new
Uint32Array
([
0
,
0
,
0
,
5
]),
'the IV for the segment is the media sequence'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'segment with key has decrypted bytes appended during processing'
,
function
()
{
...
...
@@ -839,6 +916,10 @@ QUnit.test('segment with key has decrypted bytes appended during processing', fu
// Allow the decrypter's async stream to run the callback
this
.
clock
.
tick
(
1
);
QUnit
.
ok
(
loader
.
pendingSegment_
.
bytes
,
'decrypted bytes in segment'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
8
,
'8 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'calling load with an encrypted segment waits for both key and segment '
+
...
...
@@ -864,6 +945,10 @@ QUnit.test('calling load with an encrypted segment waits for both key and segmen
keyRequest
.
response
=
new
Uint32Array
([
0
,
0
,
0
,
0
]).
buffer
;
keyRequest
.
respond
(
200
,
null
,
''
);
QUnit
.
equal
(
loader
.
state
,
'DECRYPTING'
,
'moves to decrypting state'
);
// verify stats
QUnit
.
equal
(
loader
.
mediaBytesTransferred
,
10
,
'10 bytes'
);
QUnit
.
equal
(
loader
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'key request timeouts reset bandwidth'
,
function
()
{
...
...
test/videojs-contrib-hls.test.js
View file @
b0fe834
This diff is collapsed.
Click to expand it.
Please
register
or
sign in
to post a comment