diff --git a/types/video.js/index.d.ts b/types/video.js/index.d.ts index b7a4dcf81c..a3b0f0b0b5 100644 --- a/types/video.js/index.d.ts +++ b/types/video.js/index.d.ts @@ -2921,6 +2921,94 @@ declare namespace videojs { [language: string]: string; } + /** + * LiveTracker provides several useful helper functions and events for dealing with live playback, all of which are used and tested internally. + * Internally this component keeps track of the live current time through a function that runs on a 30ms interval. + */ + interface LiveTracker extends Component { + /** + * These functions can be called to arbitrarily start/stop tracking live playback. + * Normally these are handled by automatically when the player triggers a durationchange with a duration of Infinity. + * You won't want to call them unless you are doing something fairly specific. + */ + startTracking(): void; + + /** + * These functions can be called to arbitrarily start/stop tracking live playback. + * Normally these are handled by automatically when the player triggers a durationchange with a duration of Infinity. + * You won't want to call them unless you are doing something fairly specific. + */ + stopTracking(): void; + + /** + * seekableEnd gets the time in seconds of the furthest seekable end. + * For instance if we have an array of seekable TimeRanges where the first element in the array is the start() second and the last is the end() second: + */ + seekableEnd(): number; + + /** + * seekableStart gets the time in seconds of the earliest seekable start. + * For instance if we have an array of seekable TimeRanges where the first element in the array is the start() second and the last is the end() second: + */ + seekableStart(): number; + + /** + * This function gets the amount of time between the seekableStart() and the liveCurrentTime(). + * We use this internally to update the total length of our bars, such as the progress/seek bar. + */ + liveWindow(): number; + + /** + * Determines if the currentTime of the player is close enough to live to be considered live. + * We make sure it's close enough, rather than absolutely live, because there are too many factors to determine when live actually is. + * We consider the currentTime live when it is within two seekable increments and 70ms (two ticks of the live tracking interval). + * The seekable increment is a number that is determined by the amount that seekable end changes as playback continues. + * See the seekableendchange event and the pastSeekEnd() function for more info. + */ + atLiveEdge(): boolean; + + /** + * Determines if the currentTime of the player is close enough to live to be considered live. + * We make sure it's close enough, rather than absolutely live, because there are too many factors to determine when live actually is. + * We consider the currentTime live when it is within two seekable increments and 70ms (two ticks of the live tracking interval). + * The seekable increment is a number that is determined by the amount that seekable end changes as playback continues. + * See the seekableendchange event and the pastSeekEnd() function for more info. + */ + behindLiveEdge(): boolean; + + /** + * live current time is our best approximation of what the live current time is. + * Internally it uses the pastSeekEnd() function and adds that to the seekableEnd() function. + * It is possible for this function to return Infinity. + */ + liveCurrentTime(): number; + + /** + * This is the main value that we use to track if the player is live or not. + * Every 30ms we add 0.03 seconds to this value and every seekableendchange it is reset to 0 and 0.03 is added to it right away. + */ + pastSeekEnd(): number; + + /** + * isTracking and isLive do the same thing they tell you if the LiveTracker is currently tracking live playback + * and since we assume that live tracking will only be done during live they should be the same. + */ + isLive(): boolean; + + /** + * isTracking and isLive do the same thing they tell you if the LiveTracker is currently tracking live playback + * and since we assume that live tracking will only be done during live they should be the same. + */ + isTracking(): boolean; + + /** + * This function sets the players currentTime to the result of the liveCurrentTime() function. + * It will also start playback if playback is currently paused. + * It starts playback because it is easy to fall behind the live edge if the player is not playing. + */ + seekToLiveEdge(): void; + } + /** * @file log.js */ @@ -5850,6 +5938,8 @@ export interface VideoJsPlayer extends videojs.Component { errorDisplay: videojs.ModalDialog; + liveTracker: videojs.LiveTracker; + loadingSpinner: videojs.Component; options_: videojs.PlayerOptions; diff --git a/types/video.js/video.js-tests.ts b/types/video.js/video.js-tests.ts index 3f75548dd3..0e252f6e0f 100644 --- a/types/video.js/video.js-tests.ts +++ b/types/video.js/video.js-tests.ts @@ -23,9 +23,24 @@ videojs("example_video_1").ready(function() { { type: "video/ogg", src: "http://www.example.com/path/to/video.ogv" } ]); - const whereYouAt: number = this.currentTime(); + const liveTracker = this.liveTracker; + liveTracker.on('seekableendchange', () => {}); + liveTracker.on('liveedgechange', () => {}); + const windowOrDuration = liveTracker.isLive() ? liveTracker.liveWindow() : this.duration(); + const liveCurrentTime: number = liveTracker.liveCurrentTime(); + const liveWindow: number = liveTracker.liveWindow(); + const seekableStart: number = liveTracker.seekableStart(); + const seekableEnd: number = liveTracker.seekableEnd(); + const atLiveEdge: boolean = liveTracker.atLiveEdge(); + const behindLiveEdge: boolean = liveTracker.behindLiveEdge(); + const pastSeekEnd: number = liveTracker.pastSeekEnd(); + const isLive: boolean = liveTracker.isLive(); + liveTracker.seekToLiveEdge(); + liveTracker.startTracking(); + liveTracker.stopTracking(); + const isTracking: boolean = liveTracker.isTracking(); - this.currentTime(120); // 2 minutes into the video + const whereYouAt: number = this.currentTime(); const howLongIsThis: number = this.duration();