Created
January 5, 2016 04:12
-
-
Save whatvn/2c2795f48db8dbb4c587 to your computer and use it in GitHub Desktop.
FR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MediaPlayer.dependencies.FragmentLoader = function () { | |
"use strict"; | |
var RETRY_ATTEMPTS = MediaPlayer.dependencies.FragmentLoader.RETRY_ATTEMPTS, | |
RETRY_INTERVAL = MediaPlayer.dependencies.FragmentLoader.RETRY_INTERVAL, | |
xhrs = [], | |
doLoad = function (request, remainingAttempts) { | |
var req = new XMLHttpRequest(), | |
traces = [], | |
firstProgress = true, | |
needFailureReport = true, | |
lastTraceTime = null, | |
self = this, | |
handleLoaded = function(requestVO, succeeded) { | |
needFailureReport = false; | |
var currentTime = new Date(), | |
bytes = req.response, | |
latency, | |
download, | |
httpRequestMetrics = null; | |
traces.push({ | |
s: currentTime, | |
d: currentTime.getTime() - lastTraceTime.getTime(), | |
b: [bytes ? bytes.byteLength : 0] | |
}); | |
if (!requestVO.firstByteDate) { | |
requestVO.firstByteDate = requestVO.requestStartDate; | |
} | |
requestVO.requestEndDate = currentTime; | |
latency = (requestVO.firstByteDate.getTime() - requestVO.requestStartDate.getTime()); | |
download = (requestVO.requestEndDate.getTime() - requestVO.firstByteDate.getTime()); | |
self.log((succeeded ? "loaded " : "failed ") + requestVO.mediaType + ":" + requestVO.type + ":" + requestVO.startTime + " (" + req.status + ", " + latency + "ms, " + download + "ms)"); | |
httpRequestMetrics = self.metricsModel.addHttpRequest( | |
request.mediaType, | |
null, | |
request.type, | |
request.url, | |
req.responseURL || null, | |
request.range, | |
request.requestStartDate, | |
requestVO.firstByteDate, | |
requestVO.requestEndDate, | |
req.status, | |
request.duration, | |
req.getAllResponseHeaders() | |
); | |
if (succeeded) { | |
// trace is only for successful requests | |
traces.forEach(function (trace) { | |
self.metricsModel.appendHttpTrace(httpRequestMetrics, | |
trace.s, | |
trace.d, | |
trace.b); | |
}); | |
} | |
}; | |
xhrs.push(req); | |
request.requestStartDate = new Date(); | |
traces.push({ | |
s: request.requestStartDate, | |
d: 0, | |
b: [0] | |
}); | |
lastTraceTime = request.requestStartDate; | |
req.open("GET", self.requestModifierExt.modifyRequestURL(request.url), true); | |
req.responseType = "arraybuffer"; | |
req = self.requestModifierExt.modifyRequestHeader(req); | |
/* | |
req.setRequestHeader("Cache-Control", "no-cache"); | |
req.setRequestHeader("Pragma", "no-cache"); | |
req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); | |
*/ | |
if (request.range) { | |
req.setRequestHeader("Range", "bytes=" + request.range); | |
} | |
req.onprogress = function (event) { | |
var currentTime = new Date(); | |
if (firstProgress) { | |
firstProgress = false; | |
if (!event.lengthComputable || (event.lengthComputable && event.total != event.loaded)) { | |
request.firstByteDate = currentTime; | |
} | |
} | |
if (event.lengthComputable) { | |
request.bytesLoaded = event.loaded; | |
request.bytesTotal = event.total; | |
} | |
traces.push({ | |
s: currentTime, | |
d: currentTime.getTime() - lastTraceTime.getTime(), | |
b: [req.response ? req.response.byteLength : 0] | |
}); | |
lastTraceTime = currentTime; | |
self.notify(MediaPlayer.dependencies.FragmentLoader.eventList.ENAME_LOADING_PROGRESS, {request: request}); | |
}; | |
req.onload = function () { | |
if (req.status < 200 || req.status > 299) return; | |
handleLoaded(request, true); | |
self.notify(MediaPlayer.dependencies.FragmentLoader.eventList.ENAME_LOADING_COMPLETED, {request: request, response: req.response}); | |
}; | |
req.onloadend = req.onerror = function () { | |
if (xhrs.indexOf(req) === -1) { | |
return; | |
} else { | |
xhrs.splice(xhrs.indexOf(req), 1); | |
} | |
if (!needFailureReport) return; | |
handleLoaded(request, false); | |
if (remainingAttempts > 0) { | |
self.log("Failed loading fragment: " + request.mediaType + ":" + request.type + ":" + request.startTime + ", retry in " + RETRY_INTERVAL + "ms" + " attempts: " + remainingAttempts); | |
remainingAttempts--; | |
setTimeout(function() { | |
doLoad.call(self, request, remainingAttempts); | |
}, RETRY_INTERVAL); | |
} else { | |
self.log("Failed loading fragment: " + request.mediaType + ":" + request.type + ":" + request.startTime + " no retry attempts left"); | |
self.errHandler.downloadError("content", request.url, req); | |
self.notify(MediaPlayer.dependencies.FragmentLoader.eventList.ENAME_LOADING_COMPLETED, {request: request, bytes: null}, new MediaPlayer.vo.Error(null, "failed loading fragment", null)); | |
} | |
}; | |
req.send(); | |
}, | |
checkForExistence = function(request) { | |
var self = this, | |
req = new XMLHttpRequest(), | |
isSuccessful = false; | |
req.open("HEAD", request.url, true); | |
req.onload = function () { | |
if (req.status < 200 || req.status > 299) return; | |
isSuccessful = true; | |
self.notify(MediaPlayer.dependencies.FragmentLoader.eventList.ENAME_CHECK_FOR_EXISTENCE_COMPLETED, {request: request, exists: true}); | |
}; | |
req.onloadend = req.onerror = function () { | |
if (isSuccessful) return; | |
self.notify(MediaPlayer.dependencies.FragmentLoader.eventList.ENAME_CHECK_FOR_EXISTENCE_COMPLETED, {request: request, exists: false}); | |
}; | |
req.send(); | |
}; | |
return { | |
metricsModel: undefined, | |
errHandler: undefined, | |
log: undefined, | |
requestModifierExt:undefined, | |
notify: undefined, | |
subscribe: undefined, | |
unsubscribe: undefined, | |
load: function (req) { | |
if (!req) { | |
this.notify(MediaPlayer.dependencies.FragmentLoader.eventList.ENAME_LOADING_COMPLETED, {request: req, bytes: null}, new MediaPlayer.vo.Error(null, "request is null", null)); | |
} else { | |
doLoad.call(this, req, RETRY_ATTEMPTS); | |
} | |
}, | |
checkForExistence: function(req) { | |
if (!req) { | |
this.notify(MediaPlayer.dependencies.FragmentLoader.eventList.ENAME_CHECK_FOR_EXISTENCE_COMPLETED, {request: req, exists: false}); | |
return; | |
} | |
checkForExistence.call(this, req); | |
}, | |
abort: function() { | |
var i, | |
req, | |
ln = xhrs.length; | |
for (i = 0; i < ln; i +=1) { | |
req = xhrs[i]; | |
xhrs[i] = null; | |
req.abort(); | |
req = null; | |
} | |
xhrs = []; | |
} | |
}; | |
}; | |
MediaPlayer.dependencies.FragmentLoader.RETRY_ATTEMPTS = 3; | |
MediaPlayer.dependencies.FragmentLoader.RETRY_INTERVAL = 500; | |
MediaPlayer.dependencies.FragmentLoader.prototype = { | |
constructor: MediaPlayer.dependencies.FragmentLoader | |
}; | |
MediaPlayer.dependencies.FragmentLoader.eventList = { | |
ENAME_LOADING_COMPLETED: "loadingCompleted", | |
ENAME_LOADING_PROGRESS: "loadingProgress", | |
ENAME_CHECK_FOR_EXISTENCE_COMPLETED: "checkForExistenceCompleted" | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment