UNPKG

rx-player

Version:
150 lines (136 loc) 5.03 kB
import type { IUpdatePlaybackRateWorkerMessage } from "../multithread_types"; import { WorkerMessageType } from "../multithread_types"; import type { ITrackType } from "../public_types"; import type { IRange } from "../utils/ranges"; import type { IReadOnlySharedReference } from "../utils/reference"; import type { CancellationSignal } from "../utils/task_canceller"; import type { IFreezingStatus, IReadOnlyPlaybackObserver, IRebufferingStatus, } from "./types"; import generateReadOnlyObserver from "./utils/generate_read_only_observer"; import type ObservationPosition from "./utils/observation_position"; export interface IWorkerPlaybackObservation { /** * Information on whether the media element was paused at the time of the * Observation. */ paused: IPausedPlaybackObservation; /** * Information on the current media position in seconds at the time of the * Observation. */ position: ObservationPosition; /** `duration` property of the HTMLMediaElement. */ duration: number; /** `readyState` property of the HTMLMediaElement. */ readyState: number; /** Target playback rate at which we want to play the content. */ speed: number; /** Theoretical maximum position on the content that can currently be played. */ maximumPosition: number; /** * Ranges of buffered data per type of media. * `null` if no buffer exists for that type of media. */ buffered: Record<ITrackType, IRange[] | null>; rebuffering: IRebufferingStatus | null; freezing: IFreezingStatus | null; bufferGap: number | undefined; /** * Indicates whether the user agent believes it has enough buffered data to ensure * uninterrupted playback for a meaningful period or needs more data. * It also reflects whether the user agent can retrieve and buffer data in an * energy-efficient manner while maintaining the desired memory usage. * `true` indicates that the buffer is low, and more data should be buffered. * `false` indicates that there is enough buffered data, and no additional data needs * to be buffered at this time. */ canStream: boolean; /** If `true` the content is loaded until its maximum position. */ fullyLoaded: boolean; } /** Pause-related information linked to an emitted Playback observation. */ export interface IPausedPlaybackObservation { /** * Known paused state at the time the Observation was emitted. * * `true` indicating that the HTMLMediaElement was in a paused state. * * Note that it might have changed since. If you want truly precize * information, you should recuperate it from the HTMLMediaElement directly * through another mean. */ last: boolean; /** * Actually wanted paused state not yet reached. * This might for example be set to `false` when the content is currently * loading (and thus paused) but with autoPlay enabled. */ pending: boolean | undefined; } export default class WorkerPlaybackObserver implements IReadOnlyPlaybackObserver<IWorkerPlaybackObservation> { private _src: IReadOnlySharedReference<IWorkerPlaybackObservation>; private _cancelSignal: CancellationSignal; private _messageSender: (msg: IUpdatePlaybackRateWorkerMessage) => void; private _contentId: string; constructor( src: IReadOnlySharedReference<IWorkerPlaybackObservation>, contentId: string, sendMessage: (msg: IUpdatePlaybackRateWorkerMessage) => void, cancellationSignal: CancellationSignal, ) { this._src = src; this._contentId = contentId; this._messageSender = sendMessage; this._cancelSignal = cancellationSignal; } public getCurrentTime(): number | undefined { return undefined; } public getReadyState(): number | undefined { return undefined; } public getIsPaused(): boolean | undefined { return undefined; } public getReference(): IReadOnlySharedReference<IWorkerPlaybackObservation> { return this._src; } public setPlaybackRate(playbackRate: number): void { this._messageSender({ type: WorkerMessageType.UpdatePlaybackRate, contentId: this._contentId, value: playbackRate, }); } public getPlaybackRate(): number | undefined { return undefined; } public listen( cb: (observation: IWorkerPlaybackObservation, stopListening: () => void) => void, params: { includeLastObservation?: boolean | undefined; clearSignal: CancellationSignal; }, ): void { if (this._cancelSignal.isCancelled() || params.clearSignal.isCancelled()) { return; } this._src.onUpdate(cb, { clearSignal: params.clearSignal, emitCurrentValue: params.includeLastObservation, }); } public deriveReadOnlyObserver<TDest>( transform: ( observationRef: IReadOnlySharedReference<IWorkerPlaybackObservation>, cancellationSignal: CancellationSignal, ) => IReadOnlySharedReference<TDest>, ): IReadOnlyPlaybackObserver<TDest> { return generateReadOnlyObserver(this, transform, this._cancelSignal); } }