@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.
- package/dist/hlsjs-playback.esm.js +98 -67
- package/dist/hlsjs-playback.external.js +98 -67
- package/dist/hlsjs-playback.external.min.js +1 -1
- package/dist/hlsjs-playback.external.min.js.map +1 -1
- package/dist/hlsjs-playback.js +98 -67
- package/dist/hlsjs-playback.min.js +2 -2
- package/dist/hlsjs-playback.min.js.map +1 -1
- package/package.json +1 -1
- package/src/hls.js +65 -64
- package/src/hls.test.js +12 -0
|
@@ -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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"}
|
package/dist/hlsjs-playback.js
CHANGED
|
@@ -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.
|
|
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
|
|
25808
|
-
var timePassed = this._now -
|
|
25809
|
-
var extrapolatedEndTime = (
|
|
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
|
-
|
|
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.
|
|
25866
|
-
this._hls
|
|
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
|
-
|
|
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
|
-
|
|
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;
|