diff --git a/javascripts/player.js b/javascripts/player.js index 09856b0..dce6220 100644 --- a/javascripts/player.js +++ b/javascripts/player.js @@ -1,7 +1,7 @@ gateways = [ - "https://ipfs.io" + "ipfs.io" ] -shortTermGw = "https://video.dtube.top" +shortTermGatewayHost = "video.dtube.top" player = null itLoaded = false timeout = 1000 @@ -19,31 +19,43 @@ var snapGateway = path.split("/")[5] findVideo() -function findInShortTerm(hash, cb) { - const url = shortTermGw + '/ipfs/' + hash - const request = new XMLHttpRequest(); - request.open("HEAD", url, true); - request.onerror = function(e) { - console.log('Error: ' + url) - } - request.onreadystatechange = function() { - if (request.readyState === request.HEADERS_RECEIVED) { - if (request.status === 200) { - const headers = request.getAllResponseHeaders() - console.log(headers, shortTermGw) - cb(true) - } else cb() +function findInShortTerm(quality) { + return new Promise(function(resolve, reject) { + const url = generateGatewayUrl(shortTermGatewayHost, quality.hash) + const request = new XMLHttpRequest(); + + // Assume not available if it's timing out + request.timeout = 5000; + request.ontimeout = function (e) { + reject(quality) + }; + + request.open("HEAD", url, true); + request.onerror = function(e) { + console.log('Error: ' + url) + reject(quality) } - } - request.send(); + request.onreadystatechange = function() { + if (request.readyState === request.HEADERS_RECEIVED) { + if (request.status === 200) { + const headers = request.getAllResponseHeaders() + console.log(headers, shortTermGatewayHost) + resolve(quality) + } else { + reject(quality) + } + } + } + request.send(); + }) } function findVideo(retries = 3) { if (videoPermlink == 'live') { document.addEventListener("DOMContentLoaded", function() { - createLiveStream(autoplay, nobranding, null) + createLiveStream(autoplay, nobranding, null) }); - + return } @@ -66,18 +78,75 @@ function findVideo(retries = 3) { createLiveStream(autoplay, nobranding, b) } else { var qualities = generateQualities(a) - - findInShortTerm(qualities[0].hash, function(isAvail) { - addQualitiesSource(qualities, (isAvail ? shortTermGw : gateways[0])) - - // start the player - createPlayer(a.info.snaphash, autoplay, nobranding, qualities, a.info.spritehash, a.info.duration, a.content.subtitles) - }) - } + + checkQualityAvailabilityInShortTerm(qualities) + .then(function(qualities) { + addQualitiesSource(qualities, shortTermGatewayHost) + + // start the player + createPlayer(a.info.snaphash, autoplay, nobranding, qualities, a.info.spritehash, a.info.duration, a.content.subtitles) + }) + .catch(function(e) { + console.error(e.message); + }) + } }); timeout *= 2 } +/** + * Waiting for all promises to complete with a resolve or reject + * @param arr + * @returns {*} + */ +function settlePromises(arr){ + return Promise.all(arr.map(promise => { + return promise.then( + value => ({state: 'resolved', value}), + value => ({state: 'rejected', value}) + ); + })); +} + +/** + * Checks if the file for each quality is available in short term gateway and mark the status + * @param qualities + * @returns {Promise} + */ +function checkQualityAvailabilityInShortTerm(qualities) { + return new Promise(function(resolve, reject) { + var checkPromises = []; + + try { + for (var qi = 0; qi < qualities.length; qi++) { + var quality = qualities[qi] + checkPromises.push(findInShortTerm(quality)) + } + } catch(e) { + reject(e) + } + + settlePromises(checkPromises).then(function(results) { + var qualities = [] + + for (let ri=0; ri