diff --git a/packages/p2p-media-loader-core/src/core.ts b/packages/p2p-media-loader-core/src/core.ts index 88d93905..aa1741ce 100644 --- a/packages/p2p-media-loader-core/src/core.ts +++ b/packages/p2p-media-loader-core/src/core.ts @@ -6,6 +6,7 @@ import { Settings, SegmentBase, CoreEventHandlers, + BandwidthCalculators, } from "./types"; import * as StreamUtils from "./utils/stream"; import { LinkedMap } from "./linked-map"; @@ -31,7 +32,10 @@ export class Core { httpErrorRetries: 3, p2pErrorRetries: 3, }; - private readonly bandwidthCalculator = new BandwidthCalculator(); + private readonly bandwidthCalculators: BandwidthCalculators = { + all: new BandwidthCalculator(), + http: new BandwidthCalculator(), + }; private segmentStorage?: SegmentsMemoryStorage; private mainStreamLoader?: HybridLoader; private secondaryStreamLoader?: HybridLoader; @@ -95,7 +99,7 @@ export class Core { const segment = this.identifySegment(segmentLocalId); const loader = this.getStreamHybridLoader(segment); void loader.loadSegment(segment, callbacks); - console.log(this.isLive, this.activeLevelBitrate); + // console.log(this.isLive, this.activeLevelBitrate); } abortSegmentLoading(segmentLocalId: string): void { @@ -155,7 +159,7 @@ export class Core { manifestResponseUrl, segment, this.settings, - this.bandwidthCalculator, + this.bandwidthCalculators, this.segmentStorage, this.eventHandlers ); diff --git a/packages/p2p-media-loader-core/src/hybrid-loader.ts b/packages/p2p-media-loader-core/src/hybrid-loader.ts index a2d8ab47..6d9ddcb2 100644 --- a/packages/p2p-media-loader-core/src/hybrid-loader.ts +++ b/packages/p2p-media-loader-core/src/hybrid-loader.ts @@ -1,8 +1,12 @@ import { Segment, StreamWithSegments } from "./index"; import { HttpRequestExecutor } from "./http-loader"; import { SegmentsMemoryStorage } from "./segments-storage"; -import { Settings, CoreEventHandlers, Playback } from "./types"; -import { BandwidthCalculator } from "./bandwidth-calculator"; +import { + Settings, + CoreEventHandlers, + Playback, + BandwidthCalculators, +} from "./types"; import { P2PLoadersContainer } from "./p2p/loaders-container"; import { RequestsContainer } from "./requests/request-container"; import { EngineRequest, EngineCallbacks } from "./requests/engine-request"; @@ -16,22 +20,22 @@ const FAILED_ATTEMPTS_CLEAR_INTERVAL = 60000; export class HybridLoader { private readonly requests: RequestsContainer; + private readonly engineRequests = new Map(); private readonly p2pLoaders: P2PLoadersContainer; - private storageCleanUpIntervalId?: number; - private lastRequestedSegment: Readonly; private readonly playback: Playback; - private lastQueueProcessingTimeStamp?: number; private readonly segmentAvgDuration: number; - private randomHttpDownloadInterval!: number; private readonly logger: debug.Debugger; + private lastRequestedSegment: Readonly; + private storageCleanUpIntervalId?: number; + private lastQueueProcessingTimeStamp?: number; + private randomHttpDownloadInterval!: number; private isProcessQueueMicrotaskCreated = false; - private readonly engineRequests = new Map(); constructor( private streamManifestUrl: string, requestedSegment: Segment, private readonly settings: Settings, - private readonly bandwidthCalculator: BandwidthCalculator, + private readonly bandwidthCalculators: BandwidthCalculators, private readonly segmentStorage: SegmentsMemoryStorage, private readonly eventHandlers?: Pick ) { @@ -41,7 +45,7 @@ export class HybridLoader { this.segmentAvgDuration = StreamUtils.getSegmentAvgDuration(activeStream); this.requests = new RequestsContainer( this.requestProcessQueueMicrotask, - this.bandwidthCalculator, + this.bandwidthCalculators, this.playback, this.settings ); @@ -96,7 +100,7 @@ export class HybridLoader { if (data) { engineRequest.resolve( data, - this.bandwidthCalculator.getBandwidthForLastNSplicedSeconds(3), + this.bandwidthCalculators.all.getBandwidthForLastNSplicedSeconds(3) ); } } else { @@ -150,7 +154,7 @@ export class HybridLoader { } engineRequest?.resolve( request.data, - this.bandwidthCalculator.getBandwidthForLastNSeconds(3) + this.bandwidthCalculators.all.getBandwidthForLastNSeconds(3) ); this.engineRequests.delete(segment); this.requests.remove(request); diff --git a/packages/p2p-media-loader-core/src/p2p/tracker-client.ts b/packages/p2p-media-loader-core/src/p2p/tracker-client.ts index 6f862655..6a20e43a 100644 --- a/packages/p2p-media-loader-core/src/p2p/tracker-client.ts +++ b/packages/p2p-media-loader-core/src/p2p/tracker-client.ts @@ -43,15 +43,13 @@ export class P2PTrackerClient { announce: [ // "wss://tracker.novage.com.ua", "wss://tracker.openwebtorrent.com", + "wss://tracker.webtorrent.dev", + "wss://tracker.files.fm:7073/announce", ], rtcConfig: { iceServers: [ - { - urls: [ - "stun:stun.l.google.com:19302", - "stun:global.stun.twilio.com:3478", - ], - }, + { urls: "stun:stun.l.google.com:19302" }, + { urls: "stun:global.stun.twilio.com:3478" }, ], }, }); diff --git a/packages/p2p-media-loader-core/src/requests/request-container.ts b/packages/p2p-media-loader-core/src/requests/request-container.ts index bc0edca2..8168c865 100644 --- a/packages/p2p-media-loader-core/src/requests/request-container.ts +++ b/packages/p2p-media-loader-core/src/requests/request-container.ts @@ -1,5 +1,4 @@ -import { Segment, Settings, Playback } from "../types"; -import { BandwidthCalculator } from "../bandwidth-calculator"; +import { Segment, Settings, Playback, BandwidthCalculators } from "../types"; import { Request } from "./request"; export class RequestsContainer { @@ -7,7 +6,7 @@ export class RequestsContainer { constructor( private readonly requestProcessQueueCallback: () => void, - private readonly bandwidthCalculator: BandwidthCalculator, + private readonly bandwidthCalculators: BandwidthCalculators, private readonly playback: Playback, private readonly settings: Settings ) {} @@ -38,7 +37,7 @@ export class RequestsContainer { request = new Request( segment, this.requestProcessQueueCallback, - this.bandwidthCalculator, + this.bandwidthCalculators, this.playback, this.settings ); diff --git a/packages/p2p-media-loader-core/src/requests/request.ts b/packages/p2p-media-loader-core/src/requests/request.ts index bfc14d4c..a8a22a17 100644 --- a/packages/p2p-media-loader-core/src/requests/request.ts +++ b/packages/p2p-media-loader-core/src/requests/request.ts @@ -1,5 +1,4 @@ -import { Segment, Playback } from "../types"; -import { BandwidthCalculator } from "../bandwidth-calculator"; +import { Segment, Playback, BandwidthCalculators } from "../types"; import * as StreamUtils from "../utils/stream"; import * as Utils from "../utils/utils"; import * as LoggerUtils from "../utils/logger"; @@ -67,7 +66,7 @@ export class Request { constructor( readonly segment: Segment, private readonly requestProcessQueueCallback: () => void, - private readonly bandwidthCalculator: BandwidthCalculator, + private readonly bandwidthCalculators: BandwidthCalculators, private readonly playback: Playback, private readonly settings: StreamUtils.PlaybackTimeWindowsSettings ) { @@ -160,7 +159,8 @@ export class Request { loadedBytes: 0, startTimestamp: performance.now(), }; - this.bandwidthCalculator.startLoading(); + this.manageBandwidthCalculatorsState("start"); + const { notReceivingBytesTimeoutMs, abort } = controls; this._abortRequestCallback = abort; @@ -194,9 +194,8 @@ export class Request { ); this._abortRequestCallback?.(new RequestError("abort")); this._abortRequestCallback = undefined; - this.currentAttempt = undefined; + this.manageBandwidthCalculatorsState("stop"); this.notReceivingBytesTimeout.clear(); - this.bandwidthCalculator.stopLoading(); } private abortOnTimeout = () => { @@ -213,7 +212,7 @@ export class Request { error, }); this.notReceivingBytesTimeout.clear(); - this.bandwidthCalculator.stopLoading(); + this.manageBandwidthCalculatorsState("stop"); this.requestProcessQueueCallback(); }; @@ -228,7 +227,7 @@ export class Request { error, }); this.notReceivingBytesTimeout.clear(); - this.bandwidthCalculator.stopLoading(); + this.manageBandwidthCalculatorsState("stop"); this.requestProcessQueueCallback(); }; @@ -236,7 +235,7 @@ export class Request { this.throwErrorIfNotLoadingStatus(); if (!this.currentAttempt) return; - this.bandwidthCalculator.stopLoading(); + this.manageBandwidthCalculatorsState("stop"); this.notReceivingBytesTimeout.clear(); this.finalData = Utils.joinChunks(this.bytes); this.setStatus("succeed"); @@ -253,11 +252,15 @@ export class Request { if (!this.currentAttempt || !this.progress) return; this.notReceivingBytesTimeout.restart(); - this.bandwidthCalculator.addBytes(chunk.length); + const byteLength = chunk.byteLength; + const { all: allBC, http: httpBC } = this.bandwidthCalculators; + allBC.addBytes(byteLength); + if (this.currentAttempt.type === "http") httpBC.addBytes(byteLength); + this.bytes.push(chunk); this.progress.lastLoadedChunkTimestamp = performance.now(); - this.progress.loadedBytes += chunk.length; - this._loadedBytes += chunk.length; + this.progress.loadedBytes += byteLength; + this._loadedBytes += byteLength; }; private firstBytesReceived = () => { @@ -277,6 +280,13 @@ export class Request { this._logger.color = ""; } + private manageBandwidthCalculatorsState(state: "start" | "stop") { + const { all, http } = this.bandwidthCalculators; + const method = state === "start" ? "startLoading" : "stopLoading"; + if (this.currentAttempt?.type === "http") http[method](); + all[method](); + } + static getRequestItemId(segment: Segment) { return segment.localId; } diff --git a/packages/p2p-media-loader-core/src/types.d.ts b/packages/p2p-media-loader-core/src/types.d.ts index 1f00f738..e152f92f 100644 --- a/packages/p2p-media-loader-core/src/types.d.ts +++ b/packages/p2p-media-loader-core/src/types.d.ts @@ -1,5 +1,6 @@ import { LinkedMap } from "./linked-map"; import { RequestAttempt } from "./requests/request"; +import { BandwidthCalculator } from "./bandwidth-calculator"; export type StreamType = "main" | "secondary"; @@ -71,3 +72,8 @@ export type Playback = { position: number; rate: number; }; + +export type BandwidthCalculators = Readonly<{ + all: BandwidthCalculator; + http: BandwidthCalculator; +}>;