@checksub_team/peaks_timeline
Version:
JavaScript UI component for displaying audio waveforms
127 lines (107 loc) • 3.51 kB
JavaScript
/**
* @file
*
* Retrieving functions for external or internal media data.
*
* @module data-retriever
*/
define([
'./data',
'../utils'
], function(Data, Utils) {
'use strict';
/**
* Creates a DataRetriever that will look for and download sources data.
*
* @class
* @alias DataRetriever
*
* @param {Peaks} peaks
*/
function DataRetriever(peaks) {
this._peaks = peaks;
this._data = {};
this._waitingForData = {};
}
/**
* Retrieves data for the given source.
*
* @param {Source} options
*/
DataRetriever.prototype.retrieveData = function(source) {
this._retrieveDataByUrl(source, source.previewUrl);
// If waveformData is supplied on the source, prefer it over
// remote/binary waveform retrieval.
if (!source.waveformData) {
this._retrieveDataByUrl(source, source.binaryUrl);
}
};
DataRetriever.prototype._retrieveDataByUrl = function(source, url) {
if (url && url !== '') {
if (!this._data[url]) {
this._retireveDataOnline(source, url);
}
else {
if (this._data[url].isComplete()) {
this._peaks.emit('data.retrieved', this._data[url], source, url);
}
else {
this._waitingForData[url].push(source);
}
}
}
};
DataRetriever.prototype._retireveDataOnline = function(source, url) {
var data = new Data();
this._data[url] = data;
this._waitingForData[url] = [source];
this._fetch(url, data, 2000, 3);
};
DataRetriever.prototype._fetch = function(url, data, delay, limit) {
var self = this;
function later(delay) {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
function recur(timesTried, err) {
if (timesTried >= limit) {
return Promise.reject(err);
}
return fetch(url)
.then(function(response) {
if (!response.ok) {
throw new Error('HTTP ' + response.status + ': ' + response.statusText);
}
return response.blob();
})
.then(function(blob) {
if (Utils.isNullOrUndefined(blob)) {
throw new Error('Failed to retrieve blob');
}
var type = blob.type;
if (type) {
type = type.split('/')[0];
}
else {
type = 'other';
}
data.type = type;
data.content = URL.createObjectURL(blob);
if (self._waitingForData[url]) {
self._waitingForData[url].forEach(function(src) {
self._peaks.emit('data.retrieved', data, src, url);
});
}
})
.catch(function(err) {
return later(delay)
.then(function() {
return recur(timesTried + 1, err);
});
});
}
return recur(0);
};
return DataRetriever;
});