Komponente aus 'importieren. /component.js ';
importiere mergeOptions aus './utils/merge-options.js';
dokument aus 'global/document' importieren;
importiere * as browser aus './utils/browser.js';
import window from 'global/window';
import * as Fn from './utils/fn.js';
konstante Standardwerte = {
Schwellenwert für die Nachverfolgung: 20,
Lebenstoleranz: 15
};
/*
verfolgen, wann wir am Live-Rand sind, und andere Helfer für die Live-Wiedergabe */
/**
* Eine Klasse, in der die aktuelle Uhrzeit überprüft und festgestellt wird, wann der Spieler
* befindet sich am oder hinter dem Live-Edge.
* /
Klasse LiveTracker erweitert Komponente {
/**
* Erzeugt eine Instanz dieser Klasse.
*
* @param {Player} Spieler
* Der `Player`, dem diese Klasse zugeordnet werden soll.
*
* @param {Object} [Optionen]
* Der Schlüssel/Wertspeicher der Playeroptionen.
*
* @param {Zahl} [options.trackingThreshold=20]
* Anzahl der Sekunden des Live-Fensters (SeekableEnd - SeekableStart), die
* Die Medien müssen dies haben, bevor das Liveui gezeigt wird.
*
* @param {Zahl} [options.LiveTolerance=15]
* Anzahl der Sekunden hinter dem Live-Spiel, die wir haben müssen
* bevor wir als nicht lebend gelten. Beachten Sie, dass dies nur
* kann verwendet werden, wenn am Live-Edge gespielt wird. Dies ermöglicht ein großes durchsuchbares Ende
* Änderungen haben keinen Einfluss darauf, ob wir live sind oder nicht.
* /
constructor(spieler, optionen) {
//LiveTracker benötigt kein Element
const options_ = mergeOptions (Standardwerte, Optionen, {createEl: falsch});
super(spieler, optionen_);
this.handleVisibilityChange_ = (e) => this.handleVisibilityChange (e);
this.trackLiveHandler_ = () => this.trackLive_ ();
this.handlePlay_ = (e) => this.handlePlay (e);
this.handleFirstTimeUpdate_ = (e) => this.handleFirstTimeUpdate (e);
this.handleSeeked_ = (e) => this.handleSeeked (e);
this.seekToLiveEdge_ = (e) => this.seekToLiveEdge (e);
this.reset_();
this.on (this.player_, 'durationchange', (e) => this.handleDurationChange (e));
//wir sollten versuchen, das Tracking auf Canplay als native Playback-Engines wie Safari umzuschalten
//hat bis dahin möglicherweise nicht die richtigen Werte für Dinge wie seekableEnd
this.on (this.player_, 'canplay', () => this.toggleTracking ());
//Wir müssen die Live-Wiedergabe nicht verfolgen, wenn das Dokument versteckt ist,
//außerdem kann nachverfolgt werden, wann das Dokument versteckt ist
//die CPU in die Höhe treiben und schließlich die Seite auf IE11 zum Absturz bringen.
if (browser.IE_Version && 'versteckt' im Dokument && 'VisibilityState' im Dokument) {
this.on (document, 'visibilitychange', this.handleVisibilityChange_);
}
}
/**
* Schalten Sie die Nachverfolgung basierend auf der Sichtbarkeit von Dokumenten ein
* /
handleVisibilityChange () {
wenn (this.player_.duration ()! == Unendlichkeit) {
rückkehr;
}
wenn (document.hidden) {
this.stopTracking();
} sonst {
this.startTracking();
}
}
/**
* alle Funktionen zur Nachverfolgung von Änderungen am Ende der Suche
* und um zu verfolgen, wie weit wir nach dem Ende der Woche sein sollten
* /
TrackLive_ () {
const seekable = this.player_.seekable();
//undefiniertes Suchbares überspringen
wenn (! suchbar ||! suchbar.länge) {
rückkehr;
}
const newTime = Zahl (window.performance.now () .toFixed (4));
const deltaTime = this.LastTime_ === -1? 0: (NewTime - this.LastTime_)/1000;
this.lastTime_ = Neue Uhrzeit;
this.pastSeekend_ = this.PastSeekend () + deltaTime;
const liveCurrentTime = this.liveCurrentTime();
const currentTime = this.player_.currentTime ();
//wir stehen hinter live, falls welche stimmen
//1. der Spieler ist angehalten
//2. Der Benutzer hat zu einem Ort gesucht, der 2 Sekunden vom Live-Stream entfernt ist
//3. der Unterschied zwischen Live-Zeit und aktueller Zeit ist größer
//LiveTolerance, die standardmäßig auf 15s gesetzt ist
let isBehind = this.player_.paused () || this.seekedBehindLive_ ||
Math.abs (LiveCurrentTime - CurrentTime) > this.options_.liveTolerance;
//wir können nicht hinterherhinken, wenn
//1. bis wir noch kein Timeupdate gesehen haben
//2. LiveCurrentTime ist Infinity, was auf Android und Native Safari passiert
wenn (! this.timeUpdateSeen_ || liveCurrentTime === Unendlich) {
isBehind = falsch;
}
if (isBehind! == Das.hinter LiveEdge_) {
this.behindLiveEdge_ = istHinten;
this.trigger('liveedgechange');
}
}
/**
* wickle ein Ereignis zur Änderung der Dauer des Spielers ab
* und starten/beenden Sie das Tracking entsprechend.
* /
hat DurationChange () behandelt {
this.toggleTracking ();
}
/**
* Tracking starten/beenden
* /
ToggleTracking () {
if (this.player_.duration () === Infinity && this.liveWindow () >= this.options_.trackingThreshold) {
wenn (this.player_.options_.liveui) {
this.player_.addClass ('vjs-liveui');
}
this.startTracking();
} sonst {
this.player_.removeClass ('vjs-liveui');
this.stopTracking();
}
}
/**
* beginnen Sie mit dem Verfolgen der Live-Wiedergabe
* /
startTracking() {
wenn (this.isTracking ()) {
rückkehr;
}
//Wenn wir kein Timeupdate gesehen haben, müssen wir überprüfen, ob die Wiedergabe erfolgt
//begann, bevor diese Komponente mit dem Tracking begann. Das kann häufig passieren
//wenn Autoplay verwendet wird.
if (!this.timeupdateSeen_) {
this.timeUpdateSeen_ = this.player_.hasStarted ();
}
this.trackingInterval_ = this.setInterval (this.trackLiveHandler_, fn.update_refresh_interval);
this.trackLive_();
this.on (this.player_, ['play', 'pause'], this.trackLiveHandler_);
if (!this.timeupdateSeen_) {
this.one (this.player_, 'play', this.handlePlay_);
this.one (this.player_, 'timeupdate', this.handleFirstTimeUpdate_);
} sonst {
this.on(this.player_, 'seeked', this.handleSeeked_);
}
}
/**
* kümmere dich um das erste Update auf dem Player, falls es nicht schon gespielt wurde
* als der Live-Tracker mit dem Tracking begann.
* /
handleFirstTimeUpdate () {
this.timeUpdateSeen_ = wahr;
this.on(this.player_, 'seeked', this.handleSeeked_);
}
/**
* Behalte im Auge, wann eine Suche beginnt, und höre auf Gesuchte
* um herauszufinden, wo eine Suche endet.
* /
handleSeeked () {
const timeDiff = Math.ABS (this.liveCurrentTime () - this.player_.currentTime ());
this.seekedBehindLive_ = this.NextSeekedFromUser_ & TimeDiff > 2;
this.nextSeekedFromUser_ = false;
this.trackLive_();
}
/**
* das erste Spiel mit dem Spieler abwickeln und sicherstellen, dass wir danach suchen
* direkt zum Live-Edge.
* /
Handle Play () {
this.one (this.player_, 'timeupdate', this.seekToLiveEdge_);
}
/**
* Stoppen Sie das Tracking und setzen Sie alle internen Variablen auf
* ihr Anfangswert.
* /
zurücksetzen_ () {
this.LastTime_ = -1;
this.pastSeekEnd_ = 0;
this.lastSeekEnd_ = -1;
this.BehindLiveEdge_ = wahr;
this.timeUpdateSeen_ = falsch;
this.seekedBehindLive_ = false;
this.nextSeekedFromUser_ = false;
this.clearInterval (this.trackingInterval_);
this.trackingInterval_ = null;
this.off (this.player_, ['play', 'pause'], this.trackLiveHandler_);
this.off (this.player_, 'gesucht', this.handleSeeked_);
this.off (this.player_, 'play', this.handlePlay_);
this.off (this.player_, 'timeupdate', this.handleFirstTimeUpdate_);
this.off (this.player_, 'timeupdate', this.seekToLiveEdge_);
}
/**
* Das nächste gesuchte Ereignis stammt vom Benutzer. Das bedeutet, dass jede Suche
* > 2 Sekunden hinter dem Live-Spiel werden als real hinter dem Live-Rückstand gewertet und
* LiveTolerance wird ignoriert.
* /
NextSeekedFromUser () {
this.nextSeekedFromUser_ = wahr;
}
/**
* Stoppen Sie die Live-Wiedergabe
* /
stopTracking() {
wenn (! this.isTracking ()) {
rückkehr;
}
this.reset_();
this.trigger('liveedgechange');
}
/**
* Ein Helfer, der dem Spieler ein suchbares Ende bereitet
* damit wir nicht überall eine Nullprüfung durchführen müssen
*
* @return {number}
* Das am weitesten gesuchte Ende oder Unendlichkeit.
* /
suchbares Ende () {
const seekable = this.player_.seekable();
const seekableEnds = [];
let i = seekable ? seekable.length : 0;
while (i--) {
seekableEnds.push (seekable.end (i));
}
//schnapp dir nach dem Sortieren das am weitesten durchsuchbare Ende, oder falls es keins gibt
//Standard ist Infinity
seekableEnds.length zurückgeben? seekableEnds.sort () [seekableEnds.Länge - 1]: Unendlichkeit;
}
/**
* Ein Helfer, der dem Spieler einen suchbaren Start ermöglicht
* damit wir nicht überall eine Nullprüfung durchführen müssen
*
* @return {number}
* Der früheste suchbare Start oder 0.
* /
seekableStart () {
const seekable = this.player_.seekable();
const seekableStarts = [];
let i = seekable ? seekable.length : 0;
while (i--) {
seekableStarts.push (seekable.start (i));
}
//schnapp dir den ersten suchbaren Start nach der Sortierung, oder falls es keine gibt
//Standard ist 0
seekableStarts.length zurückgeben? seekableStarts.sort () [0]: 0;
}
/**
* Holen Sie sich das Live-Zeitfenster aka
* die Zeitspanne zwischen dem Start von seekable und
* aktuelle Live-Zeit.
*
* @return {number}
* Die Anzahl der Sekunden, in denen gesucht werden kann
* das Live-Video.
* /
Live-Fenster () {
const liveCurrentTime = this.liveCurrentTime();
//wenn liveCurrenTime Infinity ist, haben wir überhaupt kein LiveWindow
if (LiveCurrentTime === Unendlich) {
0 zurückgeben;
}
gib liveCurrentTime zurück - this.seekableStart ();
}
/**
* Stellt fest, ob der Spieler live ist, prüft nur, ob diese Komponente
* verfolgt die Live-Wiedergabe oder nicht
*
* @return {boolean}
* Ob LiveTracker verfolgt
* /
ist live () {
gib this.isTracking () zurück;
}
/**
* Stellt fest, ob CurrentTime am Live-Edge ist und nicht ins Hintertreffen gerät
* bei jeder suchbaren Endänderung
*
* @return {boolean}
* Ob die Wiedergabe am Live-Rand erfolgt
* /
bei LiveEdge () {
kehre zurück! Das.hinter LiveEdge ();
}
/**
* Holen Sie sich die von uns erwartete aktuelle Live-Zeit
*
* @return {number}
* Die erwartete aktuelle Live-Zeit
* /
LiveAktuelle Uhrzeit () {
gib this.pastSeekend () + this.seekableEnd (); zurück
}
/**
* Die Anzahl der Sekunden, die nach dem Ende von Seekable vergangen sind
* geändert. Dies wird auf 0 zurückgesetzt, sobald sich das suchbare Ende ändert.
*
* @return {number}
* Sekunden nach dem aktuellen suchbaren Ende
* /
vergangenes Wochenende () {
const seekableEnd = this.seekableEnd ();
wenn (this.lastSeekend_! = -1 & SeekableEnd! == Das.LastSeekend_) {
this.pastSeekEnd_ = 0;
}
this.lastSeekEnd_ = Suchbares Ende;
gib this.pastSeekend_ zurück;
}
/**
* Wenn wir uns gerade hinter dem Live-Edge befinden, wird auch CurrentTime genannt
* hinter einer absehbaren Endänderung
*
* @return {boolean}
* Wenn wir hinter dem Live-Rand sind
* /
Hinter LiveEdge () {
gib this.BehindLiveEdge_ zurück;
}
/**
* Ob der Live-Tracker gerade verfolgt oder nicht.
* /
Ist nachverfolgbar () {
return typeofthis.trackingInterval_ === 'Nummer';
}
/**
* Suche nach dem Live-Edge, wenn wir uns hinter dem Live-Edge befinden
* /
SeektoLiveEdge () {
this.seekedBehindLive_ = false;
wenn (this.atLiveEdge ()) {
rückkehr;
}
this.nextSeekedFromUser_ = false;
this.player_.currentTime (this.liveCurrentTime ());
}
/**
* LiveTracker entsorgen
* /
dispose() {
this.off (document, 'visibilitychange', this.handleVisibilityChange_);
this.stopTracking();
super.dispose();
}
}
component.registerComponent ('LiveTracker', LiveTracker);
Exportieren Sie den Standard-LiveTracker;