UNPKG

playable

Version:

Video player based on HTML5Video

422 lines 18.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UPDATE_PROGRESS_INTERVAL_DELAY = void 0; var tslib_1 = require("tslib"); var progress_view_1 = (0, tslib_1.__importDefault)(require("./progress.view")); var video_data_1 = require("../../../../utils/video-data"); var constants_1 = require("../../../../constants"); var keyboard_control_1 = require("../../../keyboard-control/keyboard-control"); var keyboard_interceptor_1 = (0, tslib_1.__importStar)(require("../../../../utils/keyboard-interceptor")); var formatTime_1 = (0, tslib_1.__importDefault)(require("../../core/utils/formatTime")); var player_api_decorator_1 = (0, tslib_1.__importDefault)(require("../../../../core/player-api-decorator")); exports.UPDATE_PROGRESS_INTERVAL_DELAY = 1000 / 60; var ProgressControl = /** @class */ (function () { function ProgressControl(_a) { var engine = _a.engine, liveStateEngine = _a.liveStateEngine, eventEmitter = _a.eventEmitter, textMap = _a.textMap, tooltipService = _a.tooltipService, theme = _a.theme, previewThumbnail = _a.previewThumbnail, previewFullSize = _a.previewFullSize; this._engine = engine; this._liveStateEngine = liveStateEngine; this._eventEmitter = eventEmitter; this._textMap = textMap; this._tooltipService = tooltipService; this._previewThumbnail = previewThumbnail; this._previewFullSize = previewFullSize; this._isUserDragging = false; this._desiredSeekPosition = 0; this._theme = theme; this._timeIndicatorsToAdd = []; this._showFullScreenPreview = false; this._bindCallbacks(); this._initUI(); this._bindEvents(); this.view.setPlayed(0); this.view.setBuffered(0); this._initInterceptor(); } ProgressControl.prototype.getElement = function () { return this.view.getElement(); }; ProgressControl.prototype._bindEvents = function () { this._unbindEvents = this._eventEmitter.bindEvents([ [constants_1.VideoEvent.STATE_CHANGED, this._processStateChange], [constants_1.VideoEvent.LIVE_STATE_CHANGED, this._processLiveStateChange], [constants_1.VideoEvent.CHUNK_LOADED, this._updateBufferIndicator], [constants_1.VideoEvent.DURATION_UPDATED, this._updateAllIndicators], [constants_1.UIEvent.RESIZE, this.view.updateOnResize, this.view], ], this); }; ProgressControl.prototype._initUI = function () { var config = { callbacks: { onSyncWithLiveClick: this._syncWithLive, onSyncWithLiveMouseEnter: this._onSyncWithLiveMouseEnter, onSyncWithLiveMouseLeave: this._onSyncWithLiveMouseLeave, onChangePlayedPercent: this._onChangePlayedPercent, onSeekToByMouseStart: this._showTooltipAndPreview, onSeekToByMouseEnd: this._hideTooltip, onDragStart: this._startProcessingUserDrag, onDragEnd: this._stopProcessingUserDrag, }, theme: this._theme, textMap: this._textMap, tooltipService: this._tooltipService, }; this.view = new ProgressControl.View(config); }; ProgressControl.prototype._initInterceptor = function () { var _a; var _this = this; this._interceptor = new keyboard_interceptor_1.default(this.view.getElement(), (_a = {}, _a[keyboard_interceptor_1.KEYCODES.UP_ARROW] = function (e) { e.stopPropagation(); e.preventDefault(); _this._eventEmitter.emitAsync(constants_1.UIEvent.KEYBOARD_KEYDOWN_INTERCEPTED); _this._eventEmitter.emitAsync(constants_1.UIEvent.GO_FORWARD_WITH_KEYBOARD); _this._engine.seekForward(keyboard_control_1.AMOUNT_TO_SKIP_SECONDS); }, _a[keyboard_interceptor_1.KEYCODES.DOWN_ARROW] = function (e) { e.stopPropagation(); e.preventDefault(); _this._eventEmitter.emitAsync(constants_1.UIEvent.KEYBOARD_KEYDOWN_INTERCEPTED); _this._eventEmitter.emitAsync(constants_1.UIEvent.GO_BACKWARD_WITH_KEYBOARD); _this._engine.seekBackward(keyboard_control_1.AMOUNT_TO_SKIP_SECONDS); }, _a[keyboard_interceptor_1.KEYCODES.RIGHT_ARROW] = function (e) { e.stopPropagation(); e.preventDefault(); _this._eventEmitter.emitAsync(constants_1.UIEvent.KEYBOARD_KEYDOWN_INTERCEPTED); _this._eventEmitter.emitAsync(constants_1.UIEvent.GO_FORWARD_WITH_KEYBOARD); _this._engine.seekForward(keyboard_control_1.AMOUNT_TO_SKIP_SECONDS); }, _a[keyboard_interceptor_1.KEYCODES.LEFT_ARROW] = function (e) { e.stopPropagation(); e.preventDefault(); _this._eventEmitter.emitAsync(constants_1.UIEvent.KEYBOARD_KEYDOWN_INTERCEPTED); _this._eventEmitter.emitAsync(constants_1.UIEvent.GO_BACKWARD_WITH_KEYBOARD); _this._engine.seekBackward(keyboard_control_1.AMOUNT_TO_SKIP_SECONDS); }, _a)); }; ProgressControl.prototype._destroyInterceptor = function () { this._interceptor.destroy(); }; ProgressControl.prototype._bindCallbacks = function () { this._syncWithLive = this._syncWithLive.bind(this); this._onSyncWithLiveMouseEnter = this._onSyncWithLiveMouseEnter.bind(this); this._onSyncWithLiveMouseLeave = this._onSyncWithLiveMouseLeave.bind(this); this._updateAllIndicators = this._updateAllIndicators.bind(this); this._onChangePlayedPercent = this._onChangePlayedPercent.bind(this); this._showTooltipAndPreview = this._showTooltipAndPreview.bind(this); this._hideTooltip = this._hideTooltip.bind(this); this._startProcessingUserDrag = this._startProcessingUserDrag.bind(this); this._stopProcessingUserDrag = this._stopProcessingUserDrag.bind(this); }; ProgressControl.prototype._startIntervalUpdates = function () { if (this._updateControlInterval) { this._stopIntervalUpdates(); } this._updateAllIndicators(); this._updateControlInterval = window.setInterval(this._updateAllIndicators, exports.UPDATE_PROGRESS_INTERVAL_DELAY); }; ProgressControl.prototype._stopIntervalUpdates = function () { window.clearInterval(this._updateControlInterval); this._updateControlInterval = null; }; ProgressControl.prototype._convertPlayedPercentToTime = function (percent) { var duration = this._engine.getDuration(); return (duration * percent) / 100; }; ProgressControl.prototype._onChangePlayedPercent = function (percent) { var newTime = this._convertPlayedPercentToTime(percent); if (this._showFullScreenPreview) { this._desiredSeekPosition = newTime; this._eventEmitter.emitAsync(constants_1.UIEvent.PROGRESS_USER_PREVIEWING_FRAME, newTime); } else { this._changeCurrentTimeOfVideo(newTime); } if (this._isUserDragging) { this._showTooltipAndPreview(percent); } }; ProgressControl.prototype._showTooltipAndPreview = function (percent) { var duration = this._engine.getDuration(); var seekToTime = this._convertPlayedPercentToTime(percent); var timeToShow = this._engine.isDynamicContent ? seekToTime - duration : seekToTime; this._previewThumbnail.setTime((0, formatTime_1.default)(timeToShow)); this._previewThumbnail.showAt(seekToTime); this.view.showProgressTimeTooltip(this._previewThumbnail.getElement(), percent); if (this._isUserDragging && this._showFullScreenPreview) { this._previewFullSize.showAt(seekToTime); } }; ProgressControl.prototype._hideTooltip = function () { if (!this._isUserDragging) { this.view.hideProgressTimeTooltip(); } }; ProgressControl.prototype._startProcessingUserDrag = function () { if (!this._isUserDragging) { this._isUserDragging = true; this._pauseVideoOnDragStart(); this._eventEmitter.emitAsync(constants_1.UIEvent.PROGRESS_DRAG_STARTED); this._eventEmitter.emitAsync(constants_1.UIEvent.CONTROL_DRAG_START); } }; ProgressControl.prototype._stopProcessingUserDrag = function () { if (this._isUserDragging) { this._isUserDragging = false; if (this._showFullScreenPreview) { this._shouldHidePreviewOnUpdate = true; } if (this._showFullScreenPreview) { this._changeCurrentTimeOfVideo(this._desiredSeekPosition); } this._playVideoOnDragEnd(); this.view.hideProgressTimeTooltip(); this._eventEmitter.emitAsync(constants_1.UIEvent.PROGRESS_DRAG_ENDED); this._eventEmitter.emitAsync(constants_1.UIEvent.CONTROL_DRAG_END); } }; ProgressControl.prototype._hidePreview = function () { this._shouldHidePreviewOnUpdate = false; this._previewFullSize.hide(); }; ProgressControl.prototype._processStateChange = function (_a) { var nextState = _a.nextState; switch (nextState) { case constants_1.EngineState.SRC_SET: this._reset(); break; case constants_1.EngineState.METADATA_LOADED: this._initTimeIndicators(); if (this._engine.isSeekAvailable) { this.show(); } else { this.hide(); } break; case constants_1.EngineState.PLAYING: if (this._shouldHidePreviewOnUpdate) { this._hidePreview(); } if (this._liveStateEngine.state === constants_1.LiveState.SYNC) { this.view.setPlayed(100); } else { this._startIntervalUpdates(); } break; case constants_1.EngineState.PAUSED: if (this._shouldHidePreviewOnUpdate) { this._hidePreview(); } this._stopIntervalUpdates(); break; case constants_1.EngineState.SEEK_IN_PROGRESS: this._updateAllIndicators(); break; default: break; } }; ProgressControl.prototype._processLiveStateChange = function (_a) { var nextState = _a.nextState; switch (nextState) { case constants_1.LiveState.NONE: this.view.setLiveSyncState(false); this.view.setUsualMode(); break; case constants_1.LiveState.INITIAL: this.view.setLiveMode(); break; case constants_1.LiveState.SYNC: this.view.setLiveSyncState(true); break; case constants_1.LiveState.NOT_SYNC: this.view.setLiveSyncState(false); break; case constants_1.LiveState.ENDED: this.view.setLiveSyncState(false); this.view.hideSyncWithLive(); // ensure progress indicators show latest info if (this._engine.getCurrentState() === constants_1.EngineState.PLAYING) { this._startIntervalUpdates(); } else { this._updateAllIndicators(); } break; default: break; } }; ProgressControl.prototype._changeCurrentTimeOfVideo = function (newTime) { var duration = this._engine.getDuration(); if (this._engine.isDynamicContent && duration === newTime) { this._engine.syncWithLive(); } else { this._engine.seekTo(newTime); } this._eventEmitter.emitAsync(constants_1.UIEvent.PROGRESS_CHANGE, newTime); }; ProgressControl.prototype._pauseVideoOnDragStart = function () { var currentState = this._engine.getCurrentState(); if (currentState === constants_1.EngineState.PLAYING || currentState === constants_1.EngineState.PLAY_REQUESTED) { this._shouldPlayAfterDragEnd = true; this._engine.pause(); } this._eventEmitter.emitAsync(constants_1.UIEvent.PROGRESS_DRAG_STARTED); }; ProgressControl.prototype._playVideoOnDragEnd = function () { if (this._shouldPlayAfterDragEnd) { this._engine.play(); this._shouldPlayAfterDragEnd = false; } }; ProgressControl.prototype._updateBufferIndicator = function () { var currentTime = this._engine.getCurrentTime(); var buffered = this._engine.getBuffered(); var duration = this._engine.getDuration(); this._setBuffered((0, video_data_1.getOverallBufferedPercent)(buffered, currentTime, duration)); }; ProgressControl.prototype._updatePlayedIndicator = function () { if (this._liveStateEngine.state === constants_1.LiveState.SYNC) { // TODO: mb use this.updatePlayed(100) here? return; } var currentTime = this._engine.getCurrentTime(); var duration = this._engine.getDuration(); this._setPlayed((0, video_data_1.getOverallPlayedPercent)(currentTime, duration)); }; ProgressControl.prototype._updateAllIndicators = function () { this._updatePlayedIndicator(); this._updateBufferIndicator(); }; ProgressControl.prototype._initTimeIndicators = function () { var _this = this; this._timeIndicatorsToAdd.forEach(function (time) { _this._addTimeIndicator(time); }); this._timeIndicatorsToAdd = []; }; ProgressControl.prototype._addTimeIndicator = function (time) { var durationTime = this._engine.getDuration(); if (time > durationTime) { // TODO: log error for developers return; } this.view.addTimeIndicator((0, video_data_1.getTimePercent)(time, durationTime)); }; ProgressControl.prototype._syncWithLive = function () { this._engine.syncWithLive(); }; ProgressControl.prototype._onSyncWithLiveMouseEnter = function () { this._eventEmitter.emitAsync(constants_1.UIEvent.PROGRESS_SYNC_BUTTON_MOUSE_ENTER); }; ProgressControl.prototype._onSyncWithLiveMouseLeave = function () { this._eventEmitter.emitAsync(constants_1.UIEvent.PROGRESS_SYNC_BUTTON_MOUSE_LEAVE); }; ProgressControl.prototype._setPlayed = function (percent) { this.view.setPlayed(percent); }; ProgressControl.prototype._setBuffered = function (percent) { this.view.setBuffered(percent); }; ProgressControl.prototype._reset = function () { this._setPlayed(0); this._setBuffered(0); this.clearTimeIndicators(); }; /** * Player will show full screen preview instead of actual seek on video when user drag the progress control * @example * player.showPreviewOnProgressDrag(); */ ProgressControl.prototype.showPreviewOnProgressDrag = function () { this._showFullScreenPreview = true; }; /** * Player will seek on video when user drag the progress control * @example * player.seekOnProgressDrag(); */ ProgressControl.prototype.seekOnProgressDrag = function () { this._showFullScreenPreview = false; }; /** * Add time indicator to progress bar */ ProgressControl.prototype.addTimeIndicator = function (time) { this.addTimeIndicators([time]); }; /** * Add time indicators to progress bar */ ProgressControl.prototype.addTimeIndicators = function (times) { var _a; var _this = this; if (!this._engine.isMetadataLoaded) { // NOTE: Add indicator after metadata loaded (_a = this._timeIndicatorsToAdd).push.apply(_a, times); return; } times.forEach(function (time) { _this._addTimeIndicator(time); }); }; /** * Delete all time indicators from progress bar */ ProgressControl.prototype.clearTimeIndicators = function () { this.view.clearTimeIndicators(); }; ProgressControl.prototype.hide = function () { this.isHidden = true; this.view.hide(); }; ProgressControl.prototype.show = function () { this.isHidden = false; this.view.show(); }; ProgressControl.prototype.destroy = function () { this._destroyInterceptor(); this._stopIntervalUpdates(); this._unbindEvents(); this.view.destroy(); }; ProgressControl.moduleName = 'progressControl'; ProgressControl.View = progress_view_1.default; ProgressControl.dependencies = [ 'engine', 'liveStateEngine', 'eventEmitter', 'textMap', 'tooltipService', 'theme', 'previewThumbnail', 'previewFullSize', ]; (0, tslib_1.__decorate)([ (0, player_api_decorator_1.default)() ], ProgressControl.prototype, "showPreviewOnProgressDrag", null); (0, tslib_1.__decorate)([ (0, player_api_decorator_1.default)() ], ProgressControl.prototype, "seekOnProgressDrag", null); (0, tslib_1.__decorate)([ (0, player_api_decorator_1.default)() ], ProgressControl.prototype, "addTimeIndicator", null); (0, tslib_1.__decorate)([ (0, player_api_decorator_1.default)() ], ProgressControl.prototype, "addTimeIndicators", null); (0, tslib_1.__decorate)([ (0, player_api_decorator_1.default)() ], ProgressControl.prototype, "clearTimeIndicators", null); return ProgressControl; }()); exports.default = ProgressControl; //# sourceMappingURL=progress.js.map