rx-player
Version:
Canal+ HTML5 Video Player
106 lines (98 loc) • 3.99 kB
text/typescript
/**
* Copyright 2015 CANAL+ Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import log from "../../../log";
import type { CancellationSignal } from "../../../utils/task_canceller";
import type {
ISegmentFetcher,
ISegmentFetcherCallbacks,
ISegmentLoaderContent,
} from "./segment_fetcher";
import type { ITaskFn, ITaskPrioritizerCallbacks } from "./task_prioritizer";
import type TaskPrioritizer from "./task_prioritizer";
/**
* This function basically put in relation:
* - an `ISegmentFetcher`, which will be used to perform the segment requests
* - a `TaskPrioritizer`, which will handle the priority of a segment request
*
* and returns functions to fetch segments with a given priority.
* @param {Object} prioritizer
* @param {Object} fetcher
* @returns {Object}
*/
export default function applyPrioritizerToSegmentFetcher<TSegmentDataType>(
prioritizer: TaskPrioritizer<void>,
fetcher: ISegmentFetcher<TSegmentDataType>,
): IPrioritizedSegmentFetcher<TSegmentDataType> {
/**
* Map Promises returned by the `createRequest` method into the actual tasks
* used by the `TaskPrioritizer`, allowing to update task priorities just by
* using the Promise.
*/
const taskHandlers = new WeakMap<Promise<void>, ITaskFn<void>>();
return {
/**
* Create a Segment request with a given priority.
* @param {Object} content - content to request
* @param {Number} priority - priority at which the content should be requested.
* Lower number == higher priority.
* @param {Object} callbacks
* @param {Object} cancelSignal
* @returns {Promise}
*/
createRequest(
content: ISegmentLoaderContent,
priority: number,
callbacks: IPrioritizedSegmentFetcherCallbacks<TSegmentDataType>,
cancelSignal: CancellationSignal,
): Promise<void> {
const givenTask = (innerCancelSignal: CancellationSignal) => {
return fetcher(content, callbacks, innerCancelSignal);
};
const ret = prioritizer.create(givenTask, priority, callbacks, cancelSignal);
taskHandlers.set(ret, givenTask);
return ret;
},
/**
* Update the priority of a pending request, created through
* `createRequest`.
* @param {Promise} task - The Promise returned by `createRequest`.
* @param {Number} priority - The new priority value.
*/
updatePriority(task: Promise<void>, priority: number): void {
const correspondingTask = taskHandlers.get(task);
if (correspondingTask === undefined) {
log.warn("Fetchers: Cannot update the priority of a request: task not found.");
return;
}
prioritizer.updatePriority(correspondingTask, priority);
},
};
}
/** Oject returned by `applyPrioritizerToSegmentFetcher`. */
export interface IPrioritizedSegmentFetcher<TSegmentDataType> {
/** Create a new request for a segment with a given priority. */
createRequest: (
content: ISegmentLoaderContent,
priority: number,
callbacks: IPrioritizedSegmentFetcherCallbacks<TSegmentDataType>,
cancellationSignal: CancellationSignal,
) => Promise<void>;
/** Update priority of a request created through `createRequest`. */
updatePriority: (task: Promise<void>, priority: number) => void;
}
/** Callbacks awaited by `applyPrioritizerToSegmentFetcher`. */
export type IPrioritizedSegmentFetcherCallbacks<TSegmentDataType> =
ISegmentFetcherCallbacks<TSegmentDataType> & ITaskPrioritizerCallbacks;