-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsash.js
96 lines (78 loc) · 3.53 KB
/
sash.js
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
(function(undefined) {
function get(url, callback, ctx) {
var request = new XMLHttpRequest();
request.responseType = 'arraybuffer';
request.onreadystatechange = function() {
if (request.readyState == 4 && (request.status == 200 || request.status == 304)) {
callback.call(ctx, null, request.response);
}
};
request.open('GET', url , true);
request.send();
}
// TODO: 1) Limit the number of the buffers we hold in memory if MSE is slow to consume them
// 2) Stop downloading segments when we've got a sensible number buffered (Or even better a configurable duration...)
// 3) Support scrubbing to un-buffered points in the content
// Track prototype
function Track(mediaSource, codecString, segments) {
this.mediaBuffer = [];
this.sourceBuffer;
this.segments = segments;
this.codecString = codecString;
this.currentSegment = 0;
this.mediaSource = mediaSource;
mediaSource.addEventListener('sourceopen', this.sourceOpenCallback.bind(this), false);
}
Track.prototype.getNextSegment = function() {
get(this.segments[this.currentSegment], function(err, result) {
this.mediaBuffer.push(result);
this.loadBufferIntoMSE();
this.currentSegment++;
if (this.currentSegment < this.segments.length) {
this.getNextSegment();
}
}, this);
}
Track.prototype.loadBufferIntoMSE = function() {
if (this.mediaBuffer.length) {
try {
if (!this.sourceBuffer.updating) {
this.sourceBuffer.appendBuffer(this.mediaBuffer.shift());
}
else {
console.log("MSE buffer currently updating.")
}
}
catch (err) {
console.log('Error when loading buffer into MSE.')
}
}
else {
console.log('No buffers ready to load into MSE.')
}
}
Track.prototype.sourceOpenCallback = function() {
this.sourceBuffer = this.mediaSource.addSourceBuffer(this.codecString);
this.sourceBuffer.addEventListener('update', this.loadBufferIntoMSE.bind(this), false);
this.getNextSegment();
}
// Setup MSE
var mediaSource = new MediaSource();
var player = document.querySelector('#player');
$.getJSON( "0.2.json", function( manifest ) {
// Grab the first Audio and Video renditions we find, and push them onto MSE
['video', 'audio'].forEach(function(element) {
firstRenditionName = Object.keys(manifest[element][0].renditions)[0];
firstRendition = manifest[element][0].renditions[firstRenditionName];
var codecString = manifest[element][0].mime_type + '; codecs="' + firstRendition.codecs + '"';
var segments = [manifest[element][0].segment_template.init.replace('$rendition$', firstRenditionName)];
for (k = manifest[element][0].segment_template.start_number; k <= manifest[element][0].segment_template.end_number; k++) {
segments.push(manifest[element][0].segment_template.media.replace('$rendition$', firstRenditionName).replace('$number$', k));
}
new Track(mediaSource, codecString, segments);
});
// Only init MSE once the manifest is loaded.
player.src = window.URL.createObjectURL(mediaSource);
setTimeout(function(){ player.play() }, 1000);
});
}())