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
598e5e89
authored
2015-09-22 18:36:17 -0400
by
David LaPalomento
Browse Files
Options
Browse Files
Tag
Download
Plain Diff
Merge pull request #389 from videojs/discontinuity
Discontinuity
2 parents
9e8618df
322b2318
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
80 additions
and
24 deletions
package.json
src/videojs-hls.js
src/xhr.js
test/playlist-loader_test.js
test/videojs-hls_test.js
package.json
View file @
598e5e8
...
...
@@ -44,11 +44,11 @@
"karma-sauce-launcher"
:
"~0.1.8"
,
"qunitjs"
:
"^1.18.0"
,
"sinon"
:
"1.10.2"
,
"video.js"
:
"^5.0.0-rc.
51
"
"video.js"
:
"^5.0.0-rc.
96
"
},
"dependencies"
:
{
"pkcs7"
:
"^0.2.2"
,
"videojs-contrib-media-sources"
:
"videojs/videojs-contrib-media-sources.git#mse-mp2t-polyfill"
,
"videojs-swf"
:
"5.0.0-rc
0
"
"videojs-swf"
:
"5.0.0-rc
1
"
}
}
...
...
src/videojs-hls.js
View file @
598e5e8
...
...
@@ -24,8 +24,8 @@ keyFailed = function(key) {
return
key
.
retries
&&
key
.
retries
>=
2
;
};
videojs
.
Hls
=
videojs
.
extend
s
(
Component
,
{
constructor
:
function
(
tech
,
source
)
{
videojs
.
Hls
=
videojs
.
extend
(
Component
,
{
constructor
:
function
(
tech
,
options
)
{
var
self
=
this
,
_player
;
Component
.
call
(
this
,
tech
);
...
...
@@ -44,7 +44,8 @@ videojs.Hls = videojs.extends(Component, {
}
}
this
.
tech_
=
tech
;
this
.
source_
=
source
;
this
.
source_
=
options
.
source
;
this
.
mode_
=
options
.
mode
;
this
.
bytesReceived
=
0
;
// loadingState_ tracks how far along the buffering process we
...
...
@@ -87,7 +88,8 @@ videojs.Hls.canPlaySource = function() {
* the browser it is running in. It is not necessary to use or modify
* this object in normal usage.
*/
videojs
.
HlsSourceHandler
=
{
videojs
.
HlsSourceHandler
=
function
(
mode
)
{
return
{
canHandleSource
:
function
(
srcObj
)
{
var
mpegurlRE
=
/^application
\/(?:
x-|vnd
\.
apple
\.)
mpegurl/i
;
...
...
@@ -98,17 +100,21 @@ videojs.HlsSourceHandler = {
return
mpegurlRE
.
test
(
srcObj
.
type
);
},
handleSource
:
function
(
source
,
tech
)
{
tech
.
hls
=
new
videojs
.
Hls
(
tech
,
source
);
tech
.
hls
=
new
videojs
.
Hls
(
tech
,
{
source
:
source
,
mode
:
mode
});
tech
.
hls
.
src
(
source
.
src
);
return
tech
.
hls
;
}
};
};
// register with the appropriate tech
// register source handlers with the appropriate techs
if
(
videojs
.
MediaSource
.
supportsNativeMediaSources
())
{
videojs
.
getComponent
(
'Html5'
).
registerSourceHandler
(
videojs
.
HlsSourceHandler
);
}
else
{
videojs
.
getComponent
(
'Flash'
).
registerSourceHandler
(
videojs
.
HlsSourceHandler
);
videojs
.
getComponent
(
'Html5'
).
registerSourceHandler
(
videojs
.
HlsSourceHandler
(
'html5'
));
}
videojs
.
getComponent
(
'Flash'
).
registerSourceHandler
(
videojs
.
HlsSourceHandler
(
'flash'
));
// the desired length of video to maintain in the buffer, in seconds
videojs
.
Hls
.
GOAL_BUFFER_LENGTH
=
30
;
...
...
@@ -121,7 +127,7 @@ videojs.Hls.prototype.src = function(src) {
return
;
}
this
.
mediaSource
=
new
videojs
.
MediaSource
();
this
.
mediaSource
=
new
videojs
.
MediaSource
(
{
mode
:
this
.
mode_
}
);
this
.
segmentBuffer_
=
[];
// if the stream contains ID3 metadata, expose that as a metadata
...
...
@@ -739,6 +745,31 @@ videojs.Hls.prototype.stopCheckingBuffer_ = function() {
};
/**
* Attempts to find the buffered TimeRange where playback is currently
* happening. Returns a new TimeRange with one or zero ranges.
*/
videojs
.
Hls
.
prototype
.
findCurrentBuffered_
=
function
()
{
var
tech
=
this
.
tech_
,
currentTime
=
tech
.
currentTime
(),
buffered
=
this
.
tech_
.
buffered
(),
i
;
if
(
buffered
&&
buffered
.
length
)
{
// Search for a range containing the play-head
for
(
i
=
0
;
i
<
buffered
.
length
;
i
++
)
{
if
(
buffered
.
start
(
i
)
<=
currentTime
&&
buffered
.
end
(
i
)
>=
currentTime
)
{
return
videojs
.
createTimeRange
(
buffered
.
start
(
i
),
buffered
.
end
(
i
));
}
}
}
// Return an empty range if no ranges exist
return
videojs
.
createTimeRange
();
};
/**
* Determines whether there is enough video data currently in the buffer
* and downloads a new segment if the buffered time is less than the goal.
* @param offset (optional) {number} the offset into the downloaded segment
...
...
@@ -747,7 +778,8 @@ videojs.Hls.prototype.stopCheckingBuffer_ = function() {
videojs
.
Hls
.
prototype
.
fillBuffer
=
function
(
offset
)
{
var
tech
=
this
.
tech_
,
buffered
=
this
.
tech_
.
buffered
(),
currentTime
=
tech
.
currentTime
(),
buffered
=
this
.
findCurrentBuffered_
(),
bufferedTime
=
0
,
segment
,
segmentUri
;
...
...
@@ -785,9 +817,10 @@ videojs.Hls.prototype.fillBuffer = function(offset) {
return
;
}
// To determine how much is buffered, we need to find the buffered region we
// are currently playing in and measure it's length
if
(
buffered
&&
buffered
.
length
)
{
// assuming a single, contiguous buffer region
bufferedTime
=
tech
.
buffered
().
end
(
0
)
-
tech
.
currentTime
();
bufferedTime
=
Math
.
max
(
0
,
buffered
.
end
(
0
)
-
currentTime
);
}
// if there is plenty of content in the buffer and we're not
...
...
@@ -844,12 +877,13 @@ videojs.Hls.prototype.loadSegment = function(segmentUri, offset) {
// the segment request is no longer outstanding
self
.
segmentXhr_
=
null
;
if
(
error
)
{
// if a segment request times out, we may have better luck with another playlist
if
(
request
.
timedout
)
{
self
.
bandwidth
=
1
;
return
self
.
playlists
.
media
(
self
.
selectPlaylist
());
}
if
(
!
request
.
aborted
&&
error
)
{
// otherwise, try jumping ahead to the next segment
self
.
error
=
{
status
:
request
.
status
,
...
...
@@ -914,7 +948,6 @@ videojs.Hls.prototype.drainBuffer = function(event) {
segment
,
decrypter
,
segIv
,
segmentOffset
=
0
,
// ptsTime,
segmentBuffer
=
this
.
segmentBuffer_
;
...
...
@@ -999,11 +1032,9 @@ videojs.Hls.prototype.drainBuffer = function(event) {
// this.tech_.el().vjs_discontinuity();
// }
// determine the timestamp offset for the start of this segment
segmentOffset
=
this
.
playlists
.
expiredPostDiscontinuity_
+
this
.
playlists
.
expiredPreDiscontinuity_
;
segmentOffset
+=
videojs
.
Hls
.
Playlist
.
duration
(
playlist
,
playlist
.
mediaSequence
,
playlist
.
mediaSequence
+
mediaIndex
);
if
(
segment
.
discontinuity
)
{
this
.
sourceBuffer
.
timestampOffset
=
this
.
findCurrentBuffered_
().
end
(
0
);
}
this
.
sourceBuffer
.
appendBuffer
(
bytes
);
...
...
src/xhr.js
View file @
598e5e8
...
...
@@ -5,13 +5,35 @@
* A wrapper for videojs.xhr that tracks bandwidth.
*/
videojs
.
Hls
.
xhr
=
function
(
options
,
callback
)
{
var
request
=
videojs
.
xhr
(
options
,
function
(
error
,
request
)
{
if
(
request
.
response
)
{
// Add a default timeout for all hls requests
options
=
videojs
.
mergeOptions
({
timeout
:
45
e3
},
options
);
var
request
=
videojs
.
xhr
(
options
,
function
(
error
,
response
)
{
if
(
!
error
&&
request
.
response
)
{
request
.
responseTime
=
(
new
Date
()).
getTime
();
request
.
roundTripTime
=
request
.
responseTime
-
request
.
requestTime
;
request
.
bytesReceived
=
request
.
response
.
byteLength
||
request
.
response
.
length
;
if
(
!
request
.
bandwidth
)
{
request
.
bandwidth
=
Math
.
floor
((
request
.
bytesReceived
/
request
.
roundTripTime
)
*
8
*
1000
);
}
}
// videojs.xhr now uses a specific code on the error object to signal that a request has
// timed out errors of setting a boolean on the request object
if
(
error
||
request
.
timedout
)
{
request
.
timedout
=
request
.
timedout
||
(
error
.
code
===
'ETIMEDOUT'
);
}
else
{
request
.
timedout
=
false
;
}
// videojs.xhr no longer consider status codes outside of 200 and 0 (for file uris) to be
// errors but the old XHR did so emulate that behavior
if
(
!
error
&&
response
.
statusCode
!==
200
&&
response
.
statusCode
!==
0
)
{
error
=
new
Error
(
'XHR Failed with a response of: '
+
(
request
&&
(
request
.
response
||
request
.
responseText
)));
}
callback
(
error
,
request
);
});
...
...
test/playlist-loader_test.js
View file @
598e5e8
...
...
@@ -20,6 +20,8 @@
setup
:
function
()
{
// fake XHRs
sinonXhr
=
sinon
.
useFakeXMLHttpRequest
();
videojs
.
xhr
.
XMLHttpRequest
=
sinonXhr
;
requests
=
[];
sinonXhr
.
onCreate
=
function
(
xhr
)
{
// force the XHR2 timeout polyfill
...
...
@@ -32,6 +34,7 @@
},
teardown
:
function
()
{
sinonXhr
.
restore
();
videojs
.
xhr
.
XMLHttpRequest
=
window
.
XMLHttpRequest
;
clock
.
restore
();
}
});
...
...
test/videojs-hls_test.js
View file @
598e5e8
This diff is collapsed.
Click to expand it.
Please
register
or
sign in
to post a comment