rx-player
Version:
Canal+ HTML5 Video Player
117 lines (111 loc) • 4.33 kB
text/typescript
/**
* Class facilitating the exploitation of what could be called the "playback
* position" (the position at which we should currently be playing).
*
* In appearance a simple concept, it has in reality some gotchas that we wanted
* to make more explicit.
* As such, this class defines multiple methods to obtain an estimate of it,
* each having its own pros and cons.
*
* @class ObservationPosition
*/
export default class ObservationPosition {
/**
* Known position at the time the Observation was emitted, in seconds.
*
* Note that it might have changed since. If you want truly precize
* information, you should recuperate it from the HTMLMediaElement directly
* through another mean.
*/
private _last: number;
/**
* Actually wanted position in seconds that is not yet reached.
*
* This might for example be set to the initial position when the content is
* loading (and thus potentially at a `0` position) but which will be seeked
* to a given position once possible. It may also be the position of a seek
* that has not been properly accounted for by the current device.
*/
private _wanted: number | null;
constructor(last: number, wanted: number | null) {
this._last = last;
this._wanted = wanted;
}
/**
* Obtain arguments allowing to instanciate the same ObservationPosition.
*
* This can be used to create a new `ObservationPosition` across JS realms,
* generally to communicate its data between the main thread and a WebWorker.
* @returns {Array.<number>}
*/
public serialize(): [number, number | null] {
return [this._last, this._wanted];
}
/**
* Returns the playback position actually observed on the media element at
* the time the playback observation was made.
*
* Note that it may be different than the position for which media data is
* wanted in rare scenarios where the goal position is not yet set on the
* media element.
*
* You should use this value when you want to obtain the actual position set
* on the media element for browser compatibility purposes. Note that this
* position was calculated at observation time, it might thus not be
* up-to-date if what you want is milliseconds-accuracy.
*
* If what you want is the actual position which the player is intended to
* play, you should rely on `getWanted` instead`.
* @returns {number}
*/
public getPolled(): number {
return this._last;
}
/**
* Returns the position which the player should consider to load media data
* at the time the observation was made.
*
* It can be different than the value returned by `getPolled` in rare
* scenarios:
*
* - When the initial position has not been set yet.
*
* - When the current device do not let the RxPlayer peform precize seeks,
* usually for perfomance reasons by seeking to a previous IDR frame
* instead (for now only Tizen may be like this), in which case we
* prefer to generally rely on the position wanted by the player (this
* e.g. prevents issues where the RxPlayer logic and the device are
* seeking back and forth in a loop).
*
* - When a wanted position has been "forced" (@see forceWantedPosition).
* @returns {number}
*/
public getWanted(): number {
return this._wanted ?? this._last;
}
/**
* Method to call if you want to overwrite the currently wanted position.
* @param {number} pos
*/
public forceWantedPosition(pos: number): void {
this._wanted = pos;
}
/**
* Returns `true` when the position wanted returned by `getWanted` and the
* actual position returned by `getPolled` may be different, meaning that
* we're currently not at the position we want to reach.
*
* This is a relatively rare situation which only happens when either the
* initial seek has not yet been performed. on specific targets where the
* seeking behavior is a little broken (@see getWanted) or when the wanted
* position has been forced (@see forceWantedPosition).
*
* In those situations, you might temporarily refrain from acting upon the
* actual current media position, as it may change soon.
*
* @returns {boolean}
*/
public isAwaitingFuturePosition(): boolean {
return this._wanted !== null;
}
}