@clappr/hlsjs-playback 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"hlsjs-playback.external.min.js","sources":["../src/hls.js"],"sourcesContent":["// Copyright 2014 Globo.com Player authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\nimport { Events, HTML5Video, Log, Playback, PlayerError, Utils } from '@clappr/core'\nimport HLSJS from 'hls.js'\n\nconst { now, assign, listContainsIgnoreCase } = Utils\n\nconst AUTO = -1\n\nEvents.register('PLAYBACK_FRAGMENT_CHANGED')\nEvents.register('PLAYBACK_FRAGMENT_PARSING_METADATA')\n\nexport default class HlsjsPlayback extends HTML5Video {\n get name() { return 'hls' }\n\n get supportedVersion() { return { min: CLAPPR_CORE_VERSION } }\n\n get levels() { return this._levels || [] }\n\n get currentLevel() {\n if (this._currentLevel === null || this._currentLevel === undefined)\n return AUTO\n else\n return this._currentLevel //0 is a valid level ID\n\n }\n\n get isReady() {\n return this._isReadyState\n }\n\n set currentLevel(id) {\n this._currentLevel = id\n this.trigger(Events.PLAYBACK_LEVEL_SWITCH_START)\n if (this.options.playback.hlsUseNextLevel)\n this._hls.nextLevel = this._currentLevel\n else\n this._hls.currentLevel = this._currentLevel\n }\n\n get _startTime() {\n if (this._playbackType === Playback.LIVE && this._playlistType !== 'EVENT')\n return this._extrapolatedStartTime\n\n return this._playableRegionStartTime\n }\n\n get _now() {\n return now()\n }\n\n // the time in the video element which should represent the start of the sliding window\n // extrapolated to increase in real time (instead of jumping as the early segments are removed)\n get _extrapolatedStartTime() {\n if (!this._localStartTimeCorrelation)\n return this._playableRegionStartTime\n\n let corr = this._localStartTimeCorrelation\n let timePassed = this._now - corr.local\n let extrapolatedWindowStartTime = (corr.remote + timePassed) / 1000\n // cap at the end of the extrapolated window duration\n return Math.min(extrapolatedWindowStartTime, this._playableRegionStartTime + this._extrapolatedWindowDuration)\n }\n\n // the time in the video element which should represent the end of the content\n // extrapolated to increase in real time (instead of jumping as segments are added)\n get _extrapolatedEndTime() {\n let actualEndTime = this._playableRegionStartTime + this._playableRegionDuration\n if (!this._localEndTimeCorrelation)\n return actualEndTime\n\n let corr = this._localEndTimeCorrelation\n let timePassed = this._now - corr.local\n let extrapolatedEndTime = (corr.remote + timePassed) / 1000\n return Math.max(actualEndTime - this._extrapolatedWindowDuration, Math.min(extrapolatedEndTime, actualEndTime))\n }\n\n get _duration() {\n return this._extrapolatedEndTime - this._startTime\n }\n\n // Returns the duration (seconds) of the window that the extrapolated start time is allowed\n // to move in before being capped.\n // The extrapolated start time should never reach the cap at the end of the window as the\n // window should slide as chunks are removed from the start.\n // This also applies to the extrapolated end time in the same way.\n //\n // If chunks aren't being removed for some reason that the start time will reach and remain fixed at\n // playableRegionStartTime + extrapolatedWindowDuration\n //\n // <-- window duration -->\n // I.e playableRegionStartTime |-----------------------|\n // | --> . . .\n // . --> | --> . .\n // . . --> | --> .\n // . . . --> |\n // . . . .\n // extrapolatedStartTime\n get _extrapolatedWindowDuration() {\n if (this._segmentTargetDuration === null)\n return 0\n\n return this._extrapolatedWindowNumSegments * this._segmentTargetDuration\n }\n\n get bandwidthEstimate() {\n return this._hls && this._hls.bandwidthEstimate\n }\n\n get defaultOptions() {\n return { preload: true }\n }\n\n get customListeners() {\n return this.options.hlsPlayback && this.options.hlsPlayback.customListeners || []\n }\n\n static get HLSJS() {\n return HLSJS\n }\n\n constructor(...args) {\n super(...args)\n // backwards compatibility (TODO: remove on 0.3.0)\n this.options.playback = { ...this.options, ...this.options.playback }\n this.options.hlsPlayback = { ...this.defaultOptions, ...this.options.hlsPlayback }\n this._minDvrSize = typeof (this.options.hlsMinimumDvrSize) === 'undefined' ? 60 : this.options.hlsMinimumDvrSize\n // The size of the start time extrapolation window measured as a multiple of segments.\n // Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is\n // removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are\n // added/removed every 5.\n this._extrapolatedWindowNumSegments = !this.options.playback || typeof (this.options.playback.extrapolatedWindowNumSegments) === 'undefined' ? 2 : this.options.playback.extrapolatedWindowNumSegments\n\n this._playbackType = Playback.VOD\n this._lastTimeUpdate = { current: 0, total: 0 }\n this._lastDuration = null\n // for hls streams which have dvr with a sliding window,\n // the content at the start of the playlist is removed as new\n // content is appended at the end.\n // this means the actual playable start time will increase as the\n // start content is deleted\n // For streams with dvr where the entire recording is kept from the\n // beginning this should stay as 0\n this._playableRegionStartTime = 0\n // {local, remote} remote is the time in the video element that should represent 0\n // local is the system time when the 'remote' measurment took place\n this._localStartTimeCorrelation = null\n // {local, remote} remote is the time in the video element that should represents the end\n // local is the system time when the 'remote' measurment took place\n this._localEndTimeCorrelation = null\n // if content is removed from the beginning then this empty area should\n // be ignored. \"playableRegionDuration\" excludes the empty area\n this._playableRegionDuration = 0\n // #EXT-X-PROGRAM-DATE-TIME\n this._programDateTime = 0\n // true when the actual duration is longer than hlsjs's live sync point\n // when this is false playableRegionDuration will be the actual duration\n // when this is true playableRegionDuration will exclude the time after the sync point\n this._durationExcludesAfterLiveSyncPoint = false\n // #EXT-X-TARGETDURATION\n this._segmentTargetDuration = null\n // #EXT-X-PLAYLIST-TYPE\n this._playlistType = null\n this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts || 16\n }\n\n _setup() {\n this._manifestParsed = false\n this._ccIsSetup = false\n this._ccTracksUpdated = false\n this._hls && this._hls.destroy()\n this._hls = new HLSJS(assign({}, this.options.playback.hlsjsConfig))\n this._hls.once(HLSJS.Events.MEDIA_ATTACHED, () => { this.options.hlsPlayback.preload && this._hls.loadSource(this.options.src) })\n this._hls.on(HLSJS.Events.MANIFEST_PARSED, () => this._manifestParsed = true)\n this._hls.on(HLSJS.Events.LEVEL_LOADED, (evt, data) => this._updatePlaybackType(evt, data))\n this._hls.on(HLSJS.Events.LEVEL_UPDATED, (evt, data) => this._onLevelUpdated(evt, data))\n this._hls.on(HLSJS.Events.LEVEL_SWITCHING, (evt,data) => this._onLevelSwitch(evt, data))\n this._hls.on(HLSJS.Events.FRAG_CHANGED, (evt, data) => this._onFragmentChanged(evt, data))\n this._hls.on(HLSJS.Events.FRAG_LOADED, (evt, data) => this._onFragmentLoaded(evt, data))\n this._hls.on(HLSJS.Events.FRAG_PARSING_METADATA, (evt, data) => this._onFragmentParsingMetadata(evt, data))\n this._hls.on(HLSJS.Events.ERROR, (evt, data) => this._onHLSJSError(evt, data))\n this._hls.on(HLSJS.Events.SUBTITLE_TRACK_LOADED, (evt, data) => this._onSubtitleLoaded(evt, data))\n this._hls.on(HLSJS.Events.SUBTITLE_TRACKS_UPDATED, () => this._ccTracksUpdated = true)\n\n this.bindCustomListeners()\n\n this._hls.attachMedia(this.el)\n }\n\n bindCustomListeners() {\n this.customListeners.forEach(item => {\n const requestedEventName = item.eventName\n const typeOfListener = item.once ? 'once': 'on'\n requestedEventName && this._hls[`${typeOfListener}`](requestedEventName, item.callback)\n })\n }\n\n unbindCustomListeners() {\n this.customListeners.forEach(item => {\n const requestedEventName = item.eventName\n requestedEventName && this._hls.off(requestedEventName, item.callback)\n })\n }\n\n _onFragmentParsingMetadata(evt, data) {\n this.trigger(Events.Custom.PLAYBACK_FRAGMENT_PARSING_METADATA, { evt, data })\n }\n\n render() {\n this._ready()\n return super.render()\n }\n\n _ready() {\n if (this._isReadyState) return\n !this._hls && this._setup()\n this._isReadyState = true\n this.trigger(Events.PLAYBACK_READY, this.name)\n }\n\n _recover(evt, data, error) {\n if (!this._recoveredDecodingError) {\n this._recoveredDecodingError = true\n this._hls.recoverMediaError()\n } else if (!this._recoveredAudioCodecError) {\n this._recoveredAudioCodecError = true\n this._hls.swapAudioCodec()\n this._hls.recoverMediaError()\n } else {\n Log.error('hlsjs: failed to recover', { evt, data })\n error.level = PlayerError.Levels.FATAL\n const formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n }\n }\n\n // override\n _setupSrc(srcUrl) { // eslint-disable-line no-unused-vars\n // this playback manages the src on the video element itself\n }\n\n _startTimeUpdateTimer() {\n if (this._timeUpdateTimer) return\n\n this._timeUpdateTimer = setInterval(() => {\n this._onDurationChange()\n this._onTimeUpdate()\n }, 100)\n }\n\n _stopTimeUpdateTimer() {\n if (!this._timeUpdateTimer) return\n\n clearInterval(this._timeUpdateTimer)\n this._timeUpdateTimer = null\n }\n\n getProgramDateTime() {\n return this._programDateTime\n }\n // the duration on the video element itself should not be used\n // as this does not necesarily represent the duration of the stream\n // https://github.com/clappr/clappr/issues/668#issuecomment-157036678\n getDuration() {\n return this._duration\n }\n\n getCurrentTime() {\n // e.g. can be < 0 if user pauses near the start\n // eventually they will then be kicked to the end by hlsjs if they run out of buffer\n // before the official start time\n return Math.max(0, this.el.currentTime - this._startTime)\n }\n\n // the time that \"0\" now represents relative to when playback started\n // for a stream with a sliding window this will increase as content is\n // removed from the beginning\n getStartTimeOffset() {\n return this._startTime\n }\n\n seekPercentage(percentage) {\n let seekTo = this._duration\n if (percentage > 0)\n seekTo = this._duration * (percentage / 100)\n\n this.seek(seekTo)\n }\n\n seek(time) {\n if (time < 0) {\n Log.warn('Attempt to seek to a negative time. Resetting to live point. Use seekToLivePoint() to seek to the live point.')\n time = this.getDuration()\n }\n // assume live if time within 3 seconds of end of stream\n this.dvrEnabled && this._updateDvr(time < this.getDuration()-3)\n time += this._startTime\n this.el.currentTime = time\n }\n\n seekToLivePoint() {\n this.seek(this.getDuration())\n }\n\n _updateDvr(status) {\n this.trigger(Events.PLAYBACK_DVR, status)\n this.trigger(Events.PLAYBACK_STATS_ADD, { 'dvr': status })\n }\n\n _updateSettings() {\n if (this._playbackType === Playback.VOD)\n this.settings.left = ['playpause', 'position', 'duration']\n else if (this.dvrEnabled)\n this.settings.left = ['playpause']\n else\n this.settings.left = ['playstop']\n\n this.settings.seekEnabled = this.isSeekEnabled()\n this.trigger(Events.PLAYBACK_SETTINGSUPDATE)\n }\n\n _onHLSJSError(evt, data) {\n const error = {\n code: `${data.type}_${data.details}`,\n description: `${this.name} error: type: ${data.type}, details: ${data.details}`,\n raw: data,\n }\n let formattedError\n if (data.response) error.description += `, response: ${JSON.stringify(data.response)}`\n // only report/handle errors if they are fatal\n // hlsjs should automatically handle non fatal errors\n if (data.fatal) {\n if (this._recoverAttemptsRemaining > 0) {\n this._recoverAttemptsRemaining -= 1\n switch (data.type) {\n case HLSJS.ErrorTypes.NETWORK_ERROR:\n switch (data.details) {\n // The following network errors cannot be recovered with HLS.startLoad()\n // For more details, see https://github.com/video-dev/hls.js/blob/master/doc/design.md#error-detection-and-handling\n // For \"level load\" fatal errors, see https://github.com/video-dev/hls.js/issues/1138\n case HLSJS.ErrorDetails.MANIFEST_LOAD_ERROR:\n case HLSJS.ErrorDetails.MANIFEST_LOAD_TIMEOUT:\n case HLSJS.ErrorDetails.MANIFEST_PARSING_ERROR:\n case HLSJS.ErrorDetails.LEVEL_LOAD_ERROR:\n case HLSJS.ErrorDetails.LEVEL_LOAD_TIMEOUT:\n Log.error('hlsjs: unrecoverable network fatal error.', { evt, data })\n formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n break\n default:\n Log.warn('hlsjs: trying to recover from network error.', { evt, data })\n error.level = PlayerError.Levels.WARN\n this._hls.startLoad()\n break\n }\n break\n case HLSJS.ErrorTypes.MEDIA_ERROR:\n Log.warn('hlsjs: trying to recover from media error.', { evt, data })\n error.level = PlayerError.Levels.WARN\n this._recover(evt, data, error)\n break\n default:\n Log.error('hlsjs: could not recover from error.', { evt, data })\n formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n break\n }\n } else {\n Log.error('hlsjs: could not recover from error after maximum number of attempts.', { evt, data })\n formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n }\n } else {\n // Transforms HLSJS.ErrorDetails.KEY_LOAD_ERROR non-fatal error to\n // playback fatal error if triggerFatalErrorOnResourceDenied playback\n // option is set. HLSJS.ErrorTypes.KEY_SYSTEM_ERROR are fatal errors\n // and therefore already handled.\n if (this.options.playback.triggerFatalErrorOnResourceDenied && this._keyIsDenied(data)) {\n Log.error('hlsjs: could not load decrypt key.', { evt, data })\n formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n return\n }\n\n error.level = PlayerError.Levels.WARN\n Log.warn('hlsjs: non-fatal error occurred', { evt, data })\n }\n }\n\n _keyIsDenied(data) {\n return data.type === HLSJS.ErrorTypes.NETWORK_ERROR\n && data.details === HLSJS.ErrorDetails.KEY_LOAD_ERROR\n && data.response\n && data.response.code >= 400\n }\n\n _onTimeUpdate() {\n let update = { current: this.getCurrentTime(), total: this.getDuration(), firstFragDateTime: this.getProgramDateTime() }\n let isSame = this._lastTimeUpdate && (\n update.current === this._lastTimeUpdate.current &&\n update.total === this._lastTimeUpdate.total)\n if (isSame)\n return\n\n this._lastTimeUpdate = update\n this.trigger(Events.PLAYBACK_TIMEUPDATE, update, this.name)\n }\n\n _onDurationChange() {\n let duration = this.getDuration()\n if (this._lastDuration === duration)\n return\n\n this._lastDuration = duration\n super._onDurationChange()\n }\n\n _onProgress() {\n if (!this.el.buffered.length)\n return\n\n let buffered = []\n let bufferedPos = 0\n for (let i = 0; i < this.el.buffered.length; i++) {\n buffered = [...buffered, {\n // for a stream with sliding window dvr something that is buffered my slide off the start of the timeline\n start: Math.max(0, this.el.buffered.start(i) - this._playableRegionStartTime),\n end: Math.max(0, this.el.buffered.end(i) - this._playableRegionStartTime)\n }]\n if (this.el.currentTime >= buffered[i].start && this.el.currentTime <= buffered[i].end)\n bufferedPos = i\n\n }\n const progress = {\n start: buffered[bufferedPos].start,\n current: buffered[bufferedPos].end,\n total: this.getDuration()\n }\n this.trigger(Events.PLAYBACK_PROGRESS, progress, buffered)\n }\n\n play() {\n !this._hls && this._setup()\n !this._manifestParsed && !this.options.hlsPlayback.preload && this._hls.loadSource(this.options.src)\n\n super.play()\n this._startTimeUpdateTimer()\n }\n\n pause() {\n if (!this._hls) return\n this.el.pause()\n if (this.dvrEnabled) this._updateDvr(true)\n }\n\n stop() {\n this._stopTimeUpdateTimer()\n if (this._hls) {\n super.stop()\n this._hls.destroy()\n delete this._hls\n }\n }\n\n destroy() {\n this._stopTimeUpdateTimer()\n if (this._hls) {\n this._hls.destroy()\n delete this._hls\n }\n super.destroy()\n }\n\n _updatePlaybackType(evt, data) {\n this._playbackType = data.details.live ? Playback.LIVE : Playback.VOD\n this._onLevelUpdated(evt, data)\n\n // Live stream subtitle tracks detection hack (may not immediately available)\n if (this._ccTracksUpdated && this._playbackType === Playback.LIVE && this.hasClosedCaptionsTracks)\n this._onSubtitleLoaded()\n\n }\n\n _fillLevels() {\n this._levels = this._hls.levels.map((level, index) => {\n return { id: index, level: level, label: `${level.bitrate/1000}Kbps` }\n })\n this.trigger(Events.PLAYBACK_LEVELS_AVAILABLE, this._levels)\n }\n\n _onLevelUpdated(evt, data) {\n this._segmentTargetDuration = data.details.targetduration\n this._playlistType = data.details.type || null\n\n let startTimeChanged = false\n let durationChanged = false\n let fragments = data.details.fragments\n let previousPlayableRegionStartTime = this._playableRegionStartTime\n let previousPlayableRegionDuration = this._playableRegionDuration\n\n if (fragments.length === 0)\n return\n\n\n // #EXT-X-PROGRAM-DATE-TIME\n if (fragments[0].rawProgramDateTime)\n this._programDateTime = fragments[0].rawProgramDateTime\n\n\n if (this._playableRegionStartTime !== fragments[0].start) {\n startTimeChanged = true\n this._playableRegionStartTime = fragments[0].start\n }\n\n if (startTimeChanged) {\n if (!this._localStartTimeCorrelation) {\n // set the correlation to map to middle of the extrapolation window\n this._localStartTimeCorrelation = {\n local: this._now,\n remote: (fragments[0].start + (this._extrapolatedWindowDuration/2)) * 1000\n }\n } else {\n // check if the correlation still works\n let corr = this._localStartTimeCorrelation\n let timePassed = this._now - corr.local\n // this should point to a time within the extrapolation window\n let startTime = (corr.remote + timePassed) / 1000\n if (startTime < fragments[0].start) {\n // our start time is now earlier than the first chunk\n // (maybe the chunk was removed early)\n // reset correlation so that it sits at the beginning of the first available chunk\n this._localStartTimeCorrelation = {\n local: this._now,\n remote: fragments[0].start * 1000\n }\n } else if (startTime > previousPlayableRegionStartTime + this._extrapolatedWindowDuration) {\n // start time was past the end of the old extrapolation window (so would have been capped)\n // see if now that time would be inside the window, and if it would be set the correlation\n // so that it resumes from the time it was at at the end of the old window\n // update the correlation so that the time starts counting again from the value it's on now\n this._localStartTimeCorrelation = {\n local: this._now,\n remote: Math.max(fragments[0].start, previousPlayableRegionStartTime + this._extrapolatedWindowDuration) * 1000\n }\n }\n }\n }\n\n let newDuration = data.details.totalduration\n // if it's a live stream then shorten the duration to remove access\n // to the area after hlsjs's live sync point\n // seeks to areas after this point sometimes have issues\n if (this._playbackType === Playback.LIVE) {\n let fragmentTargetDuration = data.details.targetduration\n let hlsjsConfig = this.options.playback.hlsjsConfig || {}\n let liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount || HLSJS.DefaultConfig.liveSyncDurationCount\n let hiddenAreaDuration = fragmentTargetDuration * liveSyncDurationCount\n if (hiddenAreaDuration <= newDuration) {\n newDuration -= hiddenAreaDuration\n this._durationExcludesAfterLiveSyncPoint = true\n } else { this._durationExcludesAfterLiveSyncPoint = false }\n\n }\n\n if (newDuration !== this._playableRegionDuration) {\n durationChanged = true\n this._playableRegionDuration = newDuration\n }\n\n // Note the end time is not the playableRegionDuration\n // The end time will always increase even if content is removed from the beginning\n let endTime = fragments[0].start + newDuration\n let previousEndTime = previousPlayableRegionStartTime + previousPlayableRegionDuration\n let endTimeChanged = endTime !== previousEndTime\n if (endTimeChanged) {\n if (!this._localEndTimeCorrelation) {\n // set the correlation to map to the end\n this._localEndTimeCorrelation = {\n local: this._now,\n remote: endTime * 1000\n }\n } else {\n // check if the correlation still works\n let corr = this._localEndTimeCorrelation\n let timePassed = this._now - corr.local\n // this should point to a time within the extrapolation window from the end\n let extrapolatedEndTime = (corr.remote + timePassed) / 1000\n if (extrapolatedEndTime > endTime) {\n this._localEndTimeCorrelation = {\n local: this._now,\n remote: endTime * 1000\n }\n } else if (extrapolatedEndTime < endTime - this._extrapolatedWindowDuration) {\n // our extrapolated end time is now earlier than the extrapolation window from the actual end time\n // (maybe a chunk became available early)\n // reset correlation so that it sits at the beginning of the extrapolation window from the end time\n this._localEndTimeCorrelation = {\n local: this._now,\n remote: (endTime - this._extrapolatedWindowDuration) * 1000\n }\n } else if (extrapolatedEndTime > previousEndTime) {\n // end time was past the old end time (so would have been capped)\n // set the correlation so that it resumes from the time it was at at the end of the old window\n this._localEndTimeCorrelation = {\n local: this._now,\n remote: previousEndTime * 1000\n }\n }\n }\n }\n\n // now that the values have been updated call any methods that use on them so they get the updated values\n // immediately\n durationChanged && this._onDurationChange()\n startTimeChanged && this._onProgress()\n }\n\n _onFragmentChanged(evt, data) {\n this.trigger(Events.Custom.PLAYBACK_FRAGMENT_CHANGED, data)\n }\n\n _onFragmentLoaded(evt, data) {\n this.trigger(Events.PLAYBACK_FRAGMENT_LOADED, data)\n }\n\n _onSubtitleLoaded() {\n // This event may be triggered multiple times\n // Setup CC only once (disable CC by default)\n if (!this._ccIsSetup) {\n this.trigger(Events.PLAYBACK_SUBTITLE_AVAILABLE)\n const trackId = this._playbackType === Playback.LIVE ? -1 : this.closedCaptionsTrackId\n this.closedCaptionsTrackId = trackId\n this._ccIsSetup = true\n }\n }\n\n _onLevelSwitch(evt, data) {\n if (!this.levels.length)\n this._fillLevels()\n\n this.trigger(Events.PLAYBACK_LEVEL_SWITCH_END)\n this.trigger(Events.PLAYBACK_LEVEL_SWITCH, data)\n let currentLevel = this._hls.levels[data.level]\n if (currentLevel) {\n // TODO should highDefinition be private and maybe have a read only accessor if it's used somewhere\n this.highDefinition = (currentLevel.height >= 720 || (currentLevel.bitrate / 1000) >= 2000)\n this.trigger(Events.PLAYBACK_HIGHDEFINITIONUPDATE, this.highDefinition)\n this.trigger(Events.PLAYBACK_BITRATE, {\n height: currentLevel.height,\n width: currentLevel.width,\n bandwidth: currentLevel.bitrate,\n bitrate: currentLevel.bitrate,\n level: data.level\n })\n }\n }\n\n get dvrEnabled() {\n // enabled when:\n // - the duration does not include content after hlsjs's live sync point\n // - the playable region duration is longer than the configured duration to enable dvr after\n // - the playback type is LIVE.\n return (this._durationExcludesAfterLiveSyncPoint && this._duration >= this._minDvrSize && this.getPlaybackType() === Playback.LIVE)\n }\n\n getPlaybackType() {\n return this._playbackType\n }\n\n isSeekEnabled() {\n return (this._playbackType === Playback.VOD || this.dvrEnabled)\n }\n}\n\nHlsjsPlayback.canPlay = function(resource, mimeType) {\n const resourceParts = resource.split('?')[0].match(/.*\\.(.*)$/) || []\n const isHls = ((resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'm3u8') || listContainsIgnoreCase(mimeType, ['application/vnd.apple.mpegurl', 'application/x-mpegURL']))\n\n return !!(HLSJS.isSupported() && isHls)\n}\n"],"names":["now","Utils","assign","listContainsIgnoreCase","Events","register","HlsjsPlayback","_HTML5Video","_inherits","_super","_createSuper","_this","_classCallCheck","this","_len","arguments","length","args","Array","_key","call","apply","concat","options","playback","_objectSpread","hlsPlayback","defaultOptions","_minDvrSize","hlsMinimumDvrSize","_extrapolatedWindowNumSegments","extrapolatedWindowNumSegments","_playbackType","Playback","VOD","_lastTimeUpdate","current","total","_lastDuration","_playableRegionStartTime","_localStartTimeCorrelation","_localEndTimeCorrelation","_playableRegionDuration","_programDateTime","_durationExcludesAfterLiveSyncPoint","_segmentTargetDuration","_playlistType","_recoverAttemptsRemaining","hlsRecoverAttempts","key","get","HLSJS","min","_levels","_currentLevel","undefined","set","id","trigger","PLAYBACK_LEVEL_SWITCH_START","hlsUseNextLevel","_hls","nextLevel","currentLevel","_isReadyState","LIVE","_extrapolatedStartTime","corr","timePassed","_now","local","extrapolatedWindowStartTime","remote","Math","_extrapolatedWindowDuration","actualEndTime","extrapolatedEndTime","max","_extrapolatedEndTime","_startTime","bandwidthEstimate","preload","customListeners","value","_this2","_manifestParsed","_ccIsSetup","_ccTracksUpdated","destroy","hlsjsConfig","once","MEDIA_ATTACHED","loadSource","src","on","MANIFEST_PARSED","LEVEL_LOADED","evt","data","_updatePlaybackType","LEVEL_UPDATED","_onLevelUpdated","LEVEL_SWITCHING","_onLevelSwitch","FRAG_CHANGED","_onFragmentChanged","FRAG_LOADED","_onFragmentLoaded","FRAG_PARSING_METADATA","_onFragmentParsingMetadata","ERROR","_onHLSJSError","SUBTITLE_TRACK_LOADED","_onSubtitleLoaded","SUBTITLE_TRACKS_UPDATED","bindCustomListeners","attachMedia","el","_this3","forEach","item","requestedEventName","eventName","typeOfListener","callback","_this4","off","Custom","PLAYBACK_FRAGMENT_PARSING_METADATA","_ready","_get","_getPrototypeOf","prototype","_setup","PLAYBACK_READY","name","error","_recoveredDecodingError","_recoveredAudioCodecError","Log","level","PlayerError","Levels","FATAL","formattedError","createError","PLAYBACK_ERROR","stop","swapAudioCodec","recoverMediaError","srcUrl","_this5","_timeUpdateTimer","setInterval","_onDurationChange","_onTimeUpdate","clearInterval","_duration","currentTime","percentage","seekTo","seek","time","warn","getDuration","dvrEnabled","_updateDvr","status","PLAYBACK_DVR","PLAYBACK_STATS_ADD","dvr","settings","left","seekEnabled","isSeekEnabled","PLAYBACK_SETTINGSUPDATE","code","type","details","description","raw","response","JSON","stringify","fatal","ErrorTypes","NETWORK_ERROR","ErrorDetails","MANIFEST_LOAD_ERROR","MANIFEST_LOAD_TIMEOUT","MANIFEST_PARSING_ERROR","LEVEL_LOAD_ERROR","LEVEL_LOAD_TIMEOUT","WARN","startLoad","MEDIA_ERROR","_recover","triggerFatalErrorOnResourceDenied","_keyIsDenied","KEY_LOAD_ERROR","update","getCurrentTime","firstFragDateTime","getProgramDateTime","PLAYBACK_TIMEUPDATE","duration","buffered","bufferedPos","i","_toConsumableArray","start","end","progress","PLAYBACK_PROGRESS","_startTimeUpdateTimer","pause","_stopTimeUpdateTimer","live","hasClosedCaptionsTracks","levels","map","index","label","bitrate","PLAYBACK_LEVELS_AVAILABLE","targetduration","startTimeChanged","durationChanged","fragments","previousPlayableRegionStartTime","previousPlayableRegionDuration","rawProgramDateTime","startTime","newDuration","totalduration","hiddenAreaDuration","liveSyncDurationCount","DefaultConfig","endTime","previousEndTime","_onProgress","PLAYBACK_FRAGMENT_CHANGED","PLAYBACK_FRAGMENT_LOADED","PLAYBACK_SUBTITLE_AVAILABLE","trackId","closedCaptionsTrackId","_fillLevels","PLAYBACK_LEVEL_SWITCH_END","PLAYBACK_LEVEL_SWITCH","highDefinition","height","PLAYBACK_HIGHDEFINITIONUPDATE","PLAYBACK_BITRATE","width","bandwidth","getPlaybackType","HTML5Video","canPlay","resource","mimeType","resourceParts","split","match","isHls","toLowerCase","isSupported"],"mappings":"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"}
1
+ {"version":3,"file":"hlsjs-playback.external.min.js","sources":["../src/hls.js"],"sourcesContent":["// Copyright 2014 Globo.com Player authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\nimport { Events, HTML5Video, Log, Playback, PlayerError, Utils } from '@clappr/core'\nimport HLSJS from 'hls.js'\n\nconst { now, listContainsIgnoreCase } = Utils\nconst AUTO = -1\nconst DEFAULT_RECOVER_ATTEMPTS = 16\n\nEvents.register('PLAYBACK_FRAGMENT_CHANGED')\nEvents.register('PLAYBACK_FRAGMENT_PARSING_METADATA')\n\nexport default class HlsjsPlayback extends HTML5Video {\n get name() { return 'hls' }\n\n get supportedVersion() { return { min: CLAPPR_CORE_VERSION } }\n\n get levels() { return this._levels || [] }\n\n get currentLevel() {\n if (this._currentLevel === null || this._currentLevel === undefined)\n return AUTO\n else\n return this._currentLevel //0 is a valid level ID\n\n }\n\n get isReady() {\n return this._isReadyState\n }\n\n set currentLevel(id) {\n this._currentLevel = id\n this.trigger(Events.PLAYBACK_LEVEL_SWITCH_START)\n if (this.options.playback.hlsUseNextLevel)\n this._hls.nextLevel = this._currentLevel\n else\n this._hls.currentLevel = this._currentLevel\n }\n\n get _startTime() {\n if (this._playbackType === Playback.LIVE && this._playlistType !== 'EVENT')\n return this._extrapolatedStartTime\n\n return this._playableRegionStartTime\n }\n\n get _now() {\n return now()\n }\n\n // the time in the video element which should represent the start of the sliding window\n // extrapolated to increase in real time (instead of jumping as the early segments are removed)\n get _extrapolatedStartTime() {\n if (!this._localStartTimeCorrelation)\n return this._playableRegionStartTime\n\n let corr = this._localStartTimeCorrelation\n let timePassed = this._now - corr.local\n let extrapolatedWindowStartTime = (corr.remote + timePassed) / 1000\n // cap at the end of the extrapolated window duration\n return Math.min(extrapolatedWindowStartTime, this._playableRegionStartTime + this._extrapolatedWindowDuration)\n }\n\n // the time in the video element which should represent the end of the content\n // extrapolated to increase in real time (instead of jumping as segments are added)\n get _extrapolatedEndTime() {\n let actualEndTime = this._playableRegionStartTime + this._playableRegionDuration\n if (!this._localEndTimeCorrelation) return actualEndTime\n const correlation = this._localEndTimeCorrelation\n const timePassed = this._now - correlation.local\n const extrapolatedEndTime = (correlation.remote + timePassed) / 1000\n return Math.max(actualEndTime - this._extrapolatedWindowDuration, Math.min(extrapolatedEndTime, actualEndTime))\n }\n\n get _duration() {\n return this._extrapolatedEndTime - this._startTime\n }\n\n // Returns the duration (seconds) of the window that the extrapolated start time is allowed\n // to move in before being capped.\n // The extrapolated start time should never reach the cap at the end of the window as the\n // window should slide as chunks are removed from the start.\n // This also applies to the extrapolated end time in the same way.\n //\n // If chunks aren't being removed for some reason that the start time will reach and remain fixed at\n // playableRegionStartTime + extrapolatedWindowDuration\n //\n // <-- window duration -->\n // I.e playableRegionStartTime |-----------------------|\n // | --> . . .\n // . --> | --> . .\n // . . --> | --> .\n // . . . --> |\n // . . . .\n // extrapolatedStartTime\n get _extrapolatedWindowDuration() {\n if (this._segmentTargetDuration === null)\n return 0\n\n return this._extrapolatedWindowNumSegments * this._segmentTargetDuration\n }\n\n get bandwidthEstimate() {\n return this._hls && this._hls.bandwidthEstimate\n }\n\n get defaultOptions() {\n return { preload: true }\n }\n\n get customListeners() {\n return this.options.hlsPlayback && this.options.hlsPlayback.customListeners || []\n }\n\n get sourceMedia() {\n return this.options.src\n }\n\n static get HLSJS() {\n return HLSJS\n }\n\n constructor(...args) {\n super(...args)\n this.options.hlsPlayback = { ...this.defaultOptions, ...this.options.hlsPlayback }\n this._setInitialState()\n }\n\n _setInitialState() {\n this._minDvrSize = typeof (this.options.hlsMinimumDvrSize) === 'undefined' ? 60 : this.options.hlsMinimumDvrSize\n // The size of the start time extrapolation window measured as a multiple of segments.\n // Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is\n // removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are\n // added/removed every 5.\n this._extrapolatedWindowNumSegments = !this.options.playback || typeof (this.options.playback.extrapolatedWindowNumSegments) === 'undefined' ? 2 : this.options.playback.extrapolatedWindowNumSegments\n\n this._playbackType = Playback.VOD\n this._lastTimeUpdate = { current: 0, total: 0 }\n this._lastDuration = null\n // for hls streams which have dvr with a sliding window,\n // the content at the start of the playlist is removed as new\n // content is appended at the end.\n // this means the actual playable start time will increase as the\n // start content is deleted\n // For streams with dvr where the entire recording is kept from the\n // beginning this should stay as 0\n this._playableRegionStartTime = 0\n // {local, remote} remote is the time in the video element that should represent 0\n // local is the system time when the 'remote' measurment took place\n this._localStartTimeCorrelation = null\n // {local, remote} remote is the time in the video element that should represents the end\n // local is the system time when the 'remote' measurment took place\n this._localEndTimeCorrelation = null\n // if content is removed from the beginning then this empty area should\n // be ignored. \"playableRegionDuration\" excludes the empty area\n this._playableRegionDuration = 0\n // #EXT-X-PROGRAM-DATE-TIME\n this._programDateTime = 0\n // true when the actual duration is longer than hlsjs's live sync point\n // when this is false playableRegionDuration will be the actual duration\n // when this is true playableRegionDuration will exclude the time after the sync point\n this._durationExcludesAfterLiveSyncPoint = false\n // #EXT-X-TARGETDURATION\n this._segmentTargetDuration = null\n // #EXT-X-PLAYLIST-TYPE\n this._playlistType = null\n this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts || DEFAULT_RECOVER_ATTEMPTS\n }\n\n _setup() {\n this._destroyHLSInstance()\n this._createHLSInstance()\n this._listenHLSEvents()\n this._attachHLSMedia()\n }\n\n _destroyHLSInstance() {\n if (!this._hls) return\n this._manifestParsed = false\n this._ccIsSetup = false\n this._ccTracksUpdated = false\n this._setInitialState()\n this._hls.destroy()\n this._hls = null\n }\n\n _createHLSInstance() {\n const config = { ...this.options.playback.hlsjsConfig }\n this._hls = new HLSJS(config)\n }\n\n _attachHLSMedia() {\n if (!this._hls) return\n this._hls.attachMedia(this.el)\n }\n\n _listenHLSEvents() {\n if (!this._hls) return\n this._hls.once(HLSJS.Events.MEDIA_ATTACHED, () => { this.options.hlsPlayback.preload && this._hls.loadSource(this.options.src) })\n this._hls.on(HLSJS.Events.MANIFEST_PARSED, () => this._manifestParsed = true)\n this._hls.on(HLSJS.Events.LEVEL_LOADED, (evt, data) => this._updatePlaybackType(evt, data))\n this._hls.on(HLSJS.Events.LEVEL_UPDATED, (evt, data) => this._onLevelUpdated(evt, data))\n this._hls.on(HLSJS.Events.LEVEL_SWITCHING, (evt,data) => this._onLevelSwitch(evt, data))\n this._hls.on(HLSJS.Events.FRAG_CHANGED, (evt, data) => this._onFragmentChanged(evt, data))\n this._hls.on(HLSJS.Events.FRAG_LOADED, (evt, data) => this._onFragmentLoaded(evt, data))\n this._hls.on(HLSJS.Events.FRAG_PARSING_METADATA, (evt, data) => this._onFragmentParsingMetadata(evt, data))\n this._hls.on(HLSJS.Events.ERROR, (evt, data) => this._onHLSJSError(evt, data))\n this._hls.on(HLSJS.Events.SUBTITLE_TRACK_LOADED, (evt, data) => this._onSubtitleLoaded(evt, data))\n this._hls.on(HLSJS.Events.SUBTITLE_TRACKS_UPDATED, () => this._ccTracksUpdated = true)\n this.bindCustomListeners()\n }\n\n bindCustomListeners() {\n this.customListeners.forEach(item => {\n const requestedEventName = item.eventName\n const typeOfListener = item.once ? 'once': 'on'\n requestedEventName && this._hls[`${typeOfListener}`](requestedEventName, item.callback)\n })\n }\n\n unbindCustomListeners() {\n this.customListeners.forEach(item => {\n const requestedEventName = item.eventName\n requestedEventName && this._hls.off(requestedEventName, item.callback)\n })\n }\n\n _onFragmentParsingMetadata(evt, data) {\n this.trigger(Events.Custom.PLAYBACK_FRAGMENT_PARSING_METADATA, { evt, data })\n }\n\n render() {\n this._ready()\n return super.render()\n }\n\n _ready() {\n if (this._isReadyState) return\n !this._hls && this._setup()\n this._isReadyState = true\n this.trigger(Events.PLAYBACK_READY, this.name)\n }\n\n _recover(evt, data, error) {\n if (!this._recoveredDecodingError) {\n this._recoveredDecodingError = true\n this._hls.recoverMediaError()\n } else if (!this._recoveredAudioCodecError) {\n this._recoveredAudioCodecError = true\n this._hls.swapAudioCodec()\n this._hls.recoverMediaError()\n } else {\n Log.error('hlsjs: failed to recover', { evt, data })\n error.level = PlayerError.Levels.FATAL\n const formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n }\n }\n\n // override\n // this playback manages the src on the video element itself\n _setupSrc(srcUrl) {} // eslint-disable-line no-unused-vars\n\n _startTimeUpdateTimer() {\n if (this._timeUpdateTimer) return\n this._timeUpdateTimer = setInterval(() => {\n this._onDurationChange()\n this._onTimeUpdate()\n }, 100)\n }\n\n _stopTimeUpdateTimer() {\n if (!this._timeUpdateTimer) return\n clearInterval(this._timeUpdateTimer)\n this._timeUpdateTimer = null\n }\n\n getProgramDateTime() {\n return this._programDateTime\n }\n\n // the duration on the video element itself should not be used\n // as this does not necesarily represent the duration of the stream\n // https://github.com/clappr/clappr/issues/668#issuecomment-157036678\n getDuration() {\n return this._duration\n }\n\n getCurrentTime() {\n // e.g. can be < 0 if user pauses near the start\n // eventually they will then be kicked to the end by hlsjs if they run out of buffer\n // before the official start time\n return Math.max(0, this.el.currentTime - this._startTime)\n }\n\n // the time that \"0\" now represents relative to when playback started\n // for a stream with a sliding window this will increase as content is\n // removed from the beginning\n getStartTimeOffset() {\n return this._startTime\n }\n\n seekPercentage(percentage) {\n const seekTo = (percentage > 0)\n ? this._duration * (percentage / 100)\n : this._duration\n this.seek(seekTo)\n }\n\n seek(time) {\n if (time < 0) {\n Log.warn('Attempt to seek to a negative time. Resetting to live point. Use seekToLivePoint() to seek to the live point.')\n time = this.getDuration()\n }\n // assume live if time within 3 seconds of end of stream\n this.dvrEnabled && this._updateDvr(time < this.getDuration()-3)\n time += this._startTime\n this.el.currentTime = time\n }\n\n seekToLivePoint() {\n this.seek(this.getDuration())\n }\n\n _updateDvr(status) {\n this.trigger(Events.PLAYBACK_DVR, status)\n this.trigger(Events.PLAYBACK_STATS_ADD, { 'dvr': status })\n }\n\n _updateSettings() {\n if (this._playbackType === Playback.VOD)\n this.settings.left = ['playpause', 'position', 'duration']\n else if (this.dvrEnabled)\n this.settings.left = ['playpause']\n else\n this.settings.left = ['playstop']\n\n this.settings.seekEnabled = this.isSeekEnabled()\n this.trigger(Events.PLAYBACK_SETTINGSUPDATE)\n }\n\n _onHLSJSError(evt, data) {\n const error = {\n code: `${data.type}_${data.details}`,\n description: `${this.name} error: type: ${data.type}, details: ${data.details}`,\n raw: data,\n }\n let formattedError\n if (data.response) error.description += `, response: ${JSON.stringify(data.response)}`\n // only report/handle errors if they are fatal\n // hlsjs should automatically handle non fatal errors\n if (data.fatal) {\n if (this._recoverAttemptsRemaining > 0) {\n this._recoverAttemptsRemaining -= 1\n switch (data.type) {\n case HLSJS.ErrorTypes.NETWORK_ERROR:\n switch (data.details) {\n // The following network errors cannot be recovered with HLS.startLoad()\n // For more details, see https://github.com/video-dev/hls.js/blob/master/doc/design.md#error-detection-and-handling\n // For \"level load\" fatal errors, see https://github.com/video-dev/hls.js/issues/1138\n case HLSJS.ErrorDetails.MANIFEST_LOAD_ERROR:\n case HLSJS.ErrorDetails.MANIFEST_LOAD_TIMEOUT:\n case HLSJS.ErrorDetails.MANIFEST_PARSING_ERROR:\n case HLSJS.ErrorDetails.LEVEL_LOAD_ERROR:\n case HLSJS.ErrorDetails.LEVEL_LOAD_TIMEOUT:\n Log.error('hlsjs: unrecoverable network fatal error.', { evt, data })\n formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n break\n default:\n Log.warn('hlsjs: trying to recover from network error.', { evt, data })\n error.level = PlayerError.Levels.WARN\n this._hls.startLoad()\n break\n }\n break\n case HLSJS.ErrorTypes.MEDIA_ERROR:\n Log.warn('hlsjs: trying to recover from media error.', { evt, data })\n error.level = PlayerError.Levels.WARN\n this._recover(evt, data, error)\n break\n default:\n Log.error('hlsjs: could not recover from error.', { evt, data })\n formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n break\n }\n } else {\n Log.error('hlsjs: could not recover from error after maximum number of attempts.', { evt, data })\n formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n }\n } else {\n // Transforms HLSJS.ErrorDetails.KEY_LOAD_ERROR non-fatal error to\n // playback fatal error if triggerFatalErrorOnResourceDenied playback\n // option is set. HLSJS.ErrorTypes.KEY_SYSTEM_ERROR are fatal errors\n // and therefore already handled.\n if (this.options.playback.triggerFatalErrorOnResourceDenied && this._keyIsDenied(data)) {\n Log.error('hlsjs: could not load decrypt key.', { evt, data })\n formattedError = this.createError(error)\n this.trigger(Events.PLAYBACK_ERROR, formattedError)\n this.stop()\n return\n }\n\n error.level = PlayerError.Levels.WARN\n Log.warn('hlsjs: non-fatal error occurred', { evt, data })\n }\n }\n\n _keyIsDenied(data) {\n return data.type === HLSJS.ErrorTypes.NETWORK_ERROR\n && data.details === HLSJS.ErrorDetails.KEY_LOAD_ERROR\n && data.response\n && data.response.code >= 400\n }\n\n _onTimeUpdate() {\n const update = { current: this.getCurrentTime(), total: this.getDuration(), firstFragDateTime: this.getProgramDateTime() }\n const isSame = this._lastTimeUpdate && (\n update.current === this._lastTimeUpdate.current &&\n update.total === this._lastTimeUpdate.total) \n if (isSame) return\n this._lastTimeUpdate = update\n this.trigger(Events.PLAYBACK_TIMEUPDATE, update, this.name)\n }\n\n _onDurationChange() {\n const duration = this.getDuration()\n if (this._lastDuration === duration) return\n this._lastDuration = duration\n super._onDurationChange()\n }\n\n _onProgress() {\n if (!this.el.buffered.length) return\n let buffered = []\n let bufferedPos = 0\n for (let i = 0; i < this.el.buffered.length; i++) {\n buffered = [...buffered, {\n // for a stream with sliding window dvr something that is buffered my slide off the start of the timeline\n start: Math.max(0, this.el.buffered.start(i) - this._playableRegionStartTime),\n end: Math.max(0, this.el.buffered.end(i) - this._playableRegionStartTime)\n }]\n if (this.el.currentTime >= buffered[i].start && this.el.currentTime <= buffered[i].end)\n bufferedPos = i\n\n }\n const progress = {\n start: buffered[bufferedPos].start,\n current: buffered[bufferedPos].end,\n total: this.getDuration()\n }\n this.trigger(Events.PLAYBACK_PROGRESS, progress, buffered)\n }\n\n load(url) { \n this._stopTimeUpdateTimer()\n this.options.src = url\n this._setup()\n }\n\n play() {\n !this._hls && this._setup()\n !this._manifestParsed && !this.options.hlsPlayback.preload && this._hls.loadSource(this.options.src)\n super.play()\n this._startTimeUpdateTimer()\n }\n\n pause() {\n if (!this._hls) return\n this.el.pause()\n if (this.dvrEnabled) this._updateDvr(true)\n }\n\n stop() {\n this._stopTimeUpdateTimer()\n if (this._hls) super.stop()\n this._destroyHLSInstance()\n }\n\n destroy() {\n this._stopTimeUpdateTimer()\n this._destroyHLSInstance()\n super.destroy()\n }\n\n _updatePlaybackType(evt, data) {\n this._playbackType = data.details.live ? Playback.LIVE : Playback.VOD\n this._onLevelUpdated(evt, data)\n // Live stream subtitle tracks detection hack (may not immediately available)\n if (this._ccTracksUpdated && this._playbackType === Playback.LIVE && this.hasClosedCaptionsTracks)\n this._onSubtitleLoaded()\n\n }\n\n _fillLevels() {\n this._levels = this._hls.levels.map((level, index) => {\n return { id: index, level: level, label: `${level.bitrate/1000}Kbps` }\n })\n this.trigger(Events.PLAYBACK_LEVELS_AVAILABLE, this._levels)\n }\n\n _onLevelUpdated(evt, data) {\n this._segmentTargetDuration = data.details.targetduration\n this._playlistType = data.details.type || null\n let startTimeChanged = false\n let durationChanged = false\n let fragments = data.details.fragments\n let previousPlayableRegionStartTime = this._playableRegionStartTime\n let previousPlayableRegionDuration = this._playableRegionDuration\n if (fragments.length === 0) return\n // #EXT-X-PROGRAM-DATE-TIME\n if (fragments[0].rawProgramDateTime)\n this._programDateTime = fragments[0].rawProgramDateTime\n if (this._playableRegionStartTime !== fragments[0].start) {\n startTimeChanged = true\n this._playableRegionStartTime = fragments[0].start\n }\n\n if (startTimeChanged) {\n if (!this._localStartTimeCorrelation) {\n // set the correlation to map to middle of the extrapolation window\n this._localStartTimeCorrelation = {\n local: this._now,\n remote: (fragments[0].start + (this._extrapolatedWindowDuration/2)) * 1000\n }\n } else {\n // check if the correlation still works\n let corr = this._localStartTimeCorrelation\n let timePassed = this._now - corr.local\n // this should point to a time within the extrapolation window\n let startTime = (corr.remote + timePassed) / 1000\n if (startTime < fragments[0].start) {\n // our start time is now earlier than the first chunk\n // (maybe the chunk was removed early)\n // reset correlation so that it sits at the beginning of the first available chunk\n this._localStartTimeCorrelation = {\n local: this._now,\n remote: fragments[0].start * 1000\n }\n } else if (startTime > previousPlayableRegionStartTime + this._extrapolatedWindowDuration) {\n // start time was past the end of the old extrapolation window (so would have been capped)\n // see if now that time would be inside the window, and if it would be set the correlation\n // so that it resumes from the time it was at at the end of the old window\n // update the correlation so that the time starts counting again from the value it's on now\n this._localStartTimeCorrelation = {\n local: this._now,\n remote: Math.max(fragments[0].start, previousPlayableRegionStartTime + this._extrapolatedWindowDuration) * 1000\n }\n }\n }\n }\n \n let newDuration = data.details.totalduration\n // if it's a live stream then shorten the duration to remove access\n // to the area after hlsjs's live sync point\n // seeks to areas after this point sometimes have issues\n if (this._playbackType === Playback.LIVE) {\n let fragmentTargetDuration = data.details.targetduration\n let hlsjsConfig = this.options.playback.hlsjsConfig || {}\n let liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount || HLSJS.DefaultConfig.liveSyncDurationCount\n let hiddenAreaDuration = fragmentTargetDuration * liveSyncDurationCount\n if (hiddenAreaDuration <= newDuration) {\n newDuration -= hiddenAreaDuration\n this._durationExcludesAfterLiveSyncPoint = true\n } else { this._durationExcludesAfterLiveSyncPoint = false }\n\n }\n if (newDuration !== this._playableRegionDuration) {\n durationChanged = true\n this._playableRegionDuration = newDuration\n }\n // Note the end time is not the playableRegionDuration\n // The end time will always increase even if content is removed from the beginning\n let endTime = fragments[0].start + newDuration\n let previousEndTime = previousPlayableRegionStartTime + previousPlayableRegionDuration\n let endTimeChanged = endTime !== previousEndTime\n if (endTimeChanged) {\n if (!this._localEndTimeCorrelation) {\n // set the correlation to map to the end\n this._localEndTimeCorrelation = {\n local: this._now,\n remote: endTime * 1000\n }\n } else {\n // check if the correlation still works\n let corr = this._localEndTimeCorrelation\n let timePassed = this._now - corr.local\n // this should point to a time within the extrapolation window from the end\n let extrapolatedEndTime = (corr.remote + timePassed) / 1000\n if (extrapolatedEndTime > endTime) {\n this._localEndTimeCorrelation = {\n local: this._now,\n remote: endTime * 1000\n }\n } else if (extrapolatedEndTime < endTime - this._extrapolatedWindowDuration) {\n // our extrapolated end time is now earlier than the extrapolation window from the actual end time\n // (maybe a chunk became available early)\n // reset correlation so that it sits at the beginning of the extrapolation window from the end time\n this._localEndTimeCorrelation = {\n local: this._now,\n remote: (endTime - this._extrapolatedWindowDuration) * 1000\n }\n } else if (extrapolatedEndTime > previousEndTime) {\n // end time was past the old end time (so would have been capped)\n // set the correlation so that it resumes from the time it was at at the end of the old window\n this._localEndTimeCorrelation = {\n local: this._now,\n remote: previousEndTime * 1000\n }\n }\n }\n }\n\n // now that the values have been updated call any methods that use on them so they get the updated values\n // immediately\n durationChanged && this._onDurationChange()\n startTimeChanged && this._onProgress()\n }\n\n _onFragmentChanged(evt, data) {\n this.trigger(Events.Custom.PLAYBACK_FRAGMENT_CHANGED, data)\n }\n\n _onFragmentLoaded(evt, data) {\n this.trigger(Events.PLAYBACK_FRAGMENT_LOADED, data)\n }\n\n _onSubtitleLoaded() {\n // This event may be triggered multiple times\n // Setup CC only once (disable CC by default)\n if (!this._ccIsSetup) {\n this.trigger(Events.PLAYBACK_SUBTITLE_AVAILABLE)\n const trackId = this._playbackType === Playback.LIVE ? -1 : this.closedCaptionsTrackId\n this.closedCaptionsTrackId = trackId\n this._ccIsSetup = true\n }\n }\n\n _onLevelSwitch(evt, data) {\n if (!this.levels.length) this._fillLevels()\n this.trigger(Events.PLAYBACK_LEVEL_SWITCH_END)\n this.trigger(Events.PLAYBACK_LEVEL_SWITCH, data)\n let currentLevel = this._hls.levels[data.level]\n if (currentLevel) {\n // TODO should highDefinition be private and maybe have a read only accessor if it's used somewhere\n this.highDefinition = (currentLevel.height >= 720 || (currentLevel.bitrate / 1000) >= 2000)\n this.trigger(Events.PLAYBACK_HIGHDEFINITIONUPDATE, this.highDefinition)\n this.trigger(Events.PLAYBACK_BITRATE, {\n height: currentLevel.height,\n width: currentLevel.width,\n bandwidth: currentLevel.bitrate,\n bitrate: currentLevel.bitrate,\n level: data.level\n })\n }\n }\n\n get dvrEnabled() {\n // enabled when:\n // - the duration does not include content after hlsjs's live sync point\n // - the playable region duration is longer than the configured duration to enable dvr after\n // - the playback type is LIVE.\n return (this._durationExcludesAfterLiveSyncPoint && this._duration >= this._minDvrSize && this.getPlaybackType() === Playback.LIVE)\n }\n\n getPlaybackType() {\n return this._playbackType\n }\n\n isSeekEnabled() {\n return (this._playbackType === Playback.VOD || this.dvrEnabled)\n }\n}\n\nHlsjsPlayback.canPlay = function(resource, mimeType) {\n const resourceParts = resource.split('?')[0].match(/.*\\.(.*)$/) || []\n const isHls = ((resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'm3u8') || listContainsIgnoreCase(mimeType, ['application/vnd.apple.mpegurl', 'application/x-mpegURL']))\n return !!(HLSJS.isSupported() && isHls)\n}\n"],"names":["now","Utils","listContainsIgnoreCase","Events","register","HlsjsPlayback","_HTML5Video","_inherits","_super","_createSuper","_this","_classCallCheck","this","_len","arguments","length","args","Array","_key","call","apply","concat","options","hlsPlayback","_objectSpread","defaultOptions","_setInitialState","key","get","HLSJS","min","_levels","_currentLevel","undefined","set","id","trigger","PLAYBACK_LEVEL_SWITCH_START","playback","hlsUseNextLevel","_hls","nextLevel","currentLevel","_isReadyState","_playbackType","Playback","LIVE","_playlistType","_extrapolatedStartTime","_playableRegionStartTime","_localStartTimeCorrelation","corr","timePassed","_now","local","extrapolatedWindowStartTime","remote","Math","_extrapolatedWindowDuration","actualEndTime","_playableRegionDuration","_localEndTimeCorrelation","correlation","extrapolatedEndTime","max","_extrapolatedEndTime","_startTime","_segmentTargetDuration","_extrapolatedWindowNumSegments","bandwidthEstimate","preload","customListeners","src","value","_minDvrSize","hlsMinimumDvrSize","extrapolatedWindowNumSegments","VOD","_lastTimeUpdate","current","total","_lastDuration","_programDateTime","_durationExcludesAfterLiveSyncPoint","_recoverAttemptsRemaining","hlsRecoverAttempts","_destroyHLSInstance","_createHLSInstance","_listenHLSEvents","_attachHLSMedia","_manifestParsed","_ccIsSetup","_ccTracksUpdated","destroy","config","hlsjsConfig","attachMedia","el","_this2","once","MEDIA_ATTACHED","loadSource","on","MANIFEST_PARSED","LEVEL_LOADED","evt","data","_updatePlaybackType","LEVEL_UPDATED","_onLevelUpdated","LEVEL_SWITCHING","_onLevelSwitch","FRAG_CHANGED","_onFragmentChanged","FRAG_LOADED","_onFragmentLoaded","FRAG_PARSING_METADATA","_onFragmentParsingMetadata","ERROR","_onHLSJSError","SUBTITLE_TRACK_LOADED","_onSubtitleLoaded","SUBTITLE_TRACKS_UPDATED","bindCustomListeners","_this3","forEach","item","requestedEventName","eventName","typeOfListener","callback","_this4","off","Custom","PLAYBACK_FRAGMENT_PARSING_METADATA","_ready","_get","_getPrototypeOf","prototype","_setup","PLAYBACK_READY","name","error","_recoveredDecodingError","_recoveredAudioCodecError","Log","level","PlayerError","Levels","FATAL","formattedError","createError","PLAYBACK_ERROR","stop","swapAudioCodec","recoverMediaError","srcUrl","_this5","_timeUpdateTimer","setInterval","_onDurationChange","_onTimeUpdate","clearInterval","_duration","currentTime","percentage","seekTo","seek","time","warn","getDuration","dvrEnabled","_updateDvr","status","PLAYBACK_DVR","PLAYBACK_STATS_ADD","dvr","settings","left","seekEnabled","isSeekEnabled","PLAYBACK_SETTINGSUPDATE","code","type","details","description","raw","response","JSON","stringify","fatal","ErrorTypes","NETWORK_ERROR","ErrorDetails","MANIFEST_LOAD_ERROR","MANIFEST_LOAD_TIMEOUT","MANIFEST_PARSING_ERROR","LEVEL_LOAD_ERROR","LEVEL_LOAD_TIMEOUT","WARN","startLoad","MEDIA_ERROR","_recover","triggerFatalErrorOnResourceDenied","_keyIsDenied","KEY_LOAD_ERROR","update","getCurrentTime","firstFragDateTime","getProgramDateTime","PLAYBACK_TIMEUPDATE","duration","buffered","bufferedPos","i","_toConsumableArray","start","end","progress","PLAYBACK_PROGRESS","url","_stopTimeUpdateTimer","_startTimeUpdateTimer","pause","live","hasClosedCaptionsTracks","levels","map","index","label","bitrate","PLAYBACK_LEVELS_AVAILABLE","targetduration","startTimeChanged","durationChanged","fragments","previousPlayableRegionStartTime","previousPlayableRegionDuration","rawProgramDateTime","startTime","newDuration","totalduration","hiddenAreaDuration","liveSyncDurationCount","DefaultConfig","endTime","previousEndTime","_onProgress","PLAYBACK_FRAGMENT_CHANGED","PLAYBACK_FRAGMENT_LOADED","PLAYBACK_SUBTITLE_AVAILABLE","trackId","closedCaptionsTrackId","_fillLevels","PLAYBACK_LEVEL_SWITCH_END","PLAYBACK_LEVEL_SWITCH","highDefinition","height","PLAYBACK_HIGHDEFINITIONUPDATE","PLAYBACK_BITRATE","width","bandwidth","getPlaybackType","HTML5Video","canPlay","resource","mimeType","resourceParts","split","match","isHls","toLowerCase","isSupported"],"mappings":"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"}
@@ -25680,9 +25680,9 @@
25680
25680
  var HLSJS = /*@__PURE__*/getDefaultExportFromCjs(hls.exports);
25681
25681
 
25682
25682
  var now = core.Utils.now,
25683
- assign = core.Utils.assign,
25684
25683
  listContainsIgnoreCase = core.Utils.listContainsIgnoreCase;
25685
25684
  var AUTO = -1;
25685
+ var DEFAULT_RECOVER_ATTEMPTS = 16;
25686
25686
  core.Events.register('PLAYBACK_FRAGMENT_CHANGED');
25687
25687
  core.Events.register('PLAYBACK_FRAGMENT_PARSING_METADATA');
25688
25688
  var HlsjsPlayback = /*#__PURE__*/function (_HTML5Video) {
@@ -25695,49 +25695,8 @@
25695
25695
  args[_key] = arguments[_key];
25696
25696
  }
25697
25697
  _this = _super.call.apply(_super, [this].concat(args));
25698
- // backwards compatibility (TODO: remove on 0.3.0)
25699
- _this.options.playback = _objectSpread2(_objectSpread2({}, _this.options), _this.options.playback);
25700
25698
  _this.options.hlsPlayback = _objectSpread2(_objectSpread2({}, _this.defaultOptions), _this.options.hlsPlayback);
25701
- _this._minDvrSize = typeof _this.options.hlsMinimumDvrSize === 'undefined' ? 60 : _this.options.hlsMinimumDvrSize;
25702
- // The size of the start time extrapolation window measured as a multiple of segments.
25703
- // Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is
25704
- // removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are
25705
- // added/removed every 5.
25706
- _this._extrapolatedWindowNumSegments = !_this.options.playback || typeof _this.options.playback.extrapolatedWindowNumSegments === 'undefined' ? 2 : _this.options.playback.extrapolatedWindowNumSegments;
25707
- _this._playbackType = core.Playback.VOD;
25708
- _this._lastTimeUpdate = {
25709
- current: 0,
25710
- total: 0
25711
- };
25712
- _this._lastDuration = null;
25713
- // for hls streams which have dvr with a sliding window,
25714
- // the content at the start of the playlist is removed as new
25715
- // content is appended at the end.
25716
- // this means the actual playable start time will increase as the
25717
- // start content is deleted
25718
- // For streams with dvr where the entire recording is kept from the
25719
- // beginning this should stay as 0
25720
- _this._playableRegionStartTime = 0;
25721
- // {local, remote} remote is the time in the video element that should represent 0
25722
- // local is the system time when the 'remote' measurment took place
25723
- _this._localStartTimeCorrelation = null;
25724
- // {local, remote} remote is the time in the video element that should represents the end
25725
- // local is the system time when the 'remote' measurment took place
25726
- _this._localEndTimeCorrelation = null;
25727
- // if content is removed from the beginning then this empty area should
25728
- // be ignored. "playableRegionDuration" excludes the empty area
25729
- _this._playableRegionDuration = 0;
25730
- // #EXT-X-PROGRAM-DATE-TIME
25731
- _this._programDateTime = 0;
25732
- // true when the actual duration is longer than hlsjs's live sync point
25733
- // when this is false playableRegionDuration will be the actual duration
25734
- // when this is true playableRegionDuration will exclude the time after the sync point
25735
- _this._durationExcludesAfterLiveSyncPoint = false;
25736
- // #EXT-X-TARGETDURATION
25737
- _this._segmentTargetDuration = null;
25738
- // #EXT-X-PLAYLIST-TYPE
25739
- _this._playlistType = null;
25740
- _this._recoverAttemptsRemaining = _this.options.hlsRecoverAttempts || 16;
25699
+ _this._setInitialState();
25741
25700
  return _this;
25742
25701
  }
25743
25702
  _createClass(HlsjsPlayback, [{
@@ -25804,9 +25763,9 @@
25804
25763
  get: function get() {
25805
25764
  var actualEndTime = this._playableRegionStartTime + this._playableRegionDuration;
25806
25765
  if (!this._localEndTimeCorrelation) return actualEndTime;
25807
- var corr = this._localEndTimeCorrelation;
25808
- var timePassed = this._now - corr.local;
25809
- var extrapolatedEndTime = (corr.remote + timePassed) / 1000;
25766
+ var correlation = this._localEndTimeCorrelation;
25767
+ var timePassed = this._now - correlation.local;
25768
+ var extrapolatedEndTime = (correlation.remote + timePassed) / 1000;
25810
25769
  return Math.max(actualEndTime - this._extrapolatedWindowDuration, Math.min(extrapolatedEndTime, actualEndTime));
25811
25770
  }
25812
25771
  }, {
@@ -25855,15 +25814,91 @@
25855
25814
  get: function get() {
25856
25815
  return this.options.hlsPlayback && this.options.hlsPlayback.customListeners || [];
25857
25816
  }
25817
+ }, {
25818
+ key: "sourceMedia",
25819
+ get: function get() {
25820
+ return this.options.src;
25821
+ }
25822
+ }, {
25823
+ key: "_setInitialState",
25824
+ value: function _setInitialState() {
25825
+ this._minDvrSize = typeof this.options.hlsMinimumDvrSize === 'undefined' ? 60 : this.options.hlsMinimumDvrSize;
25826
+ // The size of the start time extrapolation window measured as a multiple of segments.
25827
+ // Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is
25828
+ // removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are
25829
+ // added/removed every 5.
25830
+ this._extrapolatedWindowNumSegments = !this.options.playback || typeof this.options.playback.extrapolatedWindowNumSegments === 'undefined' ? 2 : this.options.playback.extrapolatedWindowNumSegments;
25831
+ this._playbackType = core.Playback.VOD;
25832
+ this._lastTimeUpdate = {
25833
+ current: 0,
25834
+ total: 0
25835
+ };
25836
+ this._lastDuration = null;
25837
+ // for hls streams which have dvr with a sliding window,
25838
+ // the content at the start of the playlist is removed as new
25839
+ // content is appended at the end.
25840
+ // this means the actual playable start time will increase as the
25841
+ // start content is deleted
25842
+ // For streams with dvr where the entire recording is kept from the
25843
+ // beginning this should stay as 0
25844
+ this._playableRegionStartTime = 0;
25845
+ // {local, remote} remote is the time in the video element that should represent 0
25846
+ // local is the system time when the 'remote' measurment took place
25847
+ this._localStartTimeCorrelation = null;
25848
+ // {local, remote} remote is the time in the video element that should represents the end
25849
+ // local is the system time when the 'remote' measurment took place
25850
+ this._localEndTimeCorrelation = null;
25851
+ // if content is removed from the beginning then this empty area should
25852
+ // be ignored. "playableRegionDuration" excludes the empty area
25853
+ this._playableRegionDuration = 0;
25854
+ // #EXT-X-PROGRAM-DATE-TIME
25855
+ this._programDateTime = 0;
25856
+ // true when the actual duration is longer than hlsjs's live sync point
25857
+ // when this is false playableRegionDuration will be the actual duration
25858
+ // when this is true playableRegionDuration will exclude the time after the sync point
25859
+ this._durationExcludesAfterLiveSyncPoint = false;
25860
+ // #EXT-X-TARGETDURATION
25861
+ this._segmentTargetDuration = null;
25862
+ // #EXT-X-PLAYLIST-TYPE
25863
+ this._playlistType = null;
25864
+ this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts || DEFAULT_RECOVER_ATTEMPTS;
25865
+ }
25858
25866
  }, {
25859
25867
  key: "_setup",
25860
25868
  value: function _setup() {
25861
- var _this2 = this;
25869
+ this._destroyHLSInstance();
25870
+ this._createHLSInstance();
25871
+ this._listenHLSEvents();
25872
+ this._attachHLSMedia();
25873
+ }
25874
+ }, {
25875
+ key: "_destroyHLSInstance",
25876
+ value: function _destroyHLSInstance() {
25877
+ if (!this._hls) return;
25862
25878
  this._manifestParsed = false;
25863
25879
  this._ccIsSetup = false;
25864
25880
  this._ccTracksUpdated = false;
25865
- this._hls && this._hls.destroy();
25866
- this._hls = new HLSJS(assign({}, this.options.playback.hlsjsConfig));
25881
+ this._setInitialState();
25882
+ this._hls.destroy();
25883
+ this._hls = null;
25884
+ }
25885
+ }, {
25886
+ key: "_createHLSInstance",
25887
+ value: function _createHLSInstance() {
25888
+ var config = _objectSpread2({}, this.options.playback.hlsjsConfig);
25889
+ this._hls = new HLSJS(config);
25890
+ }
25891
+ }, {
25892
+ key: "_attachHLSMedia",
25893
+ value: function _attachHLSMedia() {
25894
+ if (!this._hls) return;
25895
+ this._hls.attachMedia(this.el);
25896
+ }
25897
+ }, {
25898
+ key: "_listenHLSEvents",
25899
+ value: function _listenHLSEvents() {
25900
+ var _this2 = this;
25901
+ if (!this._hls) return;
25867
25902
  this._hls.once(HLSJS.Events.MEDIA_ATTACHED, function () {
25868
25903
  _this2.options.hlsPlayback.preload && _this2._hls.loadSource(_this2.options.src);
25869
25904
  });
@@ -25898,7 +25933,6 @@
25898
25933
  return _this2._ccTracksUpdated = true;
25899
25934
  });
25900
25935
  this.bindCustomListeners();
25901
- this._hls.attachMedia(this.el);
25902
25936
  }
25903
25937
  }, {
25904
25938
  key: "bindCustomListeners",
@@ -25964,11 +25998,10 @@
25964
25998
  }
25965
25999
 
25966
26000
  // override
26001
+ // this playback manages the src on the video element itself
25967
26002
  }, {
25968
26003
  key: "_setupSrc",
25969
- value: function _setupSrc(srcUrl) {// eslint-disable-line no-unused-vars
25970
- // this playback manages the src on the video element itself
25971
- }
26004
+ value: function _setupSrc(srcUrl) {} // eslint-disable-line no-unused-vars
25972
26005
  }, {
25973
26006
  key: "_startTimeUpdateTimer",
25974
26007
  value: function _startTimeUpdateTimer() {
@@ -25991,6 +26024,7 @@
25991
26024
  value: function getProgramDateTime() {
25992
26025
  return this._programDateTime;
25993
26026
  }
26027
+
25994
26028
  // the duration on the video element itself should not be used
25995
26029
  // as this does not necesarily represent the duration of the stream
25996
26030
  // https://github.com/clappr/clappr/issues/668#issuecomment-157036678
@@ -26019,8 +26053,7 @@
26019
26053
  }, {
26020
26054
  key: "seekPercentage",
26021
26055
  value: function seekPercentage(percentage) {
26022
- var seekTo = this._duration;
26023
- if (percentage > 0) seekTo = this._duration * (percentage / 100);
26056
+ var seekTo = percentage > 0 ? this._duration * (percentage / 100) : this._duration;
26024
26057
  this.seek(seekTo);
26025
26058
  }
26026
26059
  }, {
@@ -26195,6 +26228,13 @@
26195
26228
  };
26196
26229
  this.trigger(core.Events.PLAYBACK_PROGRESS, progress, buffered);
26197
26230
  }
26231
+ }, {
26232
+ key: "load",
26233
+ value: function load(url) {
26234
+ this._stopTimeUpdateTimer();
26235
+ this.options.src = url;
26236
+ this._setup();
26237
+ }
26198
26238
  }, {
26199
26239
  key: "play",
26200
26240
  value: function play() {
@@ -26214,20 +26254,14 @@
26214
26254
  key: "stop",
26215
26255
  value: function stop() {
26216
26256
  this._stopTimeUpdateTimer();
26217
- if (this._hls) {
26218
- _get(_getPrototypeOf(HlsjsPlayback.prototype), "stop", this).call(this);
26219
- this._hls.destroy();
26220
- delete this._hls;
26221
- }
26257
+ if (this._hls) _get(_getPrototypeOf(HlsjsPlayback.prototype), "stop", this).call(this);
26258
+ this._destroyHLSInstance();
26222
26259
  }
26223
26260
  }, {
26224
26261
  key: "destroy",
26225
26262
  value: function destroy() {
26226
26263
  this._stopTimeUpdateTimer();
26227
- if (this._hls) {
26228
- this._hls.destroy();
26229
- delete this._hls;
26230
- }
26264
+ this._destroyHLSInstance();
26231
26265
  _get(_getPrototypeOf(HlsjsPlayback.prototype), "destroy", this).call(this);
26232
26266
  }
26233
26267
  }, {
@@ -26235,7 +26269,6 @@
26235
26269
  value: function _updatePlaybackType(evt, data) {
26236
26270
  this._playbackType = data.details.live ? core.Playback.LIVE : core.Playback.VOD;
26237
26271
  this._onLevelUpdated(evt, data);
26238
-
26239
26272
  // Live stream subtitle tracks detection hack (may not immediately available)
26240
26273
  if (this._ccTracksUpdated && this._playbackType === core.Playback.LIVE && this.hasClosedCaptionsTracks) this._onSubtitleLoaded();
26241
26274
  }
@@ -26262,7 +26295,6 @@
26262
26295
  var previousPlayableRegionStartTime = this._playableRegionStartTime;
26263
26296
  var previousPlayableRegionDuration = this._playableRegionDuration;
26264
26297
  if (fragments.length === 0) return;
26265
-
26266
26298
  // #EXT-X-PROGRAM-DATE-TIME
26267
26299
  if (fragments[0].rawProgramDateTime) this._programDateTime = fragments[0].rawProgramDateTime;
26268
26300
  if (this._playableRegionStartTime !== fragments[0].start) {
@@ -26322,7 +26354,6 @@
26322
26354
  durationChanged = true;
26323
26355
  this._playableRegionDuration = newDuration;
26324
26356
  }
26325
-
26326
26357
  // Note the end time is not the playableRegionDuration
26327
26358
  // The end time will always increase even if content is removed from the beginning
26328
26359
  var endTime = fragments[0].start + newDuration;