videojs-hls.js
3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
* video-js-hls
*
*
* Copyright (c) 2013 Brightcove
* All rights reserved.
*/
(function(window, videojs, undefined) {
videojs.hls = {};
var init = function(options) {
var
mediaSource = new videojs.MediaSource(),
segmentParser = new videojs.hls.SegmentParser(),
player = this,
url,
fillBuffer,
selectPlaylist;
if (typeof options === 'string') {
url = options;
} else {
url = options.url;
}
// expose the HLS plugin state
player.hls.readyState = function() {
if (!player.hls.manifest) {
return 0; // HAVE_NOTHING
}
return 1; // HAVE_METADATA
};
// load the MediaSource into the player
mediaSource.addEventListener('sourceopen', function() {
// construct the video data buffer and set the appropriate MIME type
var sourceBuffer = mediaSource.addSourceBuffer('video/flv; codecs="vp6,aac"');
player.hls.sourceBuffer = sourceBuffer;
sourceBuffer.appendBuffer(segmentParser.getFlvHeader());
// Chooses the appropriate media playlist based on the current bandwidth
// estimate and the player size
selectPlaylist = function() {
player.hls.currentPlaylist = player.hls.manifest;
player.hls.currentMediaIndex = 0;
};
// download a new segment if one is needed
fillBuffer = function() {
var
xhr = new window.XMLHttpRequest(),
segment = player.hls.currentPlaylist.segments[player.hls.currentMediaIndex],
segmentUri = segment.uri,
startTime;
if (!(/^([A-z]*:)?\/\//).test(segmentUri)) {
// the segment URI is relative to the manifest
segmentUri = url.split('/').slice(0, -1).concat(segmentUri).join('/');
}
xhr.open('GET', segmentUri);
xhr.responseType = 'arraybuffer';
xhr.onreadystatechange = function() {
var elapsed;
if (xhr.readyState === 4) {
// calculate the download bandwidth
elapsed = ((+new Date()) - startTime) * 1000;
player.hls.bandwidth = xhr.response.byteLength / elapsed;
// transmux the segment data from M2TS to FLV
segmentParser.parseSegmentBinaryData(new Uint8Array(xhr.response));
while (segmentParser.tagsAvailable()) {
player.hls.sourceBuffer.appendBuffer(segmentParser.getNextTag().bytes,
player);
}
// update the segment index
player.hls.currentMediaIndex++;
}
};
startTime = +new Date();
xhr.send(null);
};
player.on('loadedmetadata', fillBuffer);
// download and process the manifest
(function() {
var xhr = new window.XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = function() {
var parser;
if (xhr.readyState === 4) {
// readystate DONE
parser = new videojs.m3u8.Parser();
parser.push(xhr.responseText);
player.hls.manifest = parser.manifest;
player.trigger('loadedmanifest');
if (parser.manifest.segments) {
selectPlaylist();
player.trigger('loadedmetadata');
}
}
};
xhr.send(null);
})();
});
player.src({
src: videojs.URL.createObjectURL(mediaSource),
type: "video/flv"
});
};
videojs.plugin('hls', function() {
var initialize = function() {
return function() {
this.hls = initialize();
init.apply(this, arguments);
};
};
initialize().apply(this, arguments);
});
})(window, window.videojs);