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
76a27259
authored
2014-07-08 11:43:47 -0400
by
David LaPalomento
Browse Files
Options
Browse Files
Tag
Download
Plain Diff
Merge pull request #96 from videojs/feature/metrics
Expose more diagnostic info
2 parents
56043011
9edf081a
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
121 additions
and
1 deletions
README.md
src/playlist-loader.js
src/videojs-hls.js
test/playlist-loader_test.js
test/videojs-hls_test.js
README.md
View file @
76a2725
...
...
@@ -116,6 +116,11 @@ The number of bits downloaded per second in the last segment download.
This value is used by the default implementation of
`selectPlaylist`
to select an appropriate bitrate to play.
#### player.hls.bytesReceived
Type:
`number`
The total number of content bytes downloaded by the HLS tech.
#### player.hls.selectPlaylist
Type:
`function`
...
...
@@ -136,6 +141,13 @@ Fired immediately after a new master or media playlist has been
downloaded. By default, the tech only downloads playlists as they
are needed.
#### mediachange
Fired when a new playlist becomes the active media playlist. Note that
the actual rendering quality change does not occur simultaneously with
this event; a new segment must be requested and the existing buffer
depleted first.
### Testing
For testing, you can either run
`npm test`
or use
`grunt`
directly.
...
...
src/playlist-loader.js
View file @
76a2725
...
...
@@ -131,6 +131,7 @@
* object to switch to
*/
loader
.
media
=
function
(
playlist
)
{
var
mediaChange
=
false
;
// getter
if
(
!
playlist
)
{
return
media
;
...
...
@@ -150,19 +151,27 @@
playlist
=
loader
.
master
.
playlists
[
playlist
];
}
mediaChange
=
playlist
.
uri
!==
media
.
uri
;
// switch to fully loaded playlists immediately
if
(
loader
.
master
.
playlists
[
playlist
.
uri
].
endList
)
{
// abort outstanding playlist requests
if
(
request
)
{
request
.
abort
();
request
=
null
;
}
loader
.
state
=
'HAVE_METADATA'
;
media
=
playlist
;
// trigger media change if the active media has been updated
if
(
mediaChange
)
{
loader
.
trigger
(
'mediachange'
);
}
return
;
}
// switching to the active playlist is a no-op
if
(
playlist
.
uri
===
media
.
uri
)
{
if
(
!
mediaChange
)
{
return
;
}
...
...
@@ -185,6 +194,7 @@
withCredentials
:
withCredentials
},
function
(
error
)
{
haveMetadata
(
error
,
this
,
playlist
.
uri
);
loader
.
trigger
(
'mediachange'
);
});
};
...
...
src/videojs-hls.js
View file @
76a2725
...
...
@@ -433,6 +433,7 @@ var
// calculate the download bandwidth
player
.
hls
.
segmentXhrTime
=
(
+
new
Date
())
-
startTime
;
player
.
hls
.
bandwidth
=
(
this
.
response
.
byteLength
/
player
.
hls
.
segmentXhrTime
)
*
8
*
1000
;
player
.
hls
.
bytesReceived
+=
this
.
response
.
byteLength
;
// transmux the segment data from MP2T to FLV
segmentParser
.
parseSegmentBinaryData
(
new
Uint8Array
(
this
.
response
));
...
...
@@ -575,6 +576,9 @@ var
updatedPlaylist
);
oldMediaPlaylist
=
updatedPlaylist
;
});
player
.
hls
.
playlists
.
on
(
'mediachange'
,
function
()
{
player
.
trigger
(
'mediachange'
);
});
});
};
...
...
@@ -591,6 +595,8 @@ videojs.Hls = videojs.Flash.extend({
options
.
swf
=
settings
.
flash
.
swf
;
videojs
.
Flash
.
call
(
this
,
player
,
options
,
ready
);
options
.
source
=
source
;
this
.
bytesReceived
=
0
;
videojs
.
Hls
.
prototype
.
src
.
call
(
this
,
options
.
source
&&
options
.
source
.
src
);
}
});
...
...
test/playlist-loader_test.js
View file @
76a2725
...
...
@@ -510,4 +510,45 @@
strictEqual
(
errors
,
1
,
'fired one error'
);
strictEqual
(
loader
.
error
.
code
,
2
,
'fired a network error'
);
});
test
(
'triggers an event when the active media changes'
,
function
()
{
var
loader
=
new
videojs
.
Hls
.
PlaylistLoader
(
'master.m3u8'
),
mediaChanges
=
0
;
loader
.
on
(
'mediachange'
,
function
()
{
mediaChanges
++
;
});
requests
.
pop
().
respond
(
200
,
null
,
'#EXTM3U\n'
+
'#EXT-X-STREAM-INF:BANDWIDTH=1\n'
+
'low.m3u8\n'
+
'#EXT-X-STREAM-INF:BANDWIDTH=2\n'
+
'high.m3u8\n'
);
requests
.
shift
().
respond
(
200
,
null
,
'#EXTM3U\n'
+
'#EXT-X-MEDIA-SEQUENCE:0\n'
+
'#EXTINF:10,\n'
+
'low-0.ts\n'
+
'#EXT-X-ENDLIST\n'
);
strictEqual
(
mediaChanges
,
0
,
'initial selection is not a media change'
);
loader
.
media
(
'high.m3u8'
);
strictEqual
(
mediaChanges
,
0
,
'mediachange does not fire immediately'
);
requests
.
shift
().
respond
(
200
,
null
,
'#EXTM3U\n'
+
'#EXT-X-MEDIA-SEQUENCE:0\n'
+
'#EXTINF:10,\n'
+
'high-0.ts\n'
+
'#EXT-X-ENDLIST\n'
);
strictEqual
(
mediaChanges
,
1
,
'fired a mediachange'
);
// switch back to an already loaded playlist
loader
.
media
(
'low.m3u8'
);
strictEqual
(
mediaChanges
,
2
,
'fired a mediachange'
);
// trigger a no-op switch
loader
.
media
(
'low.m3u8'
);
strictEqual
(
mediaChanges
,
2
,
'ignored a no-op media change'
);
});
})(
window
);
...
...
test/videojs-hls_test.js
View file @
76a2725
...
...
@@ -1227,4 +1227,55 @@ test('has no effect if native HLS is available', function() {
player
.
dispose
();
});
test
(
'tracks the bytes downloaded'
,
function
()
{
player
.
src
({
src
:
'http://example.com/media.m3u8'
,
type
:
'application/vnd.apple.mpegurl'
});
player
.
hls
.
mediaSource
.
trigger
({
type
:
'sourceopen'
});
strictEqual
(
player
.
hls
.
bytesReceived
,
0
,
'no bytes received'
);
requests
.
shift
().
respond
(
200
,
null
,
'#EXTM3U\n'
+
'#EXTINF:10,\n'
+
'0.ts\n'
+
'#EXTINF:10,\n'
+
'1.ts\n'
+
'#EXT-X-ENDLIST\n'
);
// transmit some segment bytes
requests
[
0
].
response
=
new
ArrayBuffer
(
17
);
requests
.
shift
().
respond
(
200
,
null
,
''
);
strictEqual
(
player
.
hls
.
bytesReceived
,
17
,
'tracked bytes received'
);
player
.
trigger
(
'timeupdate'
);
// transmit some more
requests
[
0
].
response
=
new
ArrayBuffer
(
5
);
requests
.
shift
().
respond
(
200
,
null
,
''
);
strictEqual
(
player
.
hls
.
bytesReceived
,
22
,
'tracked more bytes'
);
});
test
(
're-emits mediachange events'
,
function
()
{
var
mediaChanges
=
0
;
player
.
on
(
'mediachange'
,
function
()
{
mediaChanges
++
;
});
player
.
src
({
src
:
'http://example.com/media.m3u8'
,
type
:
'application/vnd.apple.mpegurl'
});
player
.
hls
.
mediaSource
.
trigger
({
type
:
'sourceopen'
});
player
.
hls
.
playlists
.
trigger
(
'mediachange'
);
strictEqual
(
mediaChanges
,
1
,
'fired mediachange'
);
});
})(
window
,
window
.
videojs
);
...
...
Please
register
or
sign in
to post a comment