p2p-media-loader-core
Advanced tools
Comparing version 0.6.1 to 0.6.2
@@ -17,14 +17,5 @@ "use strict"; | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Debug = require("debug"); | ||
const stringly_typed_event_emitter_1 = require("./stringly-typed-event-emitter"); | ||
const loader_interface_1 = require("./loader-interface"); | ||
class HttpMediaManager extends stringly_typed_event_emitter_1.STEEmitter { | ||
@@ -48,2 +39,3 @@ constructor(settings) { | ||
this.debug("http segment download", segmentUrl); | ||
segment.requestUrl = segmentUrl; | ||
const xhr = new XMLHttpRequest(); | ||
@@ -106,5 +98,5 @@ xhr.open("GET", segmentUrl, true); | ||
}); | ||
xhr.addEventListener("load", (event) => __awaiter(this, void 0, void 0, function* () { | ||
xhr.addEventListener("load", async (event) => { | ||
if ((event.target.status < 200) || (event.target.status >= 300)) { | ||
this.segmentFailure(segment, event); | ||
this.segmentFailure(segment, event, xhr); | ||
return; | ||
@@ -127,28 +119,28 @@ } | ||
} | ||
yield this.segmentDownloadFinished(segment, data); | ||
})); | ||
await this.segmentDownloadFinished(segment, data, xhr); | ||
}); | ||
xhr.addEventListener("error", (event) => { | ||
this.segmentFailure(segment, event); | ||
this.segmentFailure(segment, event, xhr); | ||
}); | ||
xhr.addEventListener("timeout", (event) => { | ||
this.segmentFailure(segment, event); | ||
this.segmentFailure(segment, event, xhr); | ||
}); | ||
} | ||
segmentDownloadFinished(segment, data) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.settings.segmentValidator) { | ||
try { | ||
yield this.settings.segmentValidator(new loader_interface_1.Segment(segment.id, segment.url, segment.masterSwarmId, segment.masterManifestUri, segment.streamId, segment.sequence, segment.range, segment.priority, data), "http"); | ||
} | ||
catch (error) { | ||
this.debug("segment validator failed", error); | ||
this.segmentFailure(segment, error); | ||
return; | ||
} | ||
async segmentDownloadFinished(segment, data, xhr) { | ||
segment.responseUrl = xhr.responseURL === null ? undefined : xhr.responseURL; | ||
if (this.settings.segmentValidator) { | ||
try { | ||
await this.settings.segmentValidator(Object.assign(Object.assign({}, segment), { data: data }), "http"); | ||
} | ||
this.xhrRequests.delete(segment.id); | ||
this.emit("segment-loaded", segment, data); | ||
}); | ||
catch (error) { | ||
this.debug("segment validator failed", error); | ||
this.segmentFailure(segment, error, xhr); | ||
return; | ||
} | ||
} | ||
this.xhrRequests.delete(segment.id); | ||
this.emit("segment-loaded", segment, data); | ||
} | ||
segmentFailure(segment, error) { | ||
segmentFailure(segment, error, xhr) { | ||
segment.responseUrl = xhr.responseURL === null ? undefined : xhr.responseURL; | ||
this.xhrRequests.delete(segment.id); | ||
@@ -155,0 +147,0 @@ this.failedSegments.set(segment.id, this.now() + this.settings.httpFailedSegmentTimeout); |
@@ -17,10 +17,2 @@ "use strict"; | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -68,3 +60,3 @@ const Debug = require("debug"); | ||
this.httpDownloadInitialTimeoutTimestamp = -Infinity; | ||
this.processInitialSegmentTimeout = () => __awaiter(this, void 0, void 0, function* () { | ||
this.processInitialSegmentTimeout = async () => { | ||
if (this.httpRandomDownloadInterval === undefined) { | ||
@@ -74,3 +66,3 @@ return; // Instance destroyed | ||
if (this.masterSwarmId !== undefined) { | ||
const storageSegments = yield this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
const storageSegments = await this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
if (this.processSegmentsQueue(storageSegments) && !this.settings.consumeOnly) { | ||
@@ -84,4 +76,4 @@ this.p2pManager.sendSegmentsMapToAll(this.createSegmentsMap(storageSegments)); | ||
} | ||
}); | ||
this.downloadRandomSegmentOverHttp = () => __awaiter(this, void 0, void 0, function* () { | ||
}; | ||
this.downloadRandomSegmentOverHttp = async () => { | ||
if (this.masterSwarmId === undefined || | ||
@@ -95,3 +87,3 @@ this.httpRandomDownloadInterval === undefined || | ||
} | ||
const storageSegments = yield this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
const storageSegments = await this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
const segmentsMap = this.p2pManager.getOvrallSegmentsMap(); | ||
@@ -114,3 +106,3 @@ const pendingQueue = this.segmentsQueue.filter(s => !this.p2pManager.isDownloading(s) && | ||
this.p2pManager.sendSegmentsMapToAll(this.createSegmentsMap(storageSegments)); | ||
}); | ||
}; | ||
this.onPieceBytesDownloaded = (method, bytes, peerId) => { | ||
@@ -123,3 +115,3 @@ this.bandwidthApproximator.addBytes(bytes, this.now()); | ||
}; | ||
this.onSegmentLoaded = (segment, data, peerId) => __awaiter(this, void 0, void 0, function* () { | ||
this.onSegmentLoaded = async (segment, data, peerId) => { | ||
this.debugSegments("segment loaded", segment.id, segment.url); | ||
@@ -131,6 +123,6 @@ if (this.masterSwarmId === undefined) { | ||
segment.downloadBandwidth = this.bandwidthApproximator.getBandwidth(this.now()); | ||
yield this.segmentsStorage.storeSegment(segment); | ||
await this.segmentsStorage.storeSegment(segment); | ||
this.emit(loader_interface_1.Events.SegmentLoaded, segment, peerId); | ||
let storageSegments; | ||
storageSegments = (storageSegments === undefined ? yield this.segmentsStorage.getSegmentsMap(this.masterSwarmId) : storageSegments); | ||
storageSegments = (storageSegments === undefined ? await this.segmentsStorage.getSegmentsMap(this.masterSwarmId) : storageSegments); | ||
this.processSegmentsQueue(storageSegments); | ||
@@ -140,8 +132,8 @@ if (!this.settings.consumeOnly) { | ||
} | ||
}); | ||
this.onSegmentError = (segment, details, peerId) => __awaiter(this, void 0, void 0, function* () { | ||
}; | ||
this.onSegmentError = async (segment, details, peerId) => { | ||
this.debugSegments("segment error", segment.id, segment.url, peerId, details); | ||
this.emit(loader_interface_1.Events.SegmentError, segment, details, peerId); | ||
if (this.masterSwarmId !== undefined) { | ||
const storageSegments = yield this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
const storageSegments = await this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
if (this.processSegmentsQueue(storageSegments) && !this.settings.consumeOnly) { | ||
@@ -151,13 +143,13 @@ this.p2pManager.sendSegmentsMapToAll(this.createSegmentsMap(storageSegments)); | ||
} | ||
}); | ||
this.onPeerConnect = (peer) => __awaiter(this, void 0, void 0, function* () { | ||
}; | ||
this.onPeerConnect = async (peer) => { | ||
this.emit(loader_interface_1.Events.PeerConnect, peer); | ||
if (!this.settings.consumeOnly && this.masterSwarmId !== undefined) { | ||
this.p2pManager.sendSegmentsMap(peer.id, this.createSegmentsMap(yield this.segmentsStorage.getSegmentsMap(this.masterSwarmId))); | ||
this.p2pManager.sendSegmentsMap(peer.id, this.createSegmentsMap(await this.segmentsStorage.getSegmentsMap(this.masterSwarmId))); | ||
} | ||
}); | ||
}; | ||
this.onPeerClose = (peerId) => { | ||
this.emit(loader_interface_1.Events.PeerClose, peerId); | ||
}; | ||
this.onTrackerUpdate = (data) => __awaiter(this, void 0, void 0, function* () { | ||
this.onTrackerUpdate = async (data) => { | ||
if (this.httpDownloadInitialTimeoutTimestamp !== -Infinity && | ||
@@ -168,3 +160,3 @@ data.incomplete !== undefined && data.incomplete <= 1) { | ||
if (this.masterSwarmId !== undefined) { | ||
const storageSegments = yield this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
const storageSegments = await this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
if (this.processSegmentsQueue(storageSegments) && !this.settings.consumeOnly) { | ||
@@ -175,4 +167,4 @@ this.p2pManager.sendSegmentsMapToAll(this.createSegmentsMap(storageSegments)); | ||
} | ||
}); | ||
this.settings = Object.assign({}, defaultSettings, settings); | ||
}; | ||
this.settings = Object.assign(Object.assign({}, defaultSettings), settings); | ||
if (settings.bufferedSegmentsCount) { | ||
@@ -198,11 +190,11 @@ if (settings.p2pDownloadMaxPriority === undefined) { | ||
this.p2pManager.on("segment-error", this.onSegmentError); | ||
this.p2pManager.on("peer-data-updated", () => __awaiter(this, void 0, void 0, function* () { | ||
this.p2pManager.on("peer-data-updated", async () => { | ||
if (this.masterSwarmId === undefined) { | ||
return; | ||
} | ||
const storageSegments = yield this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
const storageSegments = await this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
if (this.processSegmentsQueue(storageSegments) && !this.settings.consumeOnly) { | ||
this.p2pManager.sendSegmentsMapToAll(this.createSegmentsMap(storageSegments)); | ||
} | ||
})); | ||
}); | ||
this.p2pManager.on("bytes-downloaded", (bytes, peerId) => this.onPieceBytesDownloaded("p2p", bytes, peerId)); | ||
@@ -224,63 +216,59 @@ this.p2pManager.on("bytes-uploaded", (bytes, peerId) => this.onPieceBytesUploaded("p2p", bytes, peerId)); | ||
} | ||
load(segments, streamSwarmId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.httpRandomDownloadInterval === undefined) { // Do once on first call | ||
this.httpRandomDownloadInterval = setInterval(this.downloadRandomSegmentOverHttp, this.settings.httpDownloadProbabilityInterval); | ||
if (this.settings.httpDownloadInitialTimeout > 0 && this.settings.httpDownloadInitialTimeoutPerSegment > 0) { | ||
// Initialize initial HTTP download timeout (i.e. download initial segments over P2P) | ||
this.debugSegments("enable initial HTTP download timeout", this.settings.httpDownloadInitialTimeout, "per segment", this.settings.httpDownloadInitialTimeoutPerSegment); | ||
this.httpDownloadInitialTimeoutTimestamp = this.now(); | ||
setTimeout(this.processInitialSegmentTimeout, this.settings.httpDownloadInitialTimeoutPerSegment + 100); | ||
} | ||
async load(segments, streamSwarmId) { | ||
if (this.httpRandomDownloadInterval === undefined) { // Do once on first call | ||
this.httpRandomDownloadInterval = setInterval(this.downloadRandomSegmentOverHttp, this.settings.httpDownloadProbabilityInterval); | ||
if (this.settings.httpDownloadInitialTimeout > 0 && this.settings.httpDownloadInitialTimeoutPerSegment > 0) { | ||
// Initialize initial HTTP download timeout (i.e. download initial segments over P2P) | ||
this.debugSegments("enable initial HTTP download timeout", this.settings.httpDownloadInitialTimeout, "per segment", this.settings.httpDownloadInitialTimeoutPerSegment); | ||
this.httpDownloadInitialTimeoutTimestamp = this.now(); | ||
setTimeout(this.processInitialSegmentTimeout, this.settings.httpDownloadInitialTimeoutPerSegment + 100); | ||
} | ||
if (segments.length > 0) { | ||
this.masterSwarmId = segments[0].masterSwarmId; | ||
} | ||
if (this.masterSwarmId !== undefined) { | ||
this.p2pManager.setStreamSwarmId(streamSwarmId, this.masterSwarmId); | ||
} | ||
this.debug("load segments"); | ||
let updateSegmentsMap = false; | ||
// stop all http requests and p2p downloads for segments that are not in the new load | ||
for (const segment of this.segmentsQueue) { | ||
if (!segments.find(f => f.url == segment.url)) { | ||
this.debug("remove segment", segment.url); | ||
if (this.httpManager.isDownloading(segment)) { | ||
updateSegmentsMap = true; | ||
this.httpManager.abort(segment); | ||
} | ||
else { | ||
this.p2pManager.abort(segment); | ||
} | ||
this.emit(loader_interface_1.Events.SegmentAbort, segment); | ||
} | ||
if (segments.length > 0) { | ||
this.masterSwarmId = segments[0].masterSwarmId; | ||
} | ||
if (this.masterSwarmId !== undefined) { | ||
this.p2pManager.setStreamSwarmId(streamSwarmId, this.masterSwarmId); | ||
} | ||
this.debug("load segments"); | ||
let updateSegmentsMap = false; | ||
// stop all http requests and p2p downloads for segments that are not in the new load | ||
for (const segment of this.segmentsQueue) { | ||
if (!segments.find(f => f.url == segment.url)) { | ||
this.debug("remove segment", segment.url); | ||
if (this.httpManager.isDownloading(segment)) { | ||
updateSegmentsMap = true; | ||
this.httpManager.abort(segment); | ||
} | ||
else { | ||
this.p2pManager.abort(segment); | ||
} | ||
this.emit(loader_interface_1.Events.SegmentAbort, segment); | ||
} | ||
if (this.debug.enabled) { | ||
for (const segment of segments) { | ||
if (!this.segmentsQueue.find(f => f.url == segment.url)) { | ||
this.debug("add segment", segment.url); | ||
} | ||
} | ||
if (this.debug.enabled) { | ||
for (const segment of segments) { | ||
if (!this.segmentsQueue.find(f => f.url == segment.url)) { | ||
this.debug("add segment", segment.url); | ||
} | ||
} | ||
this.segmentsQueue = segments; | ||
if (this.masterSwarmId === undefined) { | ||
return; | ||
} | ||
let storageSegments = yield this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
updateSegmentsMap = (this.processSegmentsQueue(storageSegments) || updateSegmentsMap); | ||
if (yield this.cleanSegmentsStorage()) { | ||
storageSegments = yield this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
updateSegmentsMap = true; | ||
} | ||
if (updateSegmentsMap && !this.settings.consumeOnly) { | ||
this.p2pManager.sendSegmentsMapToAll(this.createSegmentsMap(storageSegments)); | ||
} | ||
}); | ||
} | ||
this.segmentsQueue = segments; | ||
if (this.masterSwarmId === undefined) { | ||
return; | ||
} | ||
let storageSegments = await this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
updateSegmentsMap = (this.processSegmentsQueue(storageSegments) || updateSegmentsMap); | ||
if (await this.cleanSegmentsStorage()) { | ||
storageSegments = await this.segmentsStorage.getSegmentsMap(this.masterSwarmId); | ||
updateSegmentsMap = true; | ||
} | ||
if (updateSegmentsMap && !this.settings.consumeOnly) { | ||
this.p2pManager.sendSegmentsMapToAll(this.createSegmentsMap(storageSegments)); | ||
} | ||
} | ||
getSegment(id) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.masterSwarmId === undefined | ||
? undefined | ||
: this.segmentsStorage.getSegment(id, this.masterSwarmId); | ||
}); | ||
async getSegment(id) { | ||
return this.masterSwarmId === undefined | ||
? undefined | ||
: this.segmentsStorage.getSegment(id, this.masterSwarmId); | ||
} | ||
@@ -295,15 +283,13 @@ getSettings() { | ||
} | ||
destroy() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.httpRandomDownloadInterval !== undefined) { | ||
clearInterval(this.httpRandomDownloadInterval); | ||
this.httpRandomDownloadInterval = undefined; | ||
} | ||
this.httpDownloadInitialTimeoutTimestamp = -Infinity; | ||
this.segmentsQueue = []; | ||
this.httpManager.destroy(); | ||
this.p2pManager.destroy(); | ||
this.masterSwarmId = undefined; | ||
yield this.segmentsStorage.destroy(); | ||
}); | ||
async destroy() { | ||
if (this.httpRandomDownloadInterval !== undefined) { | ||
clearInterval(this.httpRandomDownloadInterval); | ||
this.httpRandomDownloadInterval = undefined; | ||
} | ||
this.httpDownloadInitialTimeoutTimestamp = -Infinity; | ||
this.segmentsQueue = []; | ||
this.httpManager.destroy(); | ||
this.p2pManager.destroy(); | ||
this.masterSwarmId = undefined; | ||
await this.segmentsStorage.destroy(); | ||
} | ||
@@ -422,9 +408,7 @@ processSegmentsQueue(storageSegments) { | ||
} | ||
cleanSegmentsStorage() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.masterSwarmId === undefined) { | ||
return false; | ||
} | ||
return this.segmentsStorage.clean(this.masterSwarmId, (id) => this.segmentsQueue.find(queueSegment => queueSegment.id === id) !== undefined); | ||
}); | ||
async cleanSegmentsStorage() { | ||
if (this.masterSwarmId === undefined) { | ||
return false; | ||
} | ||
return this.segmentsStorage.clean(this.masterSwarmId, (id) => this.segmentsQueue.find(queueSegment => queueSegment.id === id) !== undefined); | ||
} | ||
@@ -431,0 +415,0 @@ now() { |
@@ -17,4 +17,4 @@ /** | ||
*/ | ||
export declare const version = "0.6.1"; | ||
export declare const version = "0.6.2"; | ||
export * from "./loader-interface"; | ||
export * from "./hybrid-loader"; |
@@ -22,4 +22,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.version = "0.6.1"; | ||
exports.version = "0.6.2"; | ||
__export(require("./loader-interface")); | ||
__export(require("./hybrid-loader")); |
@@ -16,3 +16,3 @@ /** | ||
*/ | ||
export declare class Segment { | ||
export interface Segment { | ||
readonly id: string; | ||
@@ -24,7 +24,8 @@ readonly url: string; | ||
readonly sequence: string; | ||
readonly range?: string | undefined; | ||
readonly range: string | undefined; | ||
readonly priority: number; | ||
data?: ArrayBuffer | undefined; | ||
downloadBandwidth: number; | ||
constructor(id: string, url: string, masterSwarmId: string, masterManifestUri: string, streamId: string | undefined, sequence: string, range?: string | undefined, priority?: number, data?: ArrayBuffer | undefined, downloadBandwidth?: number); | ||
data?: ArrayBuffer; | ||
downloadBandwidth?: number; | ||
requestUrl?: string; | ||
responseUrl?: string; | ||
} | ||
@@ -31,0 +32,0 @@ export declare enum Events { |
@@ -18,17 +18,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class Segment { | ||
constructor(id, url, masterSwarmId, masterManifestUri, streamId, sequence, range, priority = 0, data, downloadBandwidth = 0) { | ||
this.id = id; | ||
this.url = url; | ||
this.masterSwarmId = masterSwarmId; | ||
this.masterManifestUri = masterManifestUri; | ||
this.streamId = streamId; | ||
this.sequence = sequence; | ||
this.range = range; | ||
this.priority = priority; | ||
this.data = data; | ||
this.downloadBandwidth = downloadBandwidth; | ||
} | ||
} | ||
exports.Segment = Segment; | ||
var Events; | ||
@@ -35,0 +20,0 @@ (function (Events) { |
@@ -17,10 +17,2 @@ "use strict"; | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -30,3 +22,2 @@ const Debug = require("debug"); | ||
const stringly_typed_event_emitter_1 = require("./stringly-typed-event-emitter"); | ||
const loader_interface_1 = require("./loader-interface"); | ||
const media_peer_1 = require("./media-peer"); | ||
@@ -156,7 +147,7 @@ const buffer_1 = require("buffer"); | ||
}; | ||
this.onSegmentRequest = (peer, segmentId) => __awaiter(this, void 0, void 0, function* () { | ||
this.onSegmentRequest = async (peer, segmentId) => { | ||
if (this.masterSwarmId === undefined) { | ||
return; | ||
} | ||
const segment = yield this.sementsStorage.getSegment(segmentId, this.masterSwarmId); | ||
const segment = await this.sementsStorage.getSegment(segmentId, this.masterSwarmId); | ||
if (segment) { | ||
@@ -168,4 +159,4 @@ peer.sendSegmentData(segmentId, segment.data); | ||
} | ||
}); | ||
this.onSegmentLoaded = (peer, segmentId, data) => __awaiter(this, void 0, void 0, function* () { | ||
}; | ||
this.onSegmentLoaded = async (peer, segmentId, data) => { | ||
const peerSegmentRequest = this.peerSegmentRequests.get(segmentId); | ||
@@ -178,3 +169,3 @@ if (!peerSegmentRequest) { | ||
try { | ||
yield this.settings.segmentValidator(new loader_interface_1.Segment(segment.id, segment.url, segment.masterSwarmId, segment.masterManifestUri, segment.streamId, segment.sequence, segment.range, segment.priority, data), "p2p", peer.id); | ||
await this.settings.segmentValidator(Object.assign(Object.assign({}, segment), { data: data }), "p2p", peer.id); | ||
} | ||
@@ -191,3 +182,3 @@ catch (error) { | ||
this.emit("segment-loaded", segment, data, peer.id); | ||
}); | ||
}; | ||
this.onSegmentAbsent = (peer, segmentId) => { | ||
@@ -225,29 +216,27 @@ this.peerSegmentRequests.delete(segmentId); | ||
} | ||
setStreamSwarmId(streamSwarmId, masterSwarmId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.streamSwarmId === streamSwarmId) { | ||
return; | ||
} | ||
this.destroy(true); | ||
this.streamSwarmId = streamSwarmId; | ||
this.masterSwarmId = masterSwarmId; | ||
this.debug("stream swarm ID", this.streamSwarmId); | ||
this.pendingTrackerClient = { | ||
isDestroyed: false | ||
}; | ||
const pendingTrackerClient = this.pendingTrackerClient; | ||
// TODO: native browser 'crypto.subtle' implementation doesn't work in Chrome in insecure pages | ||
// TODO: Edge doesn't support SHA-1. Change to SHA-256 once Edge support is required. | ||
// const infoHash = await crypto.subtle.digest("SHA-1", new TextEncoder().encode(PEER_PROTOCOL_VERSION + this.streamSwarmId)); | ||
const infoHash = new sha1().update(PEER_PROTOCOL_VERSION + this.streamSwarmId).digest(); | ||
// destroy may be called while waiting for the hash to be calculated | ||
if (!pendingTrackerClient.isDestroyed) { | ||
this.pendingTrackerClient = null; | ||
this.createClient(infoHash); | ||
} | ||
else if (this.trackerClient != null) { | ||
this.trackerClient.destroy(); | ||
this.trackerClient = null; | ||
} | ||
}); | ||
async setStreamSwarmId(streamSwarmId, masterSwarmId) { | ||
if (this.streamSwarmId === streamSwarmId) { | ||
return; | ||
} | ||
this.destroy(true); | ||
this.streamSwarmId = streamSwarmId; | ||
this.masterSwarmId = masterSwarmId; | ||
this.debug("stream swarm ID", this.streamSwarmId); | ||
this.pendingTrackerClient = { | ||
isDestroyed: false | ||
}; | ||
const pendingTrackerClient = this.pendingTrackerClient; | ||
// TODO: native browser 'crypto.subtle' implementation doesn't work in Chrome in insecure pages | ||
// TODO: Edge doesn't support SHA-1. Change to SHA-256 once Edge support is required. | ||
// const infoHash = await crypto.subtle.digest("SHA-1", new TextEncoder().encode(PEER_PROTOCOL_VERSION + this.streamSwarmId)); | ||
const infoHash = new sha1().update(PEER_PROTOCOL_VERSION + this.streamSwarmId).digest(); | ||
// destroy may be called while waiting for the hash to be calculated | ||
if (!pendingTrackerClient.isDestroyed) { | ||
this.pendingTrackerClient = null; | ||
this.createClient(infoHash); | ||
} | ||
else if (this.trackerClient != null) { | ||
this.trackerClient.destroy(); | ||
this.trackerClient = null; | ||
} | ||
} | ||
@@ -254,0 +243,0 @@ createClient(infoHash) { |
@@ -17,10 +17,2 @@ "use strict"; | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -32,65 +24,53 @@ class SegmentsMemoryStorage { | ||
} | ||
storeSegment(segment) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.cache.set(segment.id, { segment, lastAccessed: performance.now() }); | ||
}); | ||
async storeSegment(segment) { | ||
this.cache.set(segment.id, { segment, lastAccessed: performance.now() }); | ||
} | ||
getSegmentsMap(masterSwarmId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.cache; | ||
}); | ||
async getSegmentsMap(masterSwarmId) { | ||
return this.cache; | ||
} | ||
getSegment(id, masterSwarmId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const cacheItem = this.cache.get(id); | ||
if (cacheItem === undefined) { | ||
return undefined; | ||
} | ||
cacheItem.lastAccessed = performance.now(); | ||
return cacheItem.segment; | ||
}); | ||
async getSegment(id, masterSwarmId) { | ||
const cacheItem = this.cache.get(id); | ||
if (cacheItem === undefined) { | ||
return undefined; | ||
} | ||
cacheItem.lastAccessed = performance.now(); | ||
return cacheItem.segment; | ||
} | ||
hasSegment(id, masterSwarmId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.cache.has(id); | ||
}); | ||
async hasSegment(id, masterSwarmId) { | ||
return this.cache.has(id); | ||
} | ||
clean(masterSwarmId, lockedSementsfilter) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const segmentsToDelete = []; | ||
const remainingSegments = []; | ||
// Delete old segments | ||
const now = performance.now(); | ||
for (const cachedSegment of this.cache.values()) { | ||
if (now - cachedSegment.lastAccessed > this.settings.cachedSegmentExpiration) { | ||
async clean(masterSwarmId, lockedSementsfilter) { | ||
const segmentsToDelete = []; | ||
const remainingSegments = []; | ||
// Delete old segments | ||
const now = performance.now(); | ||
for (const cachedSegment of this.cache.values()) { | ||
if (now - cachedSegment.lastAccessed > this.settings.cachedSegmentExpiration) { | ||
segmentsToDelete.push(cachedSegment.segment.id); | ||
} | ||
else { | ||
remainingSegments.push(cachedSegment); | ||
} | ||
} | ||
// Delete segments over cached count | ||
let countOverhead = remainingSegments.length - this.settings.cachedSegmentsCount; | ||
if (countOverhead > 0) { | ||
remainingSegments.sort((a, b) => a.lastAccessed - b.lastAccessed); | ||
for (const cachedSegment of remainingSegments) { | ||
if ((lockedSementsfilter === undefined) || !lockedSementsfilter(cachedSegment.segment.id)) { | ||
segmentsToDelete.push(cachedSegment.segment.id); | ||
} | ||
else { | ||
remainingSegments.push(cachedSegment); | ||
} | ||
} | ||
// Delete segments over cached count | ||
let countOverhead = remainingSegments.length - this.settings.cachedSegmentsCount; | ||
if (countOverhead > 0) { | ||
remainingSegments.sort((a, b) => a.lastAccessed - b.lastAccessed); | ||
for (const cachedSegment of remainingSegments) { | ||
if ((lockedSementsfilter === undefined) || !lockedSementsfilter(cachedSegment.segment.id)) { | ||
segmentsToDelete.push(cachedSegment.segment.id); | ||
countOverhead--; | ||
if (countOverhead == 0) { | ||
break; | ||
} | ||
countOverhead--; | ||
if (countOverhead == 0) { | ||
break; | ||
} | ||
} | ||
} | ||
segmentsToDelete.forEach(id => this.cache.delete(id)); | ||
return segmentsToDelete.length > 0; | ||
}); | ||
} | ||
segmentsToDelete.forEach(id => this.cache.delete(id)); | ||
return segmentsToDelete.length > 0; | ||
} | ||
destroy() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.cache.clear(); | ||
}); | ||
async destroy() { | ||
this.cache.clear(); | ||
} | ||
} | ||
exports.SegmentsMemoryStorage = SegmentsMemoryStorage; |
{ | ||
"name": "p2p-media-loader-core", | ||
"description": "P2P Media Loader core functionality", | ||
"version": "0.6.1", | ||
"version": "0.6.2", | ||
"license": "Apache-2.0", | ||
@@ -40,3 +40,3 @@ "author": "Novage", | ||
"dependencies": { | ||
"bittorrent-tracker": "^9.11.0", | ||
"bittorrent-tracker": "^9.14.4", | ||
"debug": "^4.1.1", | ||
@@ -46,23 +46,23 @@ "events": "^3.0.0", | ||
"sha.js": "^2.4.11", | ||
"simple-peer": "^9.4.0" | ||
"simple-peer": "^9.5.0" | ||
}, | ||
"devDependencies": { | ||
"@types/assert": "^1.4.2", | ||
"@types/debug": "^4.1.4", | ||
"@types/assert": "^1.4.3", | ||
"@types/debug": "^4.1.5", | ||
"@types/events": "^3.0.0", | ||
"@types/mocha": "^5.2.7", | ||
"@types/node": "^12.6.8", | ||
"browserify": "^16.3.0", | ||
"@types/node": "^12.7.4", | ||
"browserify": "^16.5.0", | ||
"copyfiles": "^2.1.1", | ||
"mkdirp": "^0.5.1", | ||
"mocha": "^6.2.0", | ||
"terser": "^4.1.2", | ||
"terser": "^4.2.1", | ||
"ts-loader": "^6.0.4", | ||
"ts-mockito": "^2.3.1", | ||
"ts-mockito": "^2.4.2", | ||
"ts-node": "^8.3.0", | ||
"tslint": "^5.18.0", | ||
"typescript": "^3.5.3", | ||
"webpack": "^4.36.1", | ||
"webpack-cli": "^3.3.6" | ||
"tslint": "^5.19.0", | ||
"typescript": "^3.6.2", | ||
"webpack": "^4.39.3", | ||
"webpack-cli": "^3.3.7" | ||
} | ||
} |
@@ -204,3 +204,3 @@ # P2P Media Loader Core | ||
+ segment's sequence ID | ||
- `range` | ||
- `range` or `undefined` | ||
+ a `String` | ||
@@ -213,8 +213,14 @@ + must be valid HTTP Range header value or `undefined` | ||
- `data` | ||
+ an `ArrayBuffer` | ||
+ an `ArrayBuffer` or `undefined` | ||
+ available only when segment is fully loaded; subscribe to `SegmentLoaded` | ||
event for this very moment | ||
- `downloadSpeed` | ||
- `downloadSpeed` or `undefined` | ||
+ a non-negative integer `Number` | ||
+ download speed in bytes per millisecond or 0 | ||
- `requestUrl` | ||
+ a `String` or `undefined` | ||
+ Request URL of the segment | ||
- `responseUrl` | ||
+ a `String` or `undefined` | ||
+ Response URL of the segment | ||
@@ -221,0 +227,0 @@ --- |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
246
588561
11967
Updatedbittorrent-tracker@^9.14.4
Updatedsimple-peer@^9.5.0