UNPKG

p2p-media-loader-shaka

Version:

P2P Media Loader Shaka Player integration

118 lines 4.33 kB
import * as Utils from "./stream-utils.js"; import { CoreRequestError, } from "p2p-media-loader-core"; export class Loader { constructor(shaka, core, streamInfo) { Object.defineProperty(this, "shaka", { enumerable: true, configurable: true, writable: true, value: shaka }); Object.defineProperty(this, "core", { enumerable: true, configurable: true, writable: true, value: core }); Object.defineProperty(this, "streamInfo", { enumerable: true, configurable: true, writable: true, value: streamInfo }); Object.defineProperty(this, "loadArgs", { enumerable: true, configurable: true, writable: true, value: void 0 }); } defaultLoad() { const fetchPlugin = this.shaka.net.HttpFetchPlugin; return fetchPlugin.parse(...this.loadArgs); } load(...args) { this.loadArgs = args; const { RequestType } = this.shaka.net.NetworkingEngine; const [url, request, requestType] = args; if (requestType === RequestType.SEGMENT) { return this.loadSegment(url, request); } const loading = this.defaultLoad(); if (requestType === RequestType.MANIFEST) { void this.handleManifestLoading(loading.promise); } return loading; } async handleManifestLoading(loadingPromise) { if (!this.streamInfo.manifestResponseUrl) { // loading main manifest either HLS or DASH const response = await loadingPromise; this.setManifestResponseUrl(response.uri); } } loadSegment(segmentUrl, originalRequest) { const byteRangeString = originalRequest.headers.Range; const segmentRuntimeId = Utils.getSegmentRuntimeId(segmentUrl, byteRangeString); const isSegmentDownloadableByP2PCore = this.core.isSegmentLoadable(segmentRuntimeId); if (!this.core.hasSegment(segmentRuntimeId) || !isSegmentDownloadableByP2PCore) { return this.defaultLoad(); } const loadSegment = async () => { const { request, callbacks } = getSegmentRequest(); void this.core.loadSegment(segmentRuntimeId, callbacks); try { const { data, bandwidth } = await request; return { data, headers: {}, originalRequest, uri: segmentUrl, originalUri: segmentUrl, timeMs: getLoadingDurationBasedOnBandwidth(bandwidth, data.byteLength), }; } catch (error) { // TODO: throw Shaka Errors if (error instanceof CoreRequestError) { const { Error: ShakaError } = this.shaka.util; if (error.type === "aborted") { throw new ShakaError(ShakaError.Severity.RECOVERABLE, ShakaError.Category.NETWORK, this.shaka.util.Error.Code.OPERATION_ABORTED); } } throw error; } }; return new this.shaka.util.AbortableOperation(loadSegment(), () => { this.core.abortSegmentLoading(segmentRuntimeId); return Promise.resolve(); }); } setManifestResponseUrl(responseUrl) { this.streamInfo.manifestResponseUrl = responseUrl; this.core.setManifestResponseUrl(responseUrl); } } function getLoadingDurationBasedOnBandwidth(bandwidth, bytesLoaded) { const bits = bytesLoaded * 8; return Math.round(bits / bandwidth) * 1000; } function getSegmentRequest() { let onSuccess; let onError; const request = new Promise((resolve, reject) => { onSuccess = resolve; onError = reject; }); return { request, callbacks: { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion onSuccess: onSuccess, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion onError: onError, }, }; } //# sourceMappingURL=loading-handler.js.map