{"version":3,"file":"dash-shaka-playback.esm.mjs","names":[],"sources":["../src/clappr-dash-shaka-playback.js"],"sourcesContent":["import { HTML5Video, Log, Events, PlayerError, Utils } from '@clappr/core'\nimport shaka from 'shaka-player'\n\nif (!shaka || !shaka.Player) {\n  throw new Error('dash-shaka-playback requires shaka-player to be loaded before it')\n}\n\nconst SEND_STATS_INTERVAL_MS = 30 * 1e3\nconst DEFAULT_LEVEL_AUTO = -1\nconst { now } = Utils\n\nclass DashShakaPlayback extends HTML5Video {\n  static get Events() {\n    return {\n      SHAKA_READY: 'shaka:ready'\n    }\n  }\n\n  static get shakaPlayer() {\n    return shaka\n  }\n\n  static canPlay(resource, mimeType = '') {\n    shaka.polyfill.installAll()\n    const browserSupported = shaka.Player.isBrowserSupported()\n    const resourceParts = resource.split('?')[0].match(/.*\\.(.*)$/) || []\n    return (\n      browserSupported &&\n      (resourceParts[1] === 'mpd' || mimeType.indexOf('application/dash+xml') > -1)\n    )\n  }\n\n  get name() {\n    return 'dash_shaka_playback'\n  }\n\n  get shakaVersion() {\n    return shaka.Player.version\n  }\n\n  get shakaPlayerInstance() {\n    return this._player\n  }\n\n  get levels() {\n    return this._levels\n  }\n\n  get seekRange() {\n    if (!this.shakaPlayerInstance) return { start: 0, end: 0 }\n\n    return this.shakaPlayerInstance.seekRange()\n  }\n\n  set currentLevel(id) {\n    this._currentLevelId = id\n    const isAuto = this._currentLevelId === DEFAULT_LEVEL_AUTO\n\n    this.trigger(Events.PLAYBACK_LEVEL_SWITCH_START)\n    if (!isAuto) {\n      this._player.configure({ abr: { enabled: false } })\n      this._pendingAdaptationEvent = true\n      this.selectTrack(this.videoTracks.filter(t => t.id === this._currentLevelId)[0])\n    } else {\n      this._player.configure({ abr: { enabled: true } })\n      this.trigger(Events.PLAYBACK_LEVEL_SWITCH_END)\n    }\n  }\n\n  get currentLevel() {\n    return this._currentLevelId || DEFAULT_LEVEL_AUTO\n  }\n\n  get dvrEnabled() {\n    return this._duration >= this._minDvrSize && this.getPlaybackType() === 'live'\n  }\n\n  get latency() {\n    if (!this.shakaPlayerInstance) return 0\n    return this.shakaPlayerInstance.getStats().liveLatency\n  }\n\n  get currentProgramDateTime() {\n    if (!this.shakaPlayerInstance) return null\n    return this.shakaPlayerInstance.getPlayheadTimeAsDate()\n  }\n\n  getDuration() {\n    return this._duration\n  }\n\n  get _duration() {\n    if (!this.shakaPlayerInstance) return 0\n\n    return this.seekRange.end - this.seekRange.start\n  }\n\n  getFrameRate() {\n    if (this.videoTracks && this._currentLevelId) {\n      const track = this.videoTracks.find((t) => t.id === this._currentLevelId)\n      return track && track.frameRate ? track.frameRate : null\n    }\n    return null\n  }\n\n  getCurrentTime() {\n    if (!this.shakaPlayerInstance) return 0\n    const shakaMediaElement = this.shakaPlayerInstance.getMediaElement()\n    return shakaMediaElement ? shakaMediaElement.currentTime - this.seekRange.start : 0\n  }\n\n  get _startTime() {\n    return this.seekRange.start\n  }\n\n  get presentationStartTimeAsDate() {\n    if (!this.shakaPlayerInstance || !this.shakaPlayerInstance.getPresentationStartTimeAsDate()) {\n      return 0\n    }\n\n    return new Date(\n      this.shakaPlayerInstance.getPresentationStartTimeAsDate().getTime() +\n        this.seekRange.start * 1000\n    )\n  }\n\n  get bandwidthEstimate() {\n    if (!this.shakaPlayerInstance) return null\n    return this.shakaPlayerInstance.getStats().estimatedBandwidth\n  }\n\n  get sourceMedia() {\n    return this._options.src\n  }\n\n  get _now() {\n    return now()\n  }\n\n  constructor(...args) {\n    super(...args)\n    this._levels = []\n    this._pendingAdaptationEvent = false\n    this._isShakaReadyState = false\n    this._lastTimeUpdate = { current: 0, total: 0, firstFragDateTime: 0 }\n    this._timeUpdateThrottleDelay = 200\n    this._timeUpdateFiringRate = 0.2\n    this._durationChangeMinOffset = 0.5\n    this._lastTimeUpdateFiredTime = 0\n\n    this._minDvrSize =\n      typeof this.options.shakaMinimumDvrSize === 'undefined'\n        ? 60\n        : this.options.shakaMinimumDvrSize\n  }\n\n  getProgramDateTime() {\n    return this.presentationStartTimeAsDate\n  }\n\n  seek(time) {\n    if (time < 0) {\n      Log.warn(\n        'Attempt to seek to a negative time. Resetting to live point. Use seekToLivePoint() to seek to the live point.'\n      )\n      time = this._duration\n    }\n    time += this._startTime\n    this.el.currentTime = time\n  }\n\n  pause() {\n    this.el.pause()\n  }\n\n  play() {\n    if (!this._player) this.load()\n    if (!this.isReady) {\n      this.once(DashShakaPlayback.Events.SHAKA_READY, this.play)\n      return\n    }\n    super.play()\n    this._startTimeUpdateTimer()\n    this._stopped = false\n    this._src = this.el.src\n  }\n\n  load(source) {\n    if (source) this._options.src = source\n    this._setup()\n  }\n\n  _onPlaying() {\n    /*\n      The `_onPlaying` should not be called while buffering: https://github.com/google/shaka-player/issues/2230\n      It will be executed on bufferfull.\n    */\n    if (this._isBuffering) return\n    return super._onPlaying()\n  }\n\n  _onSeeking() {\n    this._isSeeking = true\n    return super._onSeeking()\n  }\n\n  _onSeeked() {\n    /*\n      The `_onSeeked` should not be called while buffering.\n      It will be executed on bufferfull.\n    */\n    if (this._isBuffering) return\n\n    this._isSeeking = false\n    return super._onSeeked()\n  }\n\n  _startTimeUpdateTimer() {\n    this._stopTimeUpdateTimer()\n    this._timeUpdateTimer = setInterval(() => {\n      this._onTimeUpdate()\n    }, 100)\n  }\n\n  _stopTimeUpdateTimer() {\n    this._timeUpdateTimer && clearInterval(this._timeUpdateTimer)\n  }\n\n  // skipping HTML5Video `_setupSrc` (on tag video)\n  _setupSrc() {}\n\n  // skipping ready event on video tag in favor of ready on shaka\n  _ready() {\n    // override with no-op\n  }\n\n  _onShakaReady() {\n    this._isShakaReadyState = true\n    this.trigger(DashShakaPlayback.Events.SHAKA_READY)\n    this.trigger(Events.PLAYBACK_READY, this.name)\n  }\n\n  get isReady() {\n    return this._isShakaReadyState\n  }\n\n  // skipping error handling on video tag in favor of error on shaka\n  error(event) {\n    Log.error('an error was raised by the video tag', event, this.el.error)\n  }\n\n  isHighDefinitionInUse() {\n    return !!this.highDefinition\n  }\n\n  stop() {\n    this._stopTimeUpdateTimer()\n    this._stopToSendStats()\n    this._stopped = true\n\n    if (this._player) {\n      this._sendStats()\n\n      this._lastTimeUpdate = { current: 0, total: 0, firstFragDateTime: 0 }\n      this._player\n        .unload()\n        .then(() => {\n          super.stop()\n          this._player = null\n          this._isShakaReadyState = false\n        })\n        .catch(() => {\n          Log.error('shaka could not be unloaded')\n        })\n    } else {\n      super.stop()\n    }\n  }\n\n  get textTracks() {\n    return this.isReady && this._player.getTextTracks()\n  }\n\n  get audioTracks() {\n    return (\n      this.isReady && this._player.getVariantTracks().filter(t => t.mimeType.startsWith('audio/'))\n    )\n  }\n\n  get videoTracks() {\n    return (\n      this.isReady && this._player.getVariantTracks().filter(t => t.mimeType.startsWith('video/'))\n    )\n  }\n\n  getPlaybackType() {\n    return (this.isReady && this._player.isLive() ? 'live' : 'vod') || ''\n  }\n\n  selectTrack(track) {\n    if (track.type === 'text') {\n      this._player.selectTextTrack(track)\n    } else if (track.type === 'variant') {\n      this._player.selectVariantTrack(track)\n      if (track.mimeType.startsWith('video/')) {\n        // we trigger the adaptation event here\n        // because Shaka doesn't trigger its event on \"manual\" selection.\n        this._onAdaptation()\n      }\n    } else {\n      throw new Error('Unhandled track type:', track.type)\n    }\n  }\n\n  /**\n   * @override\n   */\n  get closedCaptionsTracks() {\n    let id = 0\n    const trackId = () => {\n      return id++\n    }\n    const tracks = this.textTracks || []\n\n    return tracks\n      .filter(track => track.kind === 'subtitle')\n      .map(track => {\n        return { id: trackId(), name: track.label || track.language, track: track }\n      })\n  }\n\n  /**\n   * @override\n   */\n  get closedCaptionsTrackId() {\n    return super.closedCaptionsTrackId\n  }\n\n  /**\n   * @override\n   */\n  set closedCaptionsTrackId(trackId) {\n    if (!this._player) {\n      return\n    }\n\n    const tracks = this.closedCaptionsTracks\n    let showingTrack\n\n    // Note: -1 is for hide all tracks\n    if (trackId !== -1) {\n      showingTrack = tracks.find(track => track.id === trackId)\n      if (!showingTrack) {\n        Log.warn(`Track id \"${trackId}\" not found`)\n        return\n      }\n      if (this._shakaTTVisible && showingTrack.track.active === true) {\n        Log.info(`Track id \"${trackId}\" already showing`)\n        return\n      }\n    }\n\n    if (showingTrack) {\n      this._player.selectTextTrack(showingTrack.track)\n      this._player.setTextTrackVisibility(true)\n      this._enableShakaTextTrack(true)\n    } else {\n      this._player.setTextTrackVisibility(false)\n      this._enableShakaTextTrack(false)\n    }\n\n    this._ccTrackId = trackId\n    this.trigger(Events.PLAYBACK_SUBTITLE_CHANGED, {\n      id: trackId\n    })\n  }\n\n  _enableShakaTextTrack(isEnable) {\n    // Shaka player use only one TextTrack object with video element to handle all text tracks\n    // It must be enabled or disabled in addition to call selectTextTrack()\n    if (!this.el.textTracks) {\n      return\n    }\n\n    this._shakaTTVisible = isEnable\n\n    Array.from(this.el.textTracks)\n      .filter(track => track.kind === 'subtitles')\n      .forEach(track => {\n        track.mode = isEnable === true ? 'showing' : 'hidden'\n      })\n  }\n\n  _checkForClosedCaptions() {\n    if (this._ccIsSetup) {\n      return\n    }\n\n    if (this.hasClosedCaptionsTracks) {\n      this.trigger(Events.PLAYBACK_SUBTITLE_AVAILABLE)\n      const trackId = this.closedCaptionsTrackId\n      this.closedCaptionsTrackId = trackId\n    }\n    this._ccIsSetup = true\n  }\n\n  destroy() {\n    this._stopTimeUpdateTimer()\n    this._stopToSendStats()\n\n    if (this._player) {\n      this._player\n        .destroy()\n        .then(() => this._destroy())\n        .catch(() => {\n          this._destroy()\n          Log.error('shaka could not be destroyed')\n        })\n    } else {\n      this._destroy()\n    }\n\n    super.destroy()\n  }\n\n  _setup() {\n    this._isShakaReadyState = false\n    this._ccIsSetup = false\n    this._stopToSendStats()\n\n    const runAllSteps = () => {\n      this._player = this._createPlayer()\n      this._setInitialConfig()\n      this._loadSource()\n    }\n\n    this._player ? this._player.destroy().then(() => runAllSteps()) : runAllSteps()\n  }\n\n  _createPlayer() {\n    const player = new shaka.Player(this.el)\n    player.addEventListener('error', this._onError.bind(this))\n    player.addEventListener('adaptation', this._onAdaptation.bind(this))\n    player.addEventListener('buffering', this._handleShakaBufferingEvents.bind(this))\n    player.addEventListener('segmentappended', this._onFragmentBuffered.bind(this))\n    return player\n  }\n\n  _setInitialConfig() {\n    this._options.shakaConfiguration && this._player.configure(this._options.shakaConfiguration)\n    this._options.shakaOnBeforeLoad && this._options.shakaOnBeforeLoad(this._player)\n  }\n\n  _loadSource() {\n    this._player\n      .load(this._options.src)\n      .then(() => this._loaded())\n      .catch(e => this._setupError(e))\n  }\n\n  _onTimeUpdate() {\n    if (!this.shakaPlayerInstance) return\n\n    const update = {\n      current: this.getCurrentTime(),\n      total: this.getDuration(),\n      firstFragDateTime: this.getProgramDateTime()\n    }\n    const shouldThrottle = this._shouldThrottleTimeUpdate(update)\n    if (shouldThrottle) return\n    this._lastTimeUpdate = update\n    this._lastTimeUpdateFiredTime = this._now\n    this.trigger(Events.PLAYBACK_TIMEUPDATE, update, this.name)\n  }\n\n  _shouldThrottleTimeUpdate(update) {\n    const isSameTime =\n      Math.abs(update.current - this._lastTimeUpdate.current) < this._timeUpdateFiringRate\n    const isSameDuration =\n      Math.abs(update.total - this._lastTimeUpdate.total) < this._durationChangeMinOffset\n    const isSameFirstFragDateTime =\n      update.firstFragDateTime === this._lastTimeUpdate.firstFragDateTime\n    const isSameEventPayload = isSameTime && isSameDuration && isSameFirstFragDateTime\n    const isThrottled = this._now - this._lastTimeUpdateFiredTime < this._timeUpdateThrottleDelay\n\n    return isSameEventPayload && isThrottled\n  }\n\n  // skipping HTML5 `_handleBufferingEvents` in favor of shaka buffering events\n  _handleBufferingEvents() {}\n\n  _handleShakaBufferingEvents(e) {\n    if (this._stopped) return\n\n    this._isBuffering = e.buffering\n    this._isBuffering ? this._onBuffering() : this._onBufferfull()\n  }\n\n  _onBuffering() {\n    this.trigger(Events.PLAYBACK_BUFFERING)\n  }\n\n  _onBufferfull() {\n    this.trigger(Events.PLAYBACK_BUFFERFULL)\n    if (this._isSeeking) this._onSeeked()\n    if (this.isPlaying()) this._onPlaying()\n  }\n\n  _onFragmentBuffered() {\n    this.trigger(Events.PLAYBACK_FRAGMENT_BUFFERED)\n  }\n\n  _loaded() {\n    this._onShakaReady()\n    this._startToSendStats()\n    this._fillLevels()\n    this._checkForClosedCaptions()\n  }\n\n  _fillLevels() {\n    if (this._levels.length === 0) {\n      this._levels = this.videoTracks\n        .map(videoTrack => {\n          return { id: videoTrack.id, label: `${videoTrack.height}p` }\n        })\n        .reverse()\n      this.trigger(Events.PLAYBACK_LEVELS_AVAILABLE, this.levels)\n    }\n  }\n\n  _startToSendStats() {\n    this._stopToSendStats()\n    const intervalMs = this._options.shakaSendStatsInterval || SEND_STATS_INTERVAL_MS\n    this.sendStatsId = setInterval(() => this._sendStats(), intervalMs)\n  }\n\n  _stopToSendStats() {\n    this.sendStatsId && clearInterval(this.sendStatsId)\n    this.sendStatsId = null\n  }\n\n  _sendStats() {\n    this.trigger(Events.PLAYBACK_STATS_ADD, this._player.getStats())\n  }\n\n  _setupError(err) {\n    this._onError(err)\n  }\n\n  _onError(err) {\n    const error = {\n      shakaError: err,\n      videoError: this.el.error\n    }\n\n    const { category, code, severity, data } = error.shakaError.detail || error.shakaError\n\n    if (error.videoError || (!code && !category)) return super._onError()\n\n    let shakaErrorData = ''\n    try {\n      shakaErrorData = JSON.stringify(data)\n    } catch (error) {\n      Log.warn('Fail to parse shaka error data', error)\n    }\n    const isCritical = severity === shaka.util.Error.Severity.CRITICAL\n    const errorData = {\n      code: `${category}_${code}`,\n      description: `Category: ${category}, code: ${code}, severity: ${severity}, data: ${shakaErrorData}`,\n      level: isCritical ? PlayerError.Levels.FATAL : PlayerError.Levels.WARN,\n      raw: err\n    }\n    const formattedError = this.createError(errorData)\n    Log.error('Shaka error event:', formattedError)\n    this.trigger(Events.PLAYBACK_ERROR, formattedError)\n  }\n\n  _onAdaptation() {\n    const activeVideo = this.videoTracks.filter(t => t.active === true)[0]\n\n    this._fillLevels()\n\n    // update stats that may have changed before we trigger event\n    // so that user can rely on stats data when handling event\n    this._sendStats()\n\n    if (this._pendingAdaptationEvent) {\n      this.trigger(Events.PLAYBACK_LEVEL_SWITCH_END)\n      this._pendingAdaptationEvent = false\n    }\n\n    Log.debug('an adaptation has happened:', activeVideo)\n    this.highDefinition = activeVideo.height >= 720\n    this.trigger(Events.PLAYBACK_HIGHDEFINITIONUPDATE, this.highDefinition)\n    this.trigger(Events.PLAYBACK_BITRATE, {\n      bandwidth: activeVideo.bandwidth,\n      width: activeVideo.width,\n      height: activeVideo.height,\n      level: activeVideo.id,\n      bitrate: activeVideo.videoBandwidth\n    })\n  }\n\n  _updateSettings() {\n    if (this.getPlaybackType() === '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\n    this.settings.seekEnabled = this.isSeekEnabled()\n    this.trigger(Events.PLAYBACK_SETTINGSUPDATE)\n  }\n\n  _destroy() {\n    this._isShakaReadyState = false\n    Log.debug('shaka was destroyed')\n  }\n}\n\nexport default DashShakaPlayback\n"],"mappings":"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"}