From 676b0131b003aa75307cb5f321b75b904010ca88 Mon Sep 17 00:00:00 2001 From: UnKnoWn Date: Sun, 17 Jan 2021 21:05:15 +0800 Subject: [PATCH 1/2] refactor!: IPFS injection done right by wrapping the loader class with a factory function BREAKING CHANGE: the main export is now a factory function that returns the loader class with IPFS dependency injected. --- src/index.js | 188 ++++++++++++++++++++++++--------------------------- 1 file changed, 89 insertions(+), 99 deletions(-) diff --git a/src/index.js b/src/index.js index 508a210..2fb34c0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,119 +1,109 @@ 'use strict' - -class HlsjsIPFSLoader { - constructor(config) { - this._abortFlag = [ false ]; - this.ipfs = config.ipfs - this.hash = config.ipfsHash - if (config.debug === false) { - this.debug = function() {} - } else if (config.debug === true) { - this.debug = console.log - } else { - this.debug = config.debug +function HlsjsIPFSLoaderFactory (ipfs) { + return class HlsjsIPFSLoader { + constructor(config) { + this._abortFlag = [false]; + this.ipfs = ipfs; + this.hash = config.ipfsHash; + this.debug = config.debug === false ? function () { + } : config.debug === true ? console.log : config.debug; + this.m3u8provider = config.m3u8provider ? config.m3u8provider : null; + this.tsListProvider = config.tsListProvider ? config.tsListProvider : null; } - if(config.m3u8provider) { - this.m3u8provider = config.m3u8provider; - } else { - this.m3u8provider = null; + + destroy() { } - if(config.tsListProvider) { - this.tsListProvider = config.tsListProvider; - } else { - this.tsListProvider = null; + + abort() { + this._abortFlag[0] = true; } - } - destroy() { - } + load(context, config, callbacks) { + this.context = context + this.config = config + this.callbacks = callbacks + this.stats = {trequest: performance.now(), retry: 0} + this.retryDelay = config.retryDelay + this.loadInternal() + } - abort() { - this._abortFlag[0] = true; - } + /** + * Call this by getting the HLSIPFSLoader instance from hls.js hls.coreComponents[0].loaders.manifest.setM3U8Provider() + * @param {function} provider + */ + setM3U8Provider(provider) { + this.m3u8provider = provider; + } - load(context, config, callbacks) { - this.context = context - this.config = config - this.callbacks = callbacks - this.stats = { trequest: performance.now(), retry: 0 } - this.retryDelay = config.retryDelay - this.loadInternal() - } - /** - * Call this by getting the HLSIPFSLoader instance from hls.js hls.coreComponents[0].loaders.manifest.setM3U8Provider() - * @param {function} provider - */ - setM3U8Provider(provider) { - this.m3u8provider = provider; - } - /** - * - * @param {function} provider - */ - setTsListProvider(provider) { - this.tsListProvider = provider; - } + /** + * + * @param {function} provider + */ + setTsListProvider(provider) { + this.tsListProvider = provider; + } - loadInternal() { - const { stats, context, callbacks } = this + loadInternal() { + const {stats, context, callbacks} = this - stats.tfirst = Math.max(performance.now(), stats.trequest) - stats.loaded = 0 + stats.tfirst = Math.max(performance.now(), stats.trequest) + stats.loaded = 0 - //When using absolute path (https://example.com/index.html) vs https://example.com/ - const urlParts = window.location.href.split("/") - if(urlParts[urlParts.length - 1] !== "") { - urlParts[urlParts.length - 1] = "" - } - const filename = context.url.replace(urlParts.join("/"), "") + //When using absolute path (https://example.com/index.html) vs https://example.com/ + const urlParts = window.location.href.split("/") + if (urlParts[urlParts.length - 1] !== "") { + urlParts[urlParts.length - 1] = "" + } + const filename = context.url.replace(urlParts.join("/"), "") - const options = {} - if (Number.isFinite(context.rangeStart)) { + const options = {} + if (Number.isFinite(context.rangeStart)) { options.offset = context.rangeStart; if (Number.isFinite(context.rangeEnd)) { - options.length = context.rangeEnd - context.rangeStart; + options.length = context.rangeEnd - context.rangeStart; } - } + } - if(filename.split(".")[1] === "m3u8" && this.m3u8provider !== null) { - const res = this.m3u8provider(); - let data; - if(Buffer.isBuffer(res)) { - data = buf2str(res) - } else { - data = res; + if (filename.split(".")[1] === "m3u8" && this.m3u8provider !== null) { + const res = this.m3u8provider(); + let data; + if (Buffer.isBuffer(res)) { + data = buf2str(res) + } else { + data = res; + } + const response = {url: context.url, data: data} + callbacks.onSuccess(response, stats, context) + return; } - const response = { url: context.url, data: data } - callbacks.onSuccess(response, stats, context) - return; - } - if(filename.split(".")[1] === "m3u8" && this.tsListProvider !== null) { - var tslist = this.tsListProvider(); - var hash = tslist[filename]; - if(hash) { - this.cat(hash).then(res => { - let data; - if(Buffer.isBuffer(res)) { - data = buf2str(res) - } else { - data = res; - } - stats.loaded = stats.total = data.length - stats.tload = Math.max(stats.tfirst, performance.now()) - const response = { url: context.url, data: data } - callbacks.onSuccess(response, stats, context) - }); + if (filename.split(".")[1] === "m3u8" && this.tsListProvider !== null) { + var tslist = this.tsListProvider(); + var hash = tslist[filename]; + if (hash) { + this.cat(hash).then(res => { + let data; + if (Buffer.isBuffer(res)) { + data = buf2str(res) + } else { + data = res; + } + stats.loaded = stats.total = data.length + stats.tload = Math.max(stats.tfirst, performance.now()) + const response = {url: context.url, data: data} + callbacks.onSuccess(response, stats, context) + }); + } + return; } - return; + this._abortFlag[0] = false; + getFile(this.ipfs, this.hash, filename, options, this.debug, this._abortFlag).then(res => { + const data = (context.responseType === 'arraybuffer') ? res : buf2str(res) + stats.loaded = stats.total = data.length + stats.tload = Math.max(stats.tfirst, performance.now()) + const response = {url: context.url, data: data} + callbacks.onSuccess(response, stats, context) + }, console.error) } - this._abortFlag[0] = false; - getFile(this.ipfs, this.hash, filename, options, this.debug, this._abortFlag).then(res => { - const data = (context.responseType === 'arraybuffer') ? res : buf2str(res) - stats.loaded = stats.total = data.length - stats.tload = Math.max(stats.tfirst, performance.now()) - const response = { url: context.url, data: data } - callbacks.onSuccess(response, stats, context) - }, console.error) } } async function getFile(ipfs, rootHash, filename, options, debug, abortFlag) { @@ -153,4 +143,4 @@ async function cat (cid, options, ipfs, debug, abortFlag) { return value } -exports = module.exports = HlsjsIPFSLoader +exports = module.exports = HlsjsIPFSLoaderFactory; From 2799c604934d5ed5553bb11f187f90509cd4dc82 Mon Sep 17 00:00:00 2001 From: UnKnoWn Date: Sun, 17 Jan 2021 21:16:26 +0800 Subject: [PATCH 2/2] docs: updated usage in example --- examples/basic_usage.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/basic_usage.html b/examples/basic_usage.html index 17ef60a..b02ef3a 100644 --- a/examples/basic_usage.html +++ b/examples/basic_usage.html @@ -18,12 +18,11 @@ function handleInit(node) { const testhash = "QmdpAidwAsBGptFB3b6A9Pyi5coEbgjHrL3K2Qrsutmj9K"; - Hls.DefaultConfig.loader = HlsjsIpfsLoader; + Hls.DefaultConfig.loader = HlsjsIPFSLoaderFactory(node); Hls.DefaultConfig.debug = false; if (Hls.isSupported()) { const video = document.getElementById('video'); const hls = new Hls(); - hls.config.ipfs = node; hls.config.ipfsHash = testhash; hls.loadSource('master.m3u8'); hls.attachMedia(video);