type: 'PUT',
dropZone: options.dropZone, // restrict dropZone to content div
autoUpload: false,
+ progressInterval: 300, // increased from the default of 100ms for more stable behvaviour when predicting remaining time
sequentialUploads: false,
limitConcurrentUploads: 4,
/**
if (this._supportAjaxUploadWithProgress()) {
//remaining time
- var lastUpdate, lastSize, bufferSize, buffer, bufferIndex, bufferIndex2, bufferTotal;
+ var lastUpdate, lastSize, bufferSize, buffer, bufferIndex, bufferTotal, smoothRemainingSeconds, smoothBitrate;
var dragging = false;
// initial remaining time variables
lastUpdate = new Date().getTime();
lastSize = 0;
- bufferSize = 20;
+ bufferSize = 20; // length of the ring buffer
buffer = [];
- bufferIndex = 0;
- bufferIndex2 = 0;
+ bufferIndex = 0; // index of the ring buffer, runs from 0 to bufferSize continuously
bufferTotal = 0;
+ newTotal = 0;
+ smoothing = 0.02; // smoothing factor for EMA
+ h = '';
+ bufferFilled = false;
+
for(var i = 0; i < bufferSize; i++){
buffer[i] = 0;
}
var diffUpdate = (thisUpdate - lastUpdate)/1000; // eg. 2s
lastUpdate = thisUpdate;
var diffSize = data.loaded - lastSize;
+ if (diffSize <= 0) {
+ diffSize = lastSize;
+ }
lastSize = data.loaded;
diffSize = diffSize / diffUpdate; // apply timing factor, eg. 1MiB/2s = 0.5MiB/s, unit is byte per second
var remainingSeconds = ((total - data.loaded) / diffSize);
+
if(remainingSeconds >= 0) {
+ // bufferTotal holds the sum of all entries in the buffer, initially 0 like the entries itself
+ // substract current entry from total and add the current value to total
bufferTotal = bufferTotal - (buffer[bufferIndex]) + remainingSeconds;
+ // put current value to the entry
buffer[bufferIndex] = remainingSeconds; //buffer to make it smoother
+
bufferIndex = (bufferIndex + 1) % bufferSize;
- bufferIndex2++;
}
- var smoothRemainingSeconds;
- if (bufferIndex2 > 0 && bufferIndex2 < 20) {
- smoothRemainingSeconds = bufferTotal / bufferIndex2;
- } else if (bufferSize > 0) {
+ if (bufferIndex === bufferSize - 1) {
+ bufferFilled = true;
+ }
+ //console.log('#', ' idx: ',bufferIndex, ' Total: ', bufferTotal, ' remainSeconds: ', remainingSeconds, ' during: ', diffUpdate);
+
+ if (smoothRemainingSeconds === null) {
smoothRemainingSeconds = bufferTotal / bufferSize;
- } else {
- smoothRemainingSeconds = 1;
+ } else{
+ smoothRemainingSeconds = smoothing * (bufferTotal / bufferSize) + ((1-smoothing) * smoothRemainingSeconds);
+ }
+
+ if (bufferIndex % 4 === 0) {
+ h = moment.duration(smoothRemainingSeconds, "seconds").humanize({m: 50, h: 50});
}
- var h = moment.duration(smoothRemainingSeconds, "seconds").humanize();
- if (!(smoothRemainingSeconds >= 0 && smoothRemainingSeconds < 14400)) {
+ // wait for the buffer to be at least half filled, approximately takes 3s
+ if (!(smoothRemainingSeconds >= 0 && smoothRemainingSeconds < 14400) || (bufferFilled == false && bufferIndex < bufferSize/2)) {
// show "Uploading ..." for durations longer than 4 hours
h = t('files', 'Uploading …');
}
+
+ // smooth bitrate
+ if (smoothBitrate === null) {
+ smoothBitrate = data.bitrate;
+ } else{
+ smoothBitrate = smoothing * data.bitrate + ((1-smoothing) * smoothBitrate);
+ }
+
self._setProgressBarText(h, h, t('files', '{loadedSize} of {totalSize} ({bitrate})' , {
loadedSize: OC.Util.humanFileSize(data.loaded),
totalSize: OC.Util.humanFileSize(total),
- bitrate: OC.Util.humanFileSize(data.bitrate / 8) + '/s'
+ bitrate: OC.Util.humanFileSize(smoothBitrate / 8) + '/s'
}));
self._setProgressBarValue(progress);
self.trigger('progressall', e, data);