progress
http://www.w3.org/TR/progress-events/
http://www.w3.org/TR/XMLHttpRequest/
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
function makeXHR(buf, url, start, end, init_ref, is_init, is_index) {
dlog(3, "leosu add ....... makeXHR");
var xhr = new XMLHttpRequest();
var range = mkrange(start, end);
var useArg = !!/youtube.com/.exec(url)
if (range && useArg) {
url = url.replace(/&range=[^&]*/, '');
url += '&range=' + range.substring(6);
}
xhr.open("GET", url);
xhr.responseType = 'arraybuffer';
xhr.startByte = start;
if (range != null && !useArg) xhr.setRequestHeader('Range', range);
xhr.addEventListener('load', onXHRLoad);
if (url == null) throw "Null URL";
buf.url = url;
xhr.buf = buf;
xhr.init = init_ref;
xhr.is_init = is_init;
xhr.is_index = is_index;
buf.xhr = xhr;
xhr.lastTime = null;
xhr.lastSize = null;
xhr.addEventListener('progress', onXHRProgress);
xhr.send();
dlog(2, 'Sent XHR: url=' + url + ', range=' + range + 'start=' + start + 'end= ' + end);
return xhr;
}
function onXHRLoad(evt) {
dlog(3, "leosu add ....... onXHRLoad");
var xhr = evt.target;
var buf = xhr.buf;
buf.xhr = null;
var vid = buf.video;
if (xhr.readyState != xhr.DONE) return;
if (xhr.status >= 300) {
log('XHR failure, status=' + xhr.status);
throw 'TODO: retry XHRs on failure';
}
if (xhr.is_init) {
xhr.init.value = new Uint8Array(xhr.response);
}
if (xhr.is_index) {
var index = new player.dash.SegmentIndex();
buf.reps[buf.currentRep].index = index;
if (buf.mime.indexOf('mp4') >= 0) {
index.parseSidx(xhr.response, xhr.startByte);
} else {
index.parseWebM(xhr.init.value.buffer, xhr.response);
}
// We need the index before we append the init.
if (buf.last_init == null) appendInit(buf, xhr.init);
}
if (xhr.is_init || xhr.is_index) {
return;
}
if (buf.last_init !== xhr.init) {
appendInit(buf, xhr.init);
}
queueAppend(buf, xhr.response);
buf.segIdx++;
if (buf.segIdx >= buf.reps[buf.currentRep].index.getCount()) {
buf.active = false;
}
if (xhr.expected_time != null && !buf.appendBuffer) {
// The expected time is the start time of the first buffer in this sequence.
// This check ensures that media data append time is (roughly) reflected in
// the buffered range.
range = findRangeForPlaybackTime(buf, xhr.expected_time);
if (range == null ||
!(range.start <= xhr.expected_time && range.end >= xhr.expected_time)) {
log('Media data expected time not reflected in updated buffer range. ' +
'MSE implementation bug?');
if (range == null) {
dlog(2, 'Reason: range is null');
} else {
dlog(2, 'Reason: expected time ' + xhr.expected_time + ' not in (' +
range.start + ', ' + range.end + ')');
}
}
}
}
function onXHRProgress(evt) {
dlog(3, "leosu add ....... onXHRProgress");
var xhr = evt.target;
if (xhr.lastTime != null && evt.timeStamp != xhr.lastTime) {
var bw = 8000 * (evt.loaded - xhr.lastSize) / (evt.timeStamp - xhr.lastTime);
globalSlowBandwidth = kSlowEWMACoeff * globalSlowBandwidth + (1 - kSlowEWMACoeff) * bw;
globalFastBandwidth = kFastEWMACoeff * globalFastBandwidth + (1 - kFastEWMACoeff) * bw;
}
xhr.lastTime = evt.timeStamp;
xhr.lastSize = evt.loaded;
}
4 Interface XMLHttpRequest
[NoInterfaceObject] interface XMLHttpRequestEventTarget : EventTarget { // event handlers attribute EventHandler onloadstart; attribute EventHandler onprogress; attribute EventHandler onabort; attribute EventHandler onerror; attribute EventHandler onload; attribute EventHandler ontimeout; attribute EventHandler onloadend; }; interface XMLHttpRequestUpload : XMLHttpRequestEventTarget { }; enum XMLHttpRequestResponseType { "", "arraybuffer", "blob", "document", "json", "text" }; [Constructor] interface XMLHttpRequest : XMLHttpRequestEventTarget { // event handler attribute EventHandler onreadystatechange; // states const unsigned short UNSENT = 0; const unsigned short OPENED = 1; const unsigned short HEADERS_RECEIVED = 2; const unsigned short LOADING = 3; const unsigned short DONE = 4; readonly attribute unsigned short readyState; // request void open(ByteString method, [EnsureUTF16] DOMString url); void open(ByteString method, [EnsureUTF16] DOMString url, boolean async, optional [EnsureUTF16] DOMString? username = null, optional [EnsureUTF16] DOMString? password = null); void setRequestHeader(ByteString header, ByteString value); attribute unsigned long timeout; attribute boolean withCredentials; readonly attribute XMLHttpRequestUpload upload; void send(optional (ArrayBufferView or Blob or Document or [EnsureUTF16] DOMString or FormData)? data = null); void abort(); // response readonly attribute unsigned short status; readonly attribute ByteString statusText; ByteString? getResponseHeader(ByteString header); ByteString getAllResponseHeaders(); void overrideMimeType(DOMString mime); attribute XMLHttpRequestResponseType responseType; readonly attribute any response; readonly attribute DOMString responseText; readonly attribute Document? responseXML; };
Each XMLHttpRequest object has a unique, associated XMLHttpRequestUpload object.
4.3 Suggested names for events using the ProgressEvent interface
This section is non-normative.
The suggested type attribute values for use with events using the ProgressEvent interface are summarized in the table below. Specification editors are free to tune the details to their specific scenarios, though are strongly encouraged to discuss their usage with the W3C WebApps Working Group on public-webapps@w3.org to ensure input from people familiar with the subject.
type attribute value | Description | Times | When |
|---|---|---|---|
loadstart | Progress has begun. | Once. | First. |
progress | In progress. | Zero or more. | After loadstart has been dispatched. |
error | Progression failed. | Zero or once. | After the last progress has been dispatched, or after loadstart has been dispatched if progress has not been dispatched. |
abort | Progression is terminated. | Zero or once. | |
load | Progression is successful. | Zero or once. | |
loadend | Progress has stopped. | Once. | After one of error, abort, or load has been dispatched. |
The error, abort, and load event types are mutually exclusive.
Throughout the web platform the error, abort, and load event types have their bubbles and cancelable attributes initialized to false, so it is suggested that for consistency all events using the ProgressEvent interface do the same.

本文详细介绍了XMLHttpRequest (XHR) 的使用方法及Progress事件的工作原理。包括如何通过XHR进行文件片段下载、进度跟踪以及错误处理等关键操作。此外,还探讨了如何利用Progress事件接口监测加载进度,并给出了具体实现代码。
960

被折叠的 条评论
为什么被折叠?



