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
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
473 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
...
...
@@ -139,6 +139,25 @@ QUnit.test('starts playing if autoplay is specified', function() {
QUnit
.
ok
(
!
this
.
player
.
paused
(),
'not paused'
);
});
QUnit
.
test
(
'stats are reset on each new source'
,
function
()
{
this
.
player
.
src
({
src
:
'manifest/playlist.m3u8'
,
type
:
'application/vnd.apple.mpegurl'
});
// make sure play() is called *after* the media source opens
openMediaSource
(
this
.
player
,
this
.
clock
);
standardXHRResponse
(
this
.
requests
.
shift
());
standardXHRResponse
(
this
.
requests
.
shift
());
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'stat is set'
);
this
.
player
.
src
({
src
:
'manifest/master.m3u8'
,
type
:
'application/vnd.apple.mpegurl'
});
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
0
,
'stat is reset'
);
});
QUnit
.
test
(
'XHR requests first byte range on play'
,
function
()
{
this
.
player
.
src
({
src
:
'manifest/playlist.m3u8'
,
...
...
@@ -359,6 +378,10 @@ QUnit.test('starts downloading a segment on loadedmetadata', function() {
QUnit
.
strictEqual
(
this
.
requests
[
1
].
url
,
absoluteUrl
(
'manifest/media-00001.ts'
),
'the first segment is requested'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
're-initializes the handler for each source'
,
function
()
{
...
...
@@ -433,6 +456,10 @@ QUnit.test('downloads media playlists after loading the master', function() {
QUnit
.
strictEqual
(
this
.
requests
[
2
].
url
,
absoluteUrl
(
'manifest/media2-00001.ts'
),
'first segment requested'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'upshifts if the initial bandwidth hint is high'
,
function
()
{
...
...
@@ -462,6 +489,10 @@ QUnit.test('upshifts if the initial bandwidth hint is high', function() {
absoluteUrl
(
'manifest/media2-00001.ts'
),
'first segment requested'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'downshifts if the initial bandwidth hint is low'
,
function
()
{
...
...
@@ -485,6 +516,10 @@ QUnit.test('downshifts if the initial bandwidth hint is low', function() {
QUnit
.
strictEqual
(
this
.
requests
[
2
].
url
,
absoluteUrl
(
'manifest/media1-00001.ts'
),
'first segment requested'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'buffer checks are noops until a media playlist is ready'
,
function
()
{
...
...
@@ -499,6 +534,7 @@ QUnit.test('buffer checks are noops until a media playlist is ready', function()
QUnit
.
strictEqual
(
this
.
requests
[
0
].
url
,
'manifest/media.m3u8'
,
'media playlist requested'
);
});
QUnit
.
test
(
'buffer checks are noops when only the master is ready'
,
function
()
{
...
...
@@ -533,6 +569,9 @@ QUnit.test('buffer checks are noops when only the master is ready', function() {
QUnit
.
strictEqual
(
this
.
requests
[
0
].
url
,
absoluteUrl
(
'manifest/media1.m3u8'
),
'media playlist requested'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
,
'bandwidth set above'
);
});
QUnit
.
test
(
'selects a playlist below the current bandwidth'
,
function
()
{
...
...
@@ -556,6 +595,9 @@ QUnit.test('selects a playlist below the current bandwidth', function() {
QUnit
.
strictEqual
(
playlist
,
this
.
player
.
tech_
.
hls
.
playlists
.
master
.
playlists
[
1
],
'the low bitrate stream is selected'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
10
,
'bandwidth set above'
);
});
QUnit
.
test
(
'allows initial bandwidth to be provided'
,
function
()
{
...
...
@@ -574,6 +616,9 @@ QUnit.test('allows initial bandwidth to be provided', function() {
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
bandwidth
,
500
,
'prefers user-specified initial bandwidth'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
500
,
'bandwidth set above'
);
});
QUnit
.
test
(
'raises the minimum bitrate for a stream proportionially'
,
function
()
{
...
...
@@ -598,6 +643,9 @@ QUnit.test('raises the minimum bitrate for a stream proportionially', function()
QUnit
.
strictEqual
(
playlist
,
this
.
player
.
tech_
.
hls
.
playlists
.
master
.
playlists
[
1
],
'a lower bitrate stream is selected'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
11
,
'bandwidth set above'
);
});
QUnit
.
test
(
'uses the lowest bitrate if no other is suitable'
,
function
()
{
...
...
@@ -619,6 +667,9 @@ QUnit.test('uses the lowest bitrate if no other is suitable', function() {
QUnit
.
strictEqual
(
playlist
,
this
.
player
.
tech_
.
hls
.
playlists
.
master
.
playlists
[
1
],
'the lowest bitrate stream is selected'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
,
'bandwidth set above'
);
});
QUnit
.
test
(
'selects the correct rendition by tech dimensions'
,
function
()
{
...
...
@@ -683,6 +734,9 @@ QUnit.test('selects the correct rendition by tech dimensions', function() {
QUnit
.
equal
(
playlist
.
attributes
.
BANDWIDTH
,
440000
,
'should have the expected bandwidth in case of multiple, if exact match'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
3000000
,
'bandwidth set above'
);
});
QUnit
.
test
(
'selects the highest bitrate playlist when the player dimensions are '
+
...
...
@@ -713,6 +767,9 @@ QUnit.test('selects the highest bitrate playlist when the player dimensions are
QUnit
.
equal
(
playlist
.
attributes
.
BANDWIDTH
,
1000
,
'selected the highest bandwidth variant'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
e10
,
'bandwidth set above'
);
});
QUnit
.
test
(
'filters playlists that are currently excluded'
,
function
()
{
...
...
@@ -748,6 +805,9 @@ QUnit.test('filters playlists that are currently excluded', function() {
QUnit
.
equal
(
playlist
,
this
.
player
.
tech_
.
hls
.
playlists
.
master
.
playlists
[
0
],
'expired the exclusion'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
e10
,
'bandwidth set above'
);
});
QUnit
.
test
(
'does not blacklist compatible H.264 codec strings'
,
function
()
{
...
...
@@ -778,6 +838,9 @@ QUnit.test('does not blacklist compatible H.264 codec strings', function() {
QUnit
.
strictEqual
(
typeof
master
.
playlists
[
1
].
excludeUntil
,
'undefined'
,
'did not blacklist'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
,
'bandwidth set above'
);
});
QUnit
.
test
(
'does not blacklist compatible AAC codec strings'
,
function
()
{
...
...
@@ -808,6 +871,9 @@ QUnit.test('does not blacklist compatible AAC codec strings', function() {
QUnit
.
strictEqual
(
typeof
master
.
playlists
[
1
].
excludeUntil
,
'undefined'
,
'did not blacklist'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
,
'bandwidth set above'
);
});
QUnit
.
test
(
'cancels outstanding XHRs when seeking'
,
function
()
{
...
...
@@ -883,6 +949,9 @@ QUnit.test('segment 404 should trigger blacklisting of media', function() {
this
.
requests
[
2
].
respond
(
400
);
QUnit
.
ok
(
media
.
excludeUntil
>
0
,
'original media blacklisted for some time'
);
QUnit
.
equal
(
this
.
env
.
log
.
warn
.
calls
,
1
,
'warning logged for blacklist'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
20000
,
'bandwidth set above'
);
});
QUnit
.
test
(
'playlist 404 should blacklist media'
,
function
()
{
...
...
@@ -917,6 +986,8 @@ QUnit.test('playlist 404 should blacklist media', function() {
QUnit
.
ok
(
media
.
excludeUntil
>
0
,
'original media blacklisted for some time'
);
QUnit
.
equal
(
this
.
env
.
log
.
warn
.
calls
,
1
,
'warning logged for blacklist'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
e10
,
'bandwidth set above'
);
});
QUnit
.
test
(
'seeking in an empty playlist is a non-erroring noop'
,
function
()
{
...
...
@@ -965,6 +1036,9 @@ QUnit.test('fire loadedmetadata once we successfully load a playlist', function(
standardXHRResponse
(
this
.
requests
.
shift
());
QUnit
.
equal
(
count
,
1
,
'loadedMedia triggered after successful recovery from 404'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
20000
,
'bandwidth set above'
);
});
QUnit
.
test
(
'sets seekable and duration for live playlists'
,
function
()
{
...
...
@@ -1221,6 +1295,9 @@ QUnit.test('resets the switching algorithm if a request times out', function() {
QUnit
.
strictEqual
(
this
.
player
.
tech_
.
hls
.
playlists
.
media
(),
this
.
player
.
tech_
.
hls
.
playlists
.
master
.
playlists
[
1
],
'reset to the lowest bitrate playlist'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
1
,
'bandwidth is reset too'
);
});
QUnit
.
test
(
'disposes the playlist loader'
,
function
()
{
...
...
@@ -1411,6 +1488,10 @@ QUnit.test('calling play() at the end of a video replays', function() {
this
.
player
.
tech_
.
trigger
(
'play'
);
QUnit
.
equal
(
seekTime
,
0
,
'seeked to the beginning'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'keys are resolved relative to the master playlist'
,
function
()
{
...
...
@@ -1435,6 +1516,9 @@ QUnit.test('keys are resolved relative to the master playlist', function() {
QUnit
.
equal
(
this
.
requests
[
0
].
url
,
absoluteUrl
(
'video/playlist/keys/key.php'
),
'resolves multiple relative paths'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'keys are resolved relative to their containing playlist'
,
function
()
{
...
...
@@ -1487,6 +1571,10 @@ QUnit.test('seeking should abort an outstanding key request and create a new one
'https://example.com/'
+
this
.
player
.
tech_
.
hls
.
playlists
.
media
().
segments
[
1
].
key
.
uri
,
'urls should match'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'switching playlists with an outstanding key request aborts request and '
+
...
...
@@ -1529,6 +1617,9 @@ QUnit.test('switching playlists with an outstanding key request aborts request a
QUnit
.
equal
(
this
.
requests
[
1
].
url
,
'http://media.example.com/fileSequence52-A.ts'
,
'requested the segment'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'does not download segments if preload option set to none'
,
function
()
{
...
...
@@ -1549,6 +1640,9 @@ QUnit.test('does not download segments if preload option set to none', function(
return
!
(
/m3u8$/
).
test
(
request
.
uri
);
});
QUnit
.
equal
(
this
.
requests
.
length
,
0
,
'did not download any segments'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
// workaround https://bugzilla.mozilla.org/show_bug.cgi?id=548397
...
...
@@ -1572,6 +1666,9 @@ QUnit.test('selectPlaylist does not fail if getComputedStyle returns null', func
this
.
player
.
tech_
.
hls
.
selectPlaylist
();
QUnit
.
ok
(
true
,
'should not throw'
);
window
.
getComputedStyle
=
oldGetComputedStyle
;
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'resolves relative key URLs against the playlist'
,
function
()
{
...
...
@@ -1608,6 +1705,9 @@ QUnit.test('adds 1 default audio track if we have not parsed any, and the playli
QUnit
.
equal
(
this
.
player
.
audioTracks
().
length
,
1
,
'one audio track after load'
);
QUnit
.
ok
(
this
.
player
.
audioTracks
()[
0
]
instanceof
HlsAudioTrack
,
'audio track is an hls audio track'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'adds 1 default audio track if in flash mode'
,
function
()
{
...
...
@@ -1673,6 +1773,9 @@ QUnit.test('adds audio tracks if we have parsed some from a playlist', function(
QUnit
.
equal
(
vjsAudioTracks
[
1
].
enabled
,
false
,
'main track is disabled'
);
QUnit
.
equal
(
hlsAudioTracks
[
1
].
enabled
,
false
,
'main track is disabled'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'audio info from audioinfo event is stored on hls'
,
function
()
{
...
...
@@ -1754,6 +1857,9 @@ QUnit.test('audioinfo changes with three tracks, enabled track is blacklisted an
QUnit
.
equal
(
blacklistPlaylistCalls
,
0
,
'blacklist was not called on playlist'
);
QUnit
.
equal
(
this
.
env
.
log
.
warn
.
calls
,
1
,
'firefox issue warning logged'
);
videojs
.
browser
.
IS_FIREFOX
=
oldIsFirefox
;
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'audioinfo changes with one track, blacklist playlist'
,
function
()
{
...
...
@@ -1787,6 +1893,9 @@ QUnit.test('audioinfo changes with one track, blacklist playlist', function() {
QUnit
.
equal
(
blacklistPlaylistCalls
,
1
,
'blacklist was called on playlist'
);
QUnit
.
equal
(
this
.
env
.
log
.
warn
.
calls
,
1
,
'firefox issue warning logged'
);
videojs
.
browser
.
IS_FIREFOX
=
oldIsFirefox
;
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'audioinfo changes with three tracks, default is enabled, blacklisted playlist'
,
function
()
{
...
...
@@ -1835,6 +1944,9 @@ QUnit.test('audioinfo changes with three tracks, default is enabled, blacklisted
QUnit
.
equal
(
blacklistPlaylistCalls
,
1
,
'blacklist was called on playlist'
);
QUnit
.
equal
(
this
.
env
.
log
.
warn
.
calls
,
1
,
'firefox issue warning logged'
);
videojs
.
browser
.
IS_FIREFOX
=
oldIsFirefox
;
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'cleans up the buffer when loading live segments'
,
function
()
{
...
...
@@ -1884,6 +1996,10 @@ QUnit.test('cleans up the buffer when loading live segments', function() {
QUnit
.
equal
(
removes
.
length
,
1
,
'remove called'
);
QUnit
.
deepEqual
(
removes
[
0
],
[
0
,
seekable
.
start
(
0
)],
'remove called with the right range'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'cleans up the buffer based on currentTime when loading a live segment '
+
...
...
@@ -1934,6 +2050,10 @@ QUnit.test('cleans up the buffer based on currentTime when loading a live segmen
QUnit
.
strictEqual
(
this
.
requests
[
0
].
url
,
'liveStart30sBefore.m3u8'
,
'master playlist requested'
);
QUnit
.
equal
(
removes
.
length
,
1
,
'remove called'
);
QUnit
.
deepEqual
(
removes
[
0
],
[
0
,
80
-
60
],
'remove called with the right range'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'cleans up the buffer when loading VOD segments'
,
function
()
{
...
...
@@ -1969,6 +2089,10 @@ QUnit.test('cleans up the buffer when loading VOD segments', function() {
'media playlist requested'
);
QUnit
.
equal
(
removes
.
length
,
1
,
'remove called'
);
QUnit
.
deepEqual
(
removes
[
0
],
[
0
,
120
-
60
],
'remove called with the right range'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'when mediaGroup changes enabled track should not change'
,
function
()
{
...
...
@@ -2042,6 +2166,9 @@ QUnit.test('when mediaGroup changes enabled track should not change', function()
QUnit
.
equal
(
trackOne
.
enabled
,
false
,
'track 1 - still disabled'
);
QUnit
.
equal
(
trackTwo
.
enabled
,
true
,
'track 2 - still enabled'
);
QUnit
.
equal
(
trackThree
.
enabled
,
false
,
'track 3 - disabled'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'Allows specifying the beforeRequest function on the player'
,
function
()
{
...
...
@@ -2062,6 +2189,9 @@ QUnit.test('Allows specifying the beforeRequest function on the player', functio
standardXHRResponse
(
this
.
requests
.
shift
());
QUnit
.
ok
(
beforeRequestCalled
,
'beforeRequest was called'
);
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'Allows specifying the beforeRequest function globally'
,
function
()
{
...
...
@@ -2082,6 +2212,9 @@ QUnit.test('Allows specifying the beforeRequest function globally', function() {
QUnit
.
ok
(
beforeRequestCalled
,
'beforeRequest was called'
);
delete
videojs
.
Hls
.
xhr
.
beforeRequest
;
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
bandwidth
,
4194304
,
'default'
);
});
QUnit
.
test
(
'Allows overriding the global beforeRequest function'
,
function
()
{
...
...
@@ -2114,6 +2247,10 @@ QUnit.test('Allows overriding the global beforeRequest function', function() {
'for the master playlist'
);
delete
videojs
.
Hls
.
xhr
.
beforeRequest
;
// verify stats
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaBytesTransferred
,
16
,
'seen above'
);
QUnit
.
equal
(
this
.
player
.
tech_
.
hls
.
stats
.
mediaRequests
,
1
,
'one segment request'
);
});
QUnit
.
module
(
'HLS Integration'
,
{
...
...
@@ -2151,6 +2288,26 @@ QUnit.test('aborts all in-flight work when disposed', function() {
});
});
QUnit
.
test
(
'stats are reset on dispose'
,
function
()
{
let
hls
=
HlsSourceHandler
(
'html5'
).
handleSource
({
src
:
'manifest/master.m3u8'
,
type
:
'application/vnd.apple.mpegurl'
},
this
.
tech
);
hls
.
mediaSource
.
trigger
(
'sourceopen'
);
// master
standardXHRResponse
(
this
.
requests
.
shift
());
// media
standardXHRResponse
(
this
.
requests
.
shift
());
// media
standardXHRResponse
(
this
.
requests
.
shift
());
QUnit
.
equal
(
hls
.
stats
.
mediaBytesTransferred
,
16
,
'stat is set'
);
hls
.
dispose
();
QUnit
.
equal
(
hls
.
stats
.
mediaBytesTransferred
,
0
,
'stat is reset'
);
});
QUnit
.
test
(
'detects fullscreen and triggers a quality change'
,
function
()
{
let
qualityChanges
=
0
;
let
hls
=
HlsSourceHandler
(
'html5'
).
handleSource
({
...
...
@@ -2215,6 +2372,11 @@ QUnit.test('downloads additional playlists if required', function() {
hls
.
playlists
.
media
().
resolvedUri
,
'a new playlists was selected'
);
QUnit
.
ok
(
hls
.
playlists
.
media
().
segments
,
'segments are now available'
);
// verify stats
QUnit
.
equal
(
hls
.
stats
.
bandwidth
,
3000000
,
'default'
);
QUnit
.
equal
(
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'waits to download new segments until the media playlist is stable'
,
function
()
{
...
...
@@ -2251,6 +2413,11 @@ QUnit.test('waits to download new segments until the media playlist is stable',
standardXHRResponse
(
this
.
requests
.
shift
());
this
.
clock
.
tick
(
10
*
1000
);
QUnit
.
equal
(
this
.
requests
.
length
,
1
,
'resumes segment fetching'
);
// verify stats
QUnit
.
equal
(
hls
.
stats
.
bandwidth
,
Infinity
,
'default'
);
QUnit
.
equal
(
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
QUnit
.
test
(
'live playlist starts three target durations before live'
,
function
()
{
...
...
@@ -2286,6 +2453,7 @@ QUnit.test('live playlist starts three target durations before live', function()
'seeked to the seekable end'
);
QUnit
.
equal
(
this
.
requests
.
length
,
1
,
'begins buffering'
);
});
QUnit
.
module
(
'HLS - Encryption'
,
{
...
...
@@ -2361,4 +2529,8 @@ QUnit.test('treats invalid keys as a key request failure and blacklists playlist
QUnit
.
ok
(
hls
.
playlists
.
media
().
excludeUntil
>
0
,
'blacklisted playlist'
);
QUnit
.
equal
(
this
.
env
.
log
.
warn
.
calls
,
1
,
'logged warning for blacklist'
);
// verify stats
QUnit
.
equal
(
hls
.
stats
.
mediaBytesTransferred
,
16
,
'16 bytes'
);
QUnit
.
equal
(
hls
.
stats
.
mediaRequests
,
1
,
'1 request'
);
});
...
...
Please
register
or
sign in
to post a comment