UNPKG

playable

Version:

Video player based on HTML5Video

180 lines (147 loc) 4.04 kB
import View from './time.view'; import { VideoEvent, EngineState, LiveState, UIEvent, } from '../../../../constants'; import { IEventEmitter } from '../../../event-emitter/types'; import { IPlaybackEngine } from '../../../playback-engine/types'; import { ITimeControl, ITimeViewConfig } from './types'; import { IThemeService } from '../../core/theme'; export const UPDATE_TIME_INTERVAL_DELAY = 1000 / 60; export default class TimeControl implements ITimeControl { static moduleName = 'timeControl'; static View = View; static dependencies = ['engine', 'eventEmitter', 'theme']; private _eventEmitter: IEventEmitter; private _engine: IPlaybackEngine; private _theme: IThemeService; private _updateControlInterval: number; private _unbindEvents: () => void; view: View; isHidden: boolean; constructor({ eventEmitter, engine, theme, }: { eventEmitter: IEventEmitter; engine: IPlaybackEngine; theme: IThemeService; }) { this._eventEmitter = eventEmitter; this._engine = engine; this._theme = theme; this._bindCallbacks(); this._initUI(); this._bindEvents(); this._setCurrentTime(0); this._setDurationTime(0); } getElement() { return this.view.getElement(); } private _bindCallbacks() { this._updateCurrentTime = this._updateCurrentTime.bind(this); this._updateDurationTime = this._updateDurationTime.bind(this); } private _bindEvents() { this._unbindEvents = this._eventEmitter.bindEvents( [ [UIEvent.PROGRESS_USER_PREVIEWING_FRAME, this._updateTimeFromPreview], [VideoEvent.STATE_CHANGED, this._toggleIntervalUpdates], [VideoEvent.DURATION_UPDATED, this._updateDurationTime], [VideoEvent.LIVE_STATE_CHANGED, this._processLiveStateChange], ], this, ); } private _initUI() { const config: ITimeViewConfig = { theme: this._theme, }; this.view = new TimeControl.View(config); } private _startIntervalUpdates() { if (this._updateControlInterval) { this._stopIntervalUpdates(); } this._updateCurrentTime(); this._updateControlInterval = window.setInterval( this._updateCurrentTime, UPDATE_TIME_INTERVAL_DELAY, ); } private _stopIntervalUpdates() { window.clearInterval(this._updateControlInterval); this._updateControlInterval = null; } private _processLiveStateChange({ nextState }: { nextState: LiveState }) { switch (nextState) { case LiveState.NONE: this.show(); break; case LiveState.INITIAL: this.hide(); break; case LiveState.ENDED: this.show(); break; default: break; } } private _toggleIntervalUpdates({ nextState }: { nextState: EngineState }) { switch (nextState) { case EngineState.SRC_SET: this.reset(); break; case EngineState.PLAYING: this._startIntervalUpdates(); break; case EngineState.SEEK_IN_PROGRESS: this._startIntervalUpdates(); break; default: this._stopIntervalUpdates(); break; } } private _updateDurationTime() { this._setDurationTime(this._engine.getDuration()); } private _updateCurrentTime() { const time = this._engine.getCurrentTime(); this._setCurrentTime(time); } private _updateTimeFromPreview(time: number) { this.view.setCurrentTime(time); } private _setDurationTime(time: number) { this.view.setDurationTime(time); } private _setCurrentTime(time: number) { this.view.setCurrentTime(time); } hide() { this.isHidden = true; this.view.hide(); } show() { this.isHidden = false; this.view.show(); } reset() { this._setDurationTime(0); this._setCurrentTime(0); this.view.showDuration(); this.view.setCurrentTimeBackward(false); this.show(); } destroy() { this._stopIntervalUpdates(); this._unbindEvents(); this.view.destroy(); } }